Most of GAIA’s hooks live at .claude/hooks/*.sh and are registered in .claude/settings.json under the hooks key, keyed by event name. A few helper scripts under .gaia/scripts/ are registered the same way for events outside the standard tool-call surface.
Most hooks here either block dangerous tool calls outright (deny the call with a reason shown to Claude) or inject a one-line nudge into context. A few are advisory: they run, log a reminder to stderr, and exit clean.
For Claude Code’s own hook documentation, see the Hooks reference on docs.claude.com.
| Hook | What it does | Path |
|---|
wiki-session-start | Records HEAD into .git/claude-session-start so the Stop hook can detect wiki commits during the session, and re-asserts per-machine memory contracts. | .claude/hooks/wiki-session-start.sh |
| Hook | What it does | Path |
|---|
wiki-session-stop | If wiki files were committed during the session, prompts a hot-cache refresh; nags /gaia wiki sync when commits land but wiki/.state.json did not advance. | .claude/hooks/wiki-session-stop.sh |
wiki-squash-autocommits | Squashes the trailing run of wiki: auto-commit commits into one; on main, redirects the squash to a wiki/* branch and merges via PR. | .claude/hooks/wiki-squash-autocommits.sh |
| Hook | What it does | Path |
|---|
wiki-drift-check | Detects drift between wiki/.state.json and HEAD; injects a once-per-session reminder when drifted. | .claude/hooks/wiki-drift-check.sh |
| Hook | Matcher | What it does | Path |
|---|
intercept-init | init | Redirects /init to /gaia-init so the built-in flow does not overwrite GAIA’s curated CLAUDE.md. | .claude/hooks/intercept-init.sh |
| Hook | What it does | Path |
|---|
block-env-write | Denies writes to .env and .env.* files; allows .env.example. | .claude/hooks/block-env-write.sh |
block-eslint-config-edit | Denies edits to eslint.config.{js,cjs,mjs,ts}; force fixes back into the source file where the lint error occurred. | .claude/hooks/block-eslint-config-edit.sh |
block-lockfile-edit | Denies direct edits to pnpm-lock.yaml; lockfile changes must come from pnpm install. | .claude/hooks/block-lockfile-edit.sh |
block-secrets-write | Denies writes that contain AWS keys, GitHub PATs, private-key headers, or non-placeholder _TOKEN/_SECRET/_KEY/_PASSWORD assignments. | .claude/hooks/block-secrets-write.sh |
block-vitest-globals-tsconfig | Blocks adding vitest/globals to tsconfig.json; tests must use explicit imports from vitest. | .claude/hooks/block-vitest-globals-tsconfig.sh |
check-i18n-strings | Advisory once-per-session reminder when a .tsx file under app/pages/ or app/components/ is edited; does not block. | .claude/hooks/check-i18n-strings.sh |
check-story-exists | Advisory reminder to add a Storybook story when a new component index.tsx is written without a sibling tests/index.stories.tsx. | .claude/hooks/check-story-exists.sh |
| Hook | What it does | Path |
|---|
block-bare-test | Blocks bare pnpm test / npm test invocations; requires --run so vitest does not start watch mode. | .claude/hooks/block-bare-test.sh |
block-main-destructive-git | Blocks commits to main/master and force-pushes to those branches. | .claude/hooks/block-main-destructive-git.sh |
block-rm-rf | Denies rm -rf against root, $HOME, cwd, unscoped globs, .git, node_modules, and any path outside a small whitelist of scratch dirs. | .claude/hooks/block-rm-rf.sh |
pr-merge-audit-check | Blocks gh pr merge until a code-review-audit marker file exists at .gaia/local/audit/<HEAD-sha>.ok. | .claude/hooks/pr-merge-audit-check.sh |
| Hook | What it does | Path |
|---|
wiki-commit-nudge | After every non-amend git commit, injects commit metadata and the current wiki drift count into context. | .claude/hooks/wiki-commit-nudge.sh |
| Hook | What it does | Path |
|---|
audit-stamp-trailer | Writes the GAIA-Audit: commit trailer on HEAD so CI can recognize an already-audited tree. Called by the code-review-audit agent at the end of a clean review. | .claude/hooks/audit-stamp-trailer.sh |