Skip to content

fix: stop re-declaring the auto-loaded hooks file in the plugin manifest - #134

Merged
CodeWithJuber merged 1 commit into
masterfrom
claude/zimam-multi-repo-plugins-zjhoey
Aug 22, 2026
Merged

fix: stop re-declaring the auto-loaded hooks file in the plugin manifest#134
CodeWithJuber merged 1 commit into
masterfrom
claude/zimam-multi-repo-plugins-zjhoey

Conversation

@CodeWithJuber

Copy link
Copy Markdown
Owner

What & why

When forgekit 0.32.0 is installed as a marketplace plugin, Claude Code rejects it at load time:

Hook load failed: Duplicate hooks file detected: ./hooks/hooks.json resolves to
already-loaded file .../forgekit/0.32.0/hooks/hooks.json. The standard
hooks/hooks.json is loaded automatically, so manifest.hooks should only
reference additional hook files.

Claude Code auto-loads the standard hooks/hooks.json from the plugin root; manifest.hooks is only for additional hook files. The manifest re-declared the standard path, registering it twice, and the loader rejected the whole plugin — all 18 skills, 5 crew agents, every ambient guard, and the forge-cortex MCP server were absent for marketplace installs. (--plugin-dir dev flows and the repo's dogfood .claude/settings.json were unaffected, which is why this went unnoticed; claude plugin validate doesn't catch it either, as it's runtime-only.)

Changes:

  • .claude-plugin/plugin.json: drop the redundant "hooks": "./hooks/hooks.json" entry. The hooks file itself is unchanged and still loads — automatically.
  • src/doctor.js: the "Claude plugin hooks" check now defaults to the standard path when manifest.hooks is absent, and warns when a manifest re-declares the auto-loaded file (the exact failure this fixes).
  • test/channels.test.js: regression test that fails if the standard hooks path is ever re-declared (verified it fails against the old manifest).
  • CHANGELOG.md: ### Fixed entry under ## [Unreleased].

Verified end-to-end: after this fix, claude plugin install forgekit@forge loads with Status: √ enabled instead of × failed to load.

Checklist

  • npm test passes (1129 pass / 2 skipped / 0 fail, Node 20)
  • npm run check passes (Biome lint + format — no fixes applied)
  • New public functions have a test (regression test for the manifest invariant)
  • Conventional commit message (fix:)
  • CHANGELOG.md updated under ## [Unreleased]
  • No new runtime dependency (dev deps ok)
  • Substrate/docs updated — n/a: no change to forge substrate, forge impact, router/gate, or MCP substrate tools

Risk & rollback

  • Risk level: low — removes one manifest key and makes a doctor check more accurate; no hook, skill, or agent content changes
  • Rollback plan: revert the commit; the plugin returns to failing to load from marketplaces, so revert only if a Claude Code release changes the duplicate-hooks rule

Extra checks (tick if applicable)

  • npm run typecheck passes
  • Input validated at boundaries; errors handled (doctor check stays inside its existing try/catch, fail-open)
  • Authorization/ownership checked — n/a
  • Logs contain no secrets/PII
  • If AI-assisted: I understand it, verified the package APIs, and it has tests

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pyb7qWVaCdDzkQ1CfiaBk2


Generated by Claude Code

Claude Code loads the standard hooks/hooks.json automatically; declaring it
in manifest.hooks registered the same file twice and the loader rejected the
entire plugin ('Duplicate hooks file detected: ./hooks/hooks.json'), taking
all 18 skills, 5 crew agents, every ambient guard and the forge-cortex MCP
server down with it. manifest.hooks is only for additional hook files.

- .claude-plugin/plugin.json: drop the redundant hooks entry.
- src/doctor.js: the plugin-hooks check now defaults to the standard path
  when manifest.hooks is absent, and warns when a manifest re-declares the
  auto-loaded file (the exact failure this fixes).
- test/channels.test.js: regression test — fails if the standard hooks path
  is ever re-declared. Verified it catches the old manifest.
- CHANGELOG.md: Fixed entry under Unreleased.

Gate: 1129/1131 pass (2 skipped), biome clean, tsc clean, docs check exit 0.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Pyb7qWVaCdDzkQ1CfiaBk2
@CodeWithJuber
CodeWithJuber marked this pull request as ready for review August 22, 2026 20:01
@CodeWithJuber
CodeWithJuber merged commit 4614752 into master Aug 22, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant