Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 9 additions & 0 deletions nemoclaw/openclaw.plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
"name": "NemoClaw",
"version": "0.1.0",
"description": "Migrate and run OpenClaw inside OpenShell with optional NIM-backed inference",
"commandAliases": [
{
"name": "nemoclaw",
"kind": "runtime-slash"
}
],
"activation": {
"onStartup": true
},
"configSchema": {
"type": "object",
"properties": {
Expand Down
43 changes: 42 additions & 1 deletion schemas/openclaw-plugin.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
"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"],
"required": [
"id",
"name",
"version",
"description",
"commandAliases",
"activation",
"configSchema"
],
"additionalProperties": false,
"properties": {
"id": {
Expand All @@ -27,6 +35,39 @@
"minLength": 1,
"description": "Short description of the plugin."
},
"commandAliases": {
"type": "array",
"description": "Runtime command names that resolve to this plugin's handlers, such as chat slash commands.",
"items": {
"type": "object",
"required": ["name", "kind"],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"description": "Command name that belongs to this plugin."
},
"kind": {
"type": "string",
"enum": ["runtime-slash"],
"description": "Marks the alias as a chat slash command rather than a root CLI command."
}
}
}
},
"activation": {
"type": "object",
"description": "OpenClaw activation planner metadata. Use onStartup=true when plugin registration must run during Gateway startup.",
"required": ["onStartup"],
"additionalProperties": false,
"properties": {
"onStartup": {
"type": "boolean",
"description": "Whether OpenClaw should import the plugin during Gateway startup."
}
}
},
"configSchema": {
"type": "object",
"description": "JSON Schema object describing the plugin's configuration fields."
Expand Down
26 changes: 26 additions & 0 deletions test/validate-config-schemas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,38 @@ describe("openclaw-plugin.schema.json", () => {
name: "Fixture Plugin",
version: "1.2.3",
description: "Schema fixture",
configSchema: { type: "object" },
commandAliases: [{ name: "fixture", kind: "runtime-slash" }],
activation: { onStartup: true },
};

it("openclaw.plugin.json passes schema validation", () => {
expectValid(validate, data, "openclaw.plugin.json");
});

it("accepts runtime slash activation metadata", () => {
expectValid(validate, validPluginFixture, "runtime slash activation fixture");
});

it("rejects command alias without kind", () => {
const bad = {
...validPluginFixture,
commandAliases: [{ name: "fixture" }],
activation: { onStartup: true },
};
expect(validate(bad)).toBe(false);
});

it("rejects empty activation metadata", () => {
const bad = { ...validPluginFixture, activation: {} };
expect(validate(bad)).toBe(false);
});

it("rejects activation properties NemoClaw does not use", () => {
const bad = { ...validPluginFixture, activation: { onStartup: true, onProviders: ["demo"] } };
expect(validate(bad)).toBe(false);
});

it("rejects plugin with missing id", () => {
const { id: _id, ...bad } = validPluginFixture;
expect(validate(bad)).toBe(false);
Expand Down
Loading