You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The three shared hooks are hand-duplicated between the repo-local .claude/settings.json (self-hosted sessions, $CLAUDE_PROJECT_DIR paths) and the shipped .claude/hooks/hooks.json (consumers, ${CLAUDE_PLUGIN_ROOT} paths). PR #196's parity gate now detects divergence, but a human still has to copy changes by hand — the duplication itself remains. Two files are structurally required (Claude Code's project-settings loader and plugin-hooks loader each read only their own file, with no include mechanism), but two hand-maintained files are not.
Do
Make .claude/hooks/hooks.json the single source of truth and generate the hooks block of .claude/settings.json from it:
Rewrite ${CLAUDE_PLUGIN_ROOT}/scripts/X → bash "$CLAUDE_PROJECT_DIR/.claude/scripts/X"-style commands (match current settings.json quoting).
Merge in the documented self-only extras (currently log-worker-tool.sh — reuse/share the ALLOWLIST from the parity check in self/checks.sh).
Surgical JSON merge of ONLY the hooks key — settings.json also carries permissions/sandbox config that must not be touched.
Sandboxed sessions RO-mask .claude/hooks/ and friends — the generator must tolerate running where the source is read-only (it only writes settings.json) and regeneration of masked paths happens in a real terminal.
Keep the self-only ALLOWLIST as one shared definition so the generator and the gate can never disagree.
Follow-up to #140 / PR #196.
Problem
The three shared hooks are hand-duplicated between the repo-local
.claude/settings.json(self-hosted sessions,$CLAUDE_PROJECT_DIRpaths) and the shipped.claude/hooks/hooks.json(consumers,${CLAUDE_PLUGIN_ROOT}paths). PR #196's parity gate now detects divergence, but a human still has to copy changes by hand — the duplication itself remains. Two files are structurally required (Claude Code's project-settings loader and plugin-hooks loader each read only their own file, with no include mechanism), but two hand-maintained files are not.Do
Make
.claude/hooks/hooks.jsonthe single source of truth and generate thehooksblock of.claude/settings.jsonfrom it:${CLAUDE_PLUGIN_ROOT}/scripts/X→bash "$CLAUDE_PROJECT_DIR/.claude/scripts/X"-style commands (match current settings.json quoting).log-worker-tool.sh— reuse/share the ALLOWLIST from the parity check inself/checks.sh).hookskey — settings.json also carries permissions/sandbox config that must not be touched./orchestrator:sync(or expose as a fix-mode of the parity check). Keep PR test(self): gate hooks parity between settings.json and hooks.json (#140) #196's gate as the born-green verifier that the generated output is current.Caveats
.claude/hooks/and friends — the generator must tolerate running where the source is read-only (it only writes settings.json) and regeneration of masked paths happens in a real terminal.🤖 Generated with Claude Code