fix: make the plugin actually load in Claude Code (invalid manifest, wrong layout, unsupported install) - #3
Open
deniscms wants to merge 1 commit into
Conversation
deniscms
force-pushed
the
fix/plugin-discovery-and-layout
branch
from
August 18, 2026 00:23
75b8185 to
3628d88
Compare
Nothing shipped by this repo was reaching Claude Code: `/grow` never
registered, and neither did any of the agents. Three separate defects,
all confirmed by `claude plugin validate`:
1. Invalid manifest. `.claude-plugin/plugin.json` declared `commands`,
`agents`, `skills` and `hooks` as arrays of objects
(`[{"path": "..."}]`), a shape the schema rejects, plus `mcp-servers`
instead of `mcpServers`:
plugins[0] plugin.json -> hooks: Invalid input
plugins[0] plugin.json -> commands: Invalid input
plugins[0] plugin.json -> agents: Invalid input
plugins[0] plugin.json -> skills: Invalid input
2. Wrong file layout. Claude Code discovers components by convention:
`commands/<name>.md`, `agents/<name>.md`, `skills/<name>/SKILL.md`.
This repo had `commands/grow/COMMAND.md` and `agents/<n>/AGENT.md`,
so zero commands and zero agents were discovered. Pointing the
manifest at those paths explicitly passes validation but still loads
no agents -- only the conventional layout works.
3. Unsupported install method. `install.sh` symlinked the clone into
`~/.claude/plugins/growthOS`. That directory is Claude Code's own
managed state (cache/, marketplaces/, installed_plugins.json), not a
discovery path, so the symlink did nothing. A plugin is discovered
only once it is registered as a marketplace and installed from it --
and this repo already ships `.claude-plugin/marketplace.json` for
exactly that.
Changes:
- `commands/grow/COMMAND.md` -> `commands/grow.md`; the supporting docs
(`setup.md`, `FREE-CONTENT.md`) move to `docs/grow/`, references updated.
- `agents/<n>/AGENT.md` -> `agents/<n>.md`; per-agent `README.md` and
`router.md` move to `docs/agents/<n>/`.
- Manifest reduced to the valid schema, relying on convention-based
discovery. The duplicate root `plugin.json` is removed: Claude Code
reads only `.claude-plugin/plugin.json`, and the two had already
drifted apart (11 agents/26 skills vs 9/20).
- `install.sh` rewritten around `claude plugin marketplace add` +
`claude plugin install`, validating the manifest first and cleaning up
the symlink older versions left behind.
- README: installation, uninstall and troubleshooting rewritten around
commands that report real state (`claude plugin list|details|validate`);
architecture tree corrected.
Verified with `claude plugin details growthOS`:
Skills (27) ... grow ...
Agents (12) cmo, caption-writer, content-creator, ...
Still not wired, out of scope here: the four `hooks/*.md` are prose, not
hook configuration, and the MCP servers have no `mcpServers` entry --
both report (0).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After a clean
git clone+./install.sh, nothing this repo ships reaches Claude Code./growdoes not register, and neither does any of the agents. The README's troubleshooting steps ("confirm the symlink", "confirm the manifest") all pass while the plugin remains entirely absent, which makes the failure very hard to diagnose.Three separate defects, all confirmed with
claude plugin validate.1. The manifest is invalid
.claude-plugin/plugin.jsondeclaredcommands,agents,skillsandhooksas arrays of objects ([{"path": "..."}]), a shape the schema rejects, plusmcp-serversinstead ofmcpServers:2. The file layout does not match what Claude Code discovers
Claude Code discovers components by convention:
commands/<name>.md,agents/<name>.md,skills/<name>/SKILL.md. This repo hadcommands/grow/COMMAND.mdandagents/<n>/AGENT.md, so zero commands and zero agents were found. (Onlyskills/was already correct, which is why skills were the one thing that loaded.)Worth recording: pointing the manifest at those nested paths explicitly —
"agents": ["./agents/cmo/AGENT.md", ...]— passes validation but still yieldsAgents (0). Only the conventional layout actually works.3.
install.shused an unsupported install methodThe script symlinked the clone into
~/.claude/plugins/growthOS. That directory is Claude Code's own managed state (cache/,marketplaces/,installed_plugins.json) — not a discovery path. The symlink had no effect; the plugin never appeared ininstalled_plugins.jsonand noenabledPluginsentry was ever written.A plugin is discovered only once it is registered as a marketplace and installed from it — and this repo already ships
.claude-plugin/marketplace.jsonfor exactly that, so the fix is two commands.Changes
commands/grow/COMMAND.md→commands/grow.md; supporting docs (setup.md,FREE-CONTENT.md) moved todocs/grow/, references updated.agents/<n>/AGENT.md→agents/<n>.md(12 agents); per-agentREADME.md/router.mdmoved todocs/agents/<n>/so they are not mistaken for agent definitions.plugin.jsonremoved — Claude Code reads only.claude-plugin/plugin.json, and the two had already drifted apart (11 agents / 26 skills vs 9 / 20).install.shrewritten aroundclaude plugin marketplace add+claude plugin install, validating the manifest first and removing the symlink older versions left behind.claude plugin list/details/validate); architecture tree corrected.No agent, skill or command content was changed — this is manifest, layout and install only.
Verification
Before:
After:
The one remaining warning is cosmetic: the plugin name
growthOSis not kebab-case, which only matters for Claude.ai marketplace sync. Left alone deliberately — renaming it would change the plugin id users already have installed.Known, still unwired (deliberately out of scope)
hooks/*.mdfiles are prose, not hook configuration. Claude Code expects hooks as JSON inplugin.json(matcher + command). Converting them requires deciding what each hook should actually execute, which is a design call for the maintainer, not a mechanical fix.mcpServersentry and no.mcp.json. Wiring them needs the launch command and credential handling.Happy to follow up with either in a separate PR if you want to point me at the intended behaviour.