Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/basic-checks/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ runs:
shell: bash
run: npm run build:cli

- name: Validate config schemas
shell: bash
run: npm run validate:configs

- name: Run checks
shell: bash
run: npx prek run --all-files --stage pre-push
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ repos:
- id: check-shebang-scripts-are-executable
priority: 10

- repo: local
hooks:
- id: validate-config-schemas
name: Validate config files against JSON schemas
entry: npx tsx scripts/validate-configs.ts
language: system
pass_filenames: false
files: ^(nemoclaw-blueprint/.*\.yaml$|nemoclaw/openclaw\.plugin\.json$|schemas/.*\.json$)
priority: 10

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"typecheck": "tsc -p jsconfig.json",
"build:cli": "tsc -p tsconfig.src.json",
"typecheck:cli": "tsc -p tsconfig.cli.json",
"validate:configs": "tsx scripts/validate-configs.ts",
"bump:version": "tsx scripts/bump-version.ts",
"prepare": "if command -v tsc >/dev/null 2>&1 || [ -x node_modules/.bin/tsc ]; then npm run build:cli; fi && npm install --omit=dev --ignore-scripts 2>/dev/null || true && if [ -d .git ]; then if command -v prek >/dev/null 2>&1; then prek install; elif [ -d node_modules/@j178/prek ]; then echo \"ERROR: prek package found but binary not in PATH\" && exit 1; else echo \"Skipping git hook setup (prek not installed)\"; fi; fi",
"prepublishOnly": "cd nemoclaw && env -u npm_config_global -u npm_config_prefix -u npm_config_omit npm install --ignore-scripts && ./node_modules/.bin/tsc"
Expand Down Expand Up @@ -49,6 +50,7 @@
"@eslint/js": "^10.0.1",
"@j178/prek": "^0.3.6",
"@types/node": "^25.5.0",
"ajv": "^8.17.0",
"@vitest/coverage-v8": "^4.1.0",
"eslint": "^10.1.0",
"execa": "^9.6.1",
Expand Down
132 changes: 132 additions & 0 deletions schemas/blueprint.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/NVIDIA/NemoClaw/schemas/blueprint.schema.json",
"title": "NemoClaw Blueprint",
"description": "Schema for nemoclaw-blueprint/blueprint.yaml — defines sandbox orchestration, inference profiles, and policy configuration.",
"type": "object",
"required": ["version", "profiles", "components"],
"additionalProperties": false,
"properties": {
"version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Semver version of the blueprint."
},
"min_openshell_version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Minimum compatible OpenShell version."
},
"min_openclaw_version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Minimum compatible OpenClaw version."
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
"digest": {
"type": "string",
"description": "Computed at release time."
},
"profiles": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true,
"description": "Declared inference profile names."
},
"description": {
"type": "string"
},
"components": {
"type": "object",
"required": ["sandbox", "inference"],
"properties": {
"sandbox": {
"type": "object",
"required": ["image", "name"],
"additionalProperties": false,
"properties": {
"image": {
"type": "string",
"description": "Container image for the sandbox."
},
"name": {
"type": "string",
"description": "Default sandbox name."
},
"forward_ports": {
"type": "array",
"items": { "type": "integer", "minimum": 1, "maximum": 65535 }
}
}
},
"inference": {
"type": "object",
"required": ["profiles"],
"properties": {
"profiles": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"$ref": "#/$defs/inferenceProfile"
}
}
}
},
"policy": {
"type": "object",
"required": ["base"],
"properties": {
"base": {
"type": "string",
"description": "Path to the base sandbox policy file."
},
"additions": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/policyAddition"
}
}
}
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
},
"$defs": {
"inferenceProfile": {
"type": "object",
"required": ["provider_type", "endpoint"],
"properties": {
"provider_type": { "type": "string" },
"provider_name": { "type": "string" },
"endpoint": { "type": "string" },
"model": { "type": "string" },
"credential_env": { "type": "string" },
"credential_default": { "type": "string" },
"timeout_secs": { "type": "integer", "minimum": 1 },
"dynamic_endpoint": { "type": "boolean" }
}
},
"policyAddition": {
"type": "object",
"required": ["name", "endpoints"],
"properties": {
"name": { "type": "string" },
"endpoints": {
"type": "array",
"items": {
"type": "object",
"required": ["host", "port"],
"properties": {
"host": { "type": "string" },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"protocol": { "type": "string" },
"enforcement": { "type": "string" },
"tls": { "type": "string" },
"access": { "type": "string" }
}
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}
}
}
}
Empty file.
35 changes: 35 additions & 0 deletions schemas/openclaw-plugin.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/NVIDIA/NemoClaw/schemas/openclaw-plugin.schema.json",
"title": "NemoClaw OpenClaw Plugin Manifest",
"description": "Schema for nemoclaw/openclaw.plugin.json — the OpenClaw plugin manifest that declares the plugin identity and its configuration schema.",
"type": "object",
"required": ["id", "name", "version", "description", "configSchema"],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "Unique plugin identifier."
},
"name": {
"type": "string",
"minLength": 1,
"description": "Human-readable plugin name."
},
"version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Semver version of the plugin."
},
"description": {
"type": "string",
"minLength": 1,
"description": "Short description of the plugin."
},
"configSchema": {
"type": "object",
"description": "JSON Schema object describing the plugin's configuration fields."
}
}
}
100 changes: 100 additions & 0 deletions schemas/policy-preset.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/NVIDIA/NemoClaw/schemas/policy-preset.schema.json",
"title": "NemoClaw Policy Preset",
"description": "Schema for policy presets (nemoclaw-blueprint/policies/presets/*.yaml) — named network policy bundles that can be merged into the base sandbox policy.",
"type": "object",
"required": ["preset", "network_policies"],
"additionalProperties": false,
"properties": {
"preset": {
"type": "object",
"required": ["name", "description"],
"additionalProperties": false,
"properties": {
"name": { "type": "string", "minLength": 1 },
"description": { "type": "string", "minLength": 1 }
}
},
"network_policies": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"$ref": "#/$defs/networkPolicyEntry"
}
}
},
"$defs": {
"networkPolicyEntry": {
"type": "object",
"required": ["name", "endpoints"],
"properties": {
"name": { "type": "string" },
"endpoints": {
"type": "array",
"items": { "$ref": "#/$defs/endpoint" },
"minItems": 1
},
"binaries": {
"type": "array",
"items": { "$ref": "#/$defs/binary" }
}
}
},
"endpoint": {
"type": "object",
"required": ["host", "port"],
"properties": {
"host": { "type": "string" },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
"protocol": { "type": "string", "enum": ["rest"] },
"enforcement": { "type": "string", "enum": ["enforce", "audit"] },
"tls": { "type": "string", "enum": ["terminate", "passthrough"] },
"access": { "type": "string", "enum": ["full"] },
"rules": {
"type": "array",
"items": { "$ref": "#/$defs/rule" },
"minItems": 1
}
},
"if": {
"properties": { "protocol": { "const": "rest" } },
"required": ["protocol"]
},
"then": { "required": ["rules"] }
},
"rule": {
"type": "object",
"required": ["allow"],
"additionalProperties": false,
"properties": {
"allow": {
"type": "object",
"required": ["method", "path"],
"additionalProperties": false,
"properties": {
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
},
"path": {
"type": "string",
"pattern": "^/"
}
}
}
}
},
"binary": {
"type": "object",
"required": ["path"],
"additionalProperties": false,
"properties": {
"path": {
"type": "string",
"pattern": "^/"
}
}
}
}
}
Loading
Loading