scaffold-cc-hooks
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
.claude/settings*.jsonor.claude/hooks/files: Audit what already exists, chooseadditiveoroverhaul, then regenerate only the managed hook layer. - Existing hooks that show up in
/hooksbut never actually fire: Treat workspace trust as the first diagnostic. Check~/.claude.jsonfor 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.mdandreferences/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 assets/hook-events.json |
| 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
assets/hook-events.json. - Audit the target project in detail before deciding which events to enable.
- Inspect any existing
.claude/settings.json,.claude/settings.local.json,.claude/hooks/,CLAUDE.md,.claude/rules/, 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
.claude/hooks/README.mdso 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
hasTrustDialogAcceptedis 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~/.claude.jsonwhen 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
/hooksshows 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
untrusted, 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/hookshttps://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-11b4516adc5dhttps://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
~/.claude.json - 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
.env, secrets, migrations, lockfiles, generated code, and infra directories - environment reload needs such as
direnv,.envrc, or per-directory tooling
Run scripts/audit_project.sh 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
iffilters on tool events- timeouts
- the actual logic inside enabled event scripts
- whether the refresh is
additiveoroverhaul
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
overhaulmode. - Treat previously generated hooks as append-only in
additivemode 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
$CLAUDE_PROJECT_DIRin generated command paths. - Default to a managed root of
.claude/hooks/generatedunless the project already has a stronger convention. - Default to
.claude/settings.jsonwhen the hook setup should be shared. Use.claude/settings.local.jsononly 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, if, shell, and settings pitfalls |
references/gotchas.md |
Operational Scripts
scripts/audit_project.shbuilds a project profile from real repo signals.scripts/check_workspace_trust.shchecks or enables Claude Code workspace trust for an exact project path.scripts/scaffold_hooks.shrenders the managed hook tree, manifest, README, and settings fragment.scripts/merge_settings.shpreserves non-managed hooks while replacing previously managed handlers.scripts/render_hooks_readme.shrebuilds.claude/hooks/README.mdfrom the manifest and the current plan.
Gotchas
asynconly applies to command hooks, and async hooks cannot block or steer Claude after the triggering action is already done.- The
iffield only works on tool events and requires Claude Code v2.1.85 or later. Stophooks can loop forever unless you honorstop_hook_active.- Hook shells are non-interactive. Shell profile noise can break JSON output.
PermissionRequestdoes not fire in non-interactive-pmode.- Hooks do not fire in untrusted workspaces. Claude Code gates execution on
hasTrustDialogAcceptedin~/.claude.jsonunder.projects["/absolute/path/to/project"]. When hooks look installed but never run, or after a real scaffold, check trust first withscripts/check_workspace_trust.shbefore blaming the hook config. Seereferences/gotchas.mdgotcha 9 for the exact recovery flow.
More from jpcaparas/skills
markdown-new
Use markdown.new when the user explicitly wants markdown.new, Cloudflare Markdown for Agents, URL-to-Markdown conversion, file-to-Markdown conversion, crawl-to-Markdown, or the hosted markdown.new editor. Trigger on: 'markdown.new', 'convert this URL to markdown', 'crawl this docs site into markdown', 'file to markdown', 'upload this PDF to markdown', 'markdown.new API', or 'markdown editor'. Do NOT trigger for generic web search/scraping when another tool is enough, or for editing local Markdown without using the markdown.new service.
32skill-creator-advanced
Advanced skill creator for mission-critical, installable skills — API wrappers, progressively-disclosed technical documentation, CLI tool integrations, and complex multi-reference skills. Use when creating or improving skills that demand rigorous progressive disclosure, verified examples, tested operations, cross-harness compatibility, smart placement into the right repo-local or global skills directory, and self-improvement feedback loops. Triggers on: 'advanced skill', 'create API skill', 'create wrapper skill', 'production skill', 'installable skill', 'improve this skill for progressive disclosure', 'rigorous skill', 'mission-critical skill', or when skill-creator's output needs to be more thorough. Also use when upgrading an existing skill to production quality.
32azure-devops-wiki-markdown
Use when writing, fixing, or reviewing Azure DevOps wiki Markdown, Mermaid diagrams, `_TOC_` and `_TOSP_`, collapsible `<details>` blocks, query-table embeds, `@` mentions, work-item links, KaTeX math, HTML video embeds, code fences, or Azure DevOps surface-specific support differences across Wiki, PR, README, Widget, and Done fields. Triggers on Azure DevOps wiki, markdown guidance, Mermaid sequence/graph/timeline/ER diagrams, proposal decision trees, table-of-subpages, query-table, code fence aliases, line-break bugs, and wiki page formatting. Do NOT use for GitHub-only Markdown, generic Mermaid authoring outside Azure DevOps, or non-Azure documentation platforms.
29ripgrep
Prefer ripgrep (`rg`) for text search, recursive codebase search, ignore-aware grep replacement, filename discovery via `rg --files`, and machine-readable search output. Use when the user asks to search for text, find occurrences, inspect a large tree, locate files by name or pattern, or when `grep`, `grep -R`, `find | grep`, or manual file reads would be slower. Triggers on: 'search for', 'find occurrences', 'grep', 'grep -R', 'ripgrep', 'rg', 'find files', 'look for pattern'. Do NOT trigger for reading entire files, structured JSON queries better handled by `jq`, or filesystem metadata tasks that need `find` or `fd`.
29synthetic-search
Use this skill when the user explicitly wants Synthetic Search, the Synthetic API, `api.synthetic.new`, `SYNTHETIC_API_KEY`, or zero-data-retention web search with raw `curl`/`jq` examples. It covers live-verified search requests, quota checks, and a zero-dependency Node helper for readable output. Triggers on: 'Synthetic Search', 'Synthetic API', 'api.synthetic.new', 'SYNTHETIC_API_KEY', 'Synthetic quotas'. Do NOT trigger for general browser automation, full-site crawling, or unrelated search providers.
29tweet-replicate
Rebuild a public X/Twitter status into a deterministic local replica with a frozen snapshot, local HTML/CSS, Playwright capture, X-like media-frame fill behavior, a high-quality MP4 master, and a companion GIF capped under 24 MB. Use when asked to replicate a tweet/X post, freeze a status into video, make a tweet look like X offline, or create rerenderable tweet assets with a saved build folder. Trigger on: 'replicate this tweet', 'turn this X post into MP4', 'make this tweet into a GIF too', 'freeze this status locally'. Do NOT use for plain tweet text extraction, raw media download only, live X browser capture, authenticated pages, DMs, or promises of a pixel-perfect private X renderer.
29