From c19fde229a37cd30b141fbf5afd211cfe841e11a Mon Sep 17 00:00:00 2001 From: Gaurav Dubey Date: Sat, 18 Apr 2026 21:29:11 +0530 Subject: [PATCH] fix: remove agents field from plugin.json manifest (#1459) The Claude Code plugin validator rejects the "agents" field entirely. Remove it from the manifest, schema, and tests. Update schema notes to document this as a known constraint alongside the hooks field. Co-Authored-By: Claude Opus 4.6 --- .claude-plugin/PLUGIN_SCHEMA_NOTES.md | 63 ++++++++------------------- .claude-plugin/plugin.json | 40 ----------------- schemas/plugin.schema.json | 4 -- tests/plugin-manifest.test.js | 36 +++------------ 4 files changed, 23 insertions(+), 120 deletions(-) diff --git a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md index 21b68c99..3ce4b76f 100644 --- a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md +++ b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md @@ -45,60 +45,37 @@ Example: The following fields **must always be arrays**: -* `agents` * `commands` * `skills` * `hooks` (if present) Even if there is only one entry, **strings are not accepted**. -### Invalid - -```json -{ - "agents": "./agents" -} -``` - -### Valid - -```json -{ - "agents": ["./agents/planner.md"] -} -``` - This applies consistently across all component path fields. --- -## Path Resolution Rules (Critical) +## The `agents` Field: DO NOT ADD -### Agents MUST use explicit file paths +> WARNING: **CRITICAL:** Do NOT add an `"agents"` field to `plugin.json`. The Claude Code plugin validator rejects it entirely. -The validator **does not accept directory paths for `agents`**. +### Why This Matters -Even the following will fail: +The `agents` field is not part of the Claude Code plugin manifest schema. Any form of it -- string path, array of paths, or array of directories -- causes a validation error: -```json -{ - "agents": ["./agents/"] -} +``` +agents: Invalid input ``` -Instead, you must enumerate agent files explicitly: +Agent `.md` files under `agents/` are discovered automatically by convention (similar to hooks). They do not need to be declared in the manifest. -```json -{ - "agents": [ - "./agents/planner.md", - "./agents/architect.md", - "./agents/code-reviewer.md" - ] -} -``` +### History -This is the most common source of validation errors. +Previously this repo listed agents explicitly in `plugin.json` as an array of file paths. This passed the repo's own schema but failed Claude Code's actual validator, which does not recognize the field. Removed in #1459. + +--- + +## Path Resolution Rules ### Commands and Skills @@ -160,7 +137,7 @@ The test `plugin.json does NOT have explicit hooks declaration` in `tests/hooks/ These look correct but are rejected: * String values instead of arrays -* Arrays of directories for `agents` +* **Adding `"agents"` in any form** - not a recognized manifest field, causes `Invalid input` * Missing `version` * Relying on inferred paths * Assuming marketplace behavior matches local validation @@ -175,10 +152,6 @@ Avoid cleverness. Be explicit. ```json { "version": "1.1.0", - "agents": [ - "./agents/planner.md", - "./agents/code-reviewer.md" - ], "commands": ["./commands/"], "skills": ["./skills/"] } @@ -186,7 +159,7 @@ Avoid cleverness. Be explicit. This structure has been validated against the Claude plugin validator. -**Important:** Notice there is NO `"hooks"` field. The `hooks/hooks.json` file is loaded automatically by convention. Adding it explicitly causes a duplicate error. +**Important:** Notice there is NO `"hooks"` field and NO `"agents"` field. Both are loaded automatically by convention. Adding either explicitly causes errors. --- @@ -194,9 +167,9 @@ This structure has been validated against the Claude plugin validator. Before submitting changes that touch `plugin.json`: -1. Use explicit file paths for agents -2. Ensure all component fields are arrays -3. Include a `version` +1. Ensure all component fields are arrays +2. Include a `version` +3. Do NOT add `agents` or `hooks` fields (both are auto-loaded by convention) 4. Run: ```bash diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 9ccf8884..a9a7c023 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -22,46 +22,6 @@ "automation", "best-practices" ], - "agents": [ - "./agents/architect.md", - "./agents/build-error-resolver.md", - "./agents/chief-of-staff.md", - "./agents/code-reviewer.md", - "./agents/cpp-build-resolver.md", - "./agents/cpp-reviewer.md", - "./agents/csharp-reviewer.md", - "./agents/dart-build-resolver.md", - "./agents/database-reviewer.md", - "./agents/doc-updater.md", - "./agents/docs-lookup.md", - "./agents/e2e-runner.md", - "./agents/flutter-reviewer.md", - "./agents/gan-evaluator.md", - "./agents/gan-generator.md", - "./agents/gan-planner.md", - "./agents/go-build-resolver.md", - "./agents/go-reviewer.md", - "./agents/harness-optimizer.md", - "./agents/healthcare-reviewer.md", - "./agents/java-build-resolver.md", - "./agents/java-reviewer.md", - "./agents/kotlin-build-resolver.md", - "./agents/kotlin-reviewer.md", - "./agents/loop-operator.md", - "./agents/opensource-forker.md", - "./agents/opensource-packager.md", - "./agents/opensource-sanitizer.md", - "./agents/performance-optimizer.md", - "./agents/planner.md", - "./agents/python-reviewer.md", - "./agents/pytorch-build-resolver.md", - "./agents/refactor-cleaner.md", - "./agents/rust-build-resolver.md", - "./agents/rust-reviewer.md", - "./agents/security-reviewer.md", - "./agents/tdd-guide.md", - "./agents/typescript-reviewer.md" - ], "skills": ["./skills/"], "commands": ["./commands/"] } diff --git a/schemas/plugin.schema.json b/schemas/plugin.schema.json index 326a5a3b..f9a3d90f 100644 --- a/schemas/plugin.schema.json +++ b/schemas/plugin.schema.json @@ -31,10 +31,6 @@ "type": "array", "items": { "type": "string" } }, - "agents": { - "type": "array", - "items": { "type": "string" } - }, "features": { "type": "object", "properties": { diff --git a/tests/plugin-manifest.test.js b/tests/plugin-manifest.test.js index 069afb21..dc56d118 100644 --- a/tests/plugin-manifest.test.js +++ b/tests/plugin-manifest.test.js @@ -212,37 +212,11 @@ test('claude plugin.json uses published plugin name', () => { assert.strictEqual(claudePlugin.name, 'everything-claude-code'); }); -test('claude plugin.json agents is an array', () => { - assert.ok(Array.isArray(claudePlugin.agents), 'Expected agents to be an array (not a string/directory)'); -}); - -test('claude plugin.json agents uses explicit file paths (not directories)', () => { - for (const agentPath of claudePlugin.agents) { - assertSafeRepoRelativePath(agentPath, 'Agent path'); - assert.ok( - agentPath.endsWith('.md'), - `Expected explicit .md file path, got: ${agentPath}`, - ); - assert.ok( - !agentPath.endsWith('/'), - `Expected explicit file path, not directory, got: ${agentPath}`, - ); - } -}); - -test('claude plugin.json all agent files exist', () => { - for (const agentRelPath of claudePlugin.agents) { - assertSafeRepoRelativePath(agentRelPath, 'Agent path'); - const absolute = path.resolve(repoRoot, agentRelPath); - assert.ok( - absolute === repoRoot || absolute.startsWith(repoRootWithSep), - `Agent path resolves outside repo root: ${agentRelPath}`, - ); - assert.ok( - fs.existsSync(absolute), - `Agent file missing: ${agentRelPath}`, - ); - } +test('claude plugin.json does NOT have agents field (unsupported by Claude Code validator)', () => { + assert.ok( + !('agents' in claudePlugin), + 'agents field must NOT be declared — Claude Code plugin validator rejects it', + ); }); test('claude plugin.json skills is an array', () => {