scaffold-cc-hooks
Audit the target project first, then scaffold Claude Code hooks with a deterministic bash-first layout.
Decision Tree
What is the user asking for?
- New Claude Code hooks in a project with no hook setup yet:
Run live docs verification, audit the project, choose a hook plan, then scaffold.
- Existing or files:
Audit what already exists, choose or , then regenerate only the managed hook layer.
- Existing hooks that show up in but never actually fire:
Treat workspace trust as the first diagnostic. Check for the exact project path before debugging settings or script logic, then offer to enable trust if it is still off.
- Existing hooks plus possible Claude Code feature drift:
Verify the live official hook event list before writing files. If the docs changed, update the scaffold inputs first.
- Explanation only, not implementation:
Read
references/hook-events.md
and references/scaffold-layout.md
, then answer without scaffolding.
Quick Reference
| Task | Action |
|---|
| Verify the current official hook model | Read the live official docs at https://code.claude.com/docs/en/hooks
and https://code.claude.com/docs/en/hooks-guide
, then compare them to |
| Audit a target repo | Run scripts/audit_project.sh /path/to/project
|
| Check whether Claude Code trusts the target workspace | Run scripts/check_workspace_trust.sh /path/to/project --json
|
| Enable workspace trust for the target workspace | Run scripts/check_workspace_trust.sh /path/to/project --enable
|
| Understand the event catalog | Read references/hook-events.md
|
| Decide additive vs overhaul | Read references/merge-strategy.md
|
| Generate or refresh the managed hook scaffold | Run `scripts/scaffold_hooks.sh --project /path/to/project --plan /path/to/plan.json --mode additive |
| Merge generated hooks into settings | Let scripts/scaffold_hooks.sh
call scripts/merge_settings.sh
, or run the merge script directly |
| Regenerate the hooks README in a target project | Run scripts/render_hooks_readme.sh --project /path/to/project --plan /path/to/plan.json
|
Non-Negotiable Workflow
- Verify the live official Claude Code hook docs before planning any scaffold.
- Compare the live event list, hook type support, and async rules with .
- Audit the target project in detail before deciding which events to enable.
- Inspect any existing ,
.claude/settings.local.json
, , , , and related automation files before choosing a merge mode.
- Produce or update a concrete hook plan JSON. Keep the scaffold deterministic by putting project-specific judgment into the plan, not into the scaffold script.
- Scaffold every current hook event as a commented bash stub under the managed hook root, even if the event stays disabled in settings.
- Wire only the enabled events into the chosen settings file so the project does not pay runtime cost for inactive stubs.
- Regenerate so the project always has a readable event map.
- If the user reports that hooks are registered but not firing, or you just completed a real scaffold and need to verify the setup, check or explicitly offer to check workspace trust for the exact project path before debugging hook logic.
- If trust is disabled, explain that is false for that project. Offer the user two recovery paths: accept the dialog in a fresh Claude Code session, or flip the flag directly. Only mutate when the user asks you to do so or explicitly asks you to ensure trust is enabled.
Trust First Heuristic
Default to a trust check early when any of these signals appear:
- the user says hooks are not activating, not firing, or being ignored
- shows registered handlers with the expected counts, but nothing executes
- the hook scripts work when run by hand, but Claude Code never invokes them
- you just scaffolded hooks and the user wants you to confirm they actually work
Use this flow:
- Canonicalize the target path first. Trust is keyed by the exact absolute project path.
- Run
scripts/check_workspace_trust.sh /path/to/project --json
.
- If status is , tell the user the flag is false and offer to enable it.
- If the user wants it fixed, run
scripts/check_workspace_trust.sh /path/to/project --enable
.
- Only after trust is confirmed should you spend time debugging settings merges, hook matchers, script permissions, or hook logic.
Live Docs First
The official Claude Code docs are the source of truth:
https://code.claude.com/docs/en/hooks
https://code.claude.com/docs/en/hooks-guide
Use the two reading.sh articles only as secondary material for practical patterns and trade-off language:
https://reading.sh/claude-code-hooks-a-bookmarkable-guide-to-git-automation-11b4516adc5d
https://reading.sh/claude-code-async-hooks-what-they-are-and-when-to-use-them-61b21cd71aad
If the official docs and the secondary articles disagree, follow the official docs and update the local references.
Project Analysis Rules
Before choosing any hook structure, inspect:
- repo root and workspace shape
- the exact absolute project path Claude Code will trust, because trust is keyed by path in
- languages and package managers
- build, test, lint, and format entry points
- monorepo tools like Turborepo, Nx, pnpm workspaces, Bun workspaces, or custom task runners
- existing Claude Code settings, rules, hooks, plugins, and skills
- existing Git hooks, Husky, Lefthook, or CI gates
- sensitive paths like , secrets, migrations, lockfiles, generated code, and infra directories
- environment reload needs such as , , or per-directory tooling
Run
first, then read
references/project-analysis.md
when you need the full checklist.
Deterministic vs Project-Specific Work
Keep these parts deterministic:
- managed hook root path
- event stub filenames
- generated settings fragment shape
- merge behavior for previously managed hooks
- hooks README generation
- event manifest coverage for every current official hook event
Allow these parts to stay project-specific:
- which events are enabled
- event matchers
- sync vs async choice
- filters on tool events
- timeouts
- the actual logic inside enabled event scripts
- whether the refresh is or
Repeat-Run Rules
When the skill is invoked again against a project:
- Re-run live docs verification before assuming the event set is unchanged.
- Re-audit the project before assuming the current hook plan still fits.
- If the user says hooks never fire, or the scaffold needs verification, re-check workspace trust for the exact project path before assuming the generated settings are wrong.
- Preserve non-managed hooks by default.
- Treat previously generated hooks under the managed root as replaceable in mode.
- Treat previously generated hooks as append-only in mode unless a missing event or stale README requires a refresh.
- If new official hook events exist, add new stubs and README entries even if the project keeps them disabled.
Scaffold Rules
- Generate bash scripts, not Python, for the project hook runtime.
- Comment the generated bash stubs in plain language.
- Use in generated command paths.
- Default to a managed root of unless the project already has a stronger convention.
- Default to when the hook setup should be shared. Use
.claude/settings.local.json
only when the project needs machine-local behavior or already uses that pattern.
- Keep one managed script per event so the event map stays obvious.
- Keep the merged settings deterministic: remove only previously managed handlers, never unrelated custom hooks.
Reading Guide
| Need | Read |
|---|
| Full audit checklist and what to inspect first | references/project-analysis.md
|
| Current official event list and support matrix | references/hook-events.md
|
| Managed folder layout and plan file shape | references/scaffold-layout.md
|
| Additive versus overhaul behavior | references/merge-strategy.md
|
| Async, , shell, and settings pitfalls | |
Operational Scripts
- builds a project profile from real repo signals.
scripts/check_workspace_trust.sh
checks or enables Claude Code workspace trust for an exact project path.
scripts/scaffold_hooks.sh
renders the managed hook tree, manifest, README, and settings fragment.
scripts/merge_settings.sh
preserves non-managed hooks while replacing previously managed handlers.
scripts/render_hooks_readme.sh
rebuilds from the manifest and the current plan.
Gotchas
- only applies to command hooks, and async hooks cannot block or steer Claude after the triggering action is already done.
- The field only works on tool events and requires Claude Code v2.1.85 or later.
- hooks can loop forever unless you honor .
- Hook shells are non-interactive. Shell profile noise can break JSON output.
- does not fire in non-interactive mode.
- Hooks do not fire in untrusted workspaces. Claude Code gates execution on in under
.projects["/absolute/path/to/project"]
. When hooks look installed but never run, or after a real scaffold, check trust first with scripts/check_workspace_trust.sh
before blaming the hook config. See gotcha 9 for the exact recovery flow.