{"id":48362190,"url":"https://github.com/grobomo/hook-runner","last_synced_at":"2026-05-03T20:02:31.488Z","repository":{"id":347681113,"uuid":"1194885629","full_name":"grobomo/hook-runner","owner":"grobomo","description":"Modular hook system for Claude Code. Drop .js files in folders to enforce workflows, block mistakes, and inject context. 100 modules, 5 workflows, zero config.","archived":false,"fork":false,"pushed_at":"2026-04-14T16:35:14.000Z","size":2538,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T17:26:22.602Z","etag":null,"topics":["ai-tools","automation","claude","claude-code","developer-tools","hooks","workflow"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grobomo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T23:59:09.000Z","updated_at":"2026-04-14T16:35:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/grobomo/hook-runner","commit_stats":null,"previous_names":["grobomo/hook-runner"],"tags_count":73,"template":false,"template_full_name":null,"purl":"pkg:github/grobomo/hook-runner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grobomo%2Fhook-runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grobomo%2Fhook-runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grobomo%2Fhook-runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grobomo%2Fhook-runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grobomo","download_url":"https://codeload.github.com/grobomo/hook-runner/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grobomo%2Fhook-runner/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31957158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","automation","claude","claude-code","developer-tools","hooks","workflow"],"created_at":"2026-04-05T13:00:56.680Z","updated_at":"2026-05-03T20:02:31.469Z","avatar_url":"https://github.com/grobomo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hook-runner\n\n[![Tests](https://github.com/grobomo/hook-runner/actions/workflows/test.yml/badge.svg)](https://github.com/grobomo/hook-runner/actions/workflows/test.yml)\n\nModular hook system for Claude Code. Enforce workflows, block mistakes, inject context — all with plain `.js` files in folders. No settings.json editing needed.\n\n## What is hook-runner?\n\nClaude Code [hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) let you run scripts at key moments: before a tool runs, after it runs, when a session starts, when it stops. hook-runner turns this into a **module system** — drop a `.js` file in a folder and it runs automatically.\n\nOn top of modules, **workflows** group related modules into enforceable pipelines. Enable a workflow and its modules activate together. Disable it and they all go silent. This gives you a single place to organize all your hook behavior — no more hunting through `settings.json` entries.\n\n## Why hook-runner?\n\nClaude Code hooks are powerful but raw: you write shell commands in `settings.json`, they run on every invocation, and there's no structure. This works with three hooks. It doesn't work when you have 30+ enforcement rules, some that only apply in certain contexts, and you need to turn groups on and off.\n\nhook-runner replaces direct `settings.json` editing. After install, you never touch `settings.json` for hooks again — hook-runner owns all five events and routes to your modules automatically.\n\n**1. Modules over shell commands.** Each rule is a `.js` file that receives structured input (tool name, file path, command) and returns a decision. Modules are testable, documented, and version-controlled. Drop a file in a folder and it runs — remove it and it stops.\n\n**2. Workflows over individual modules.** You don't think \"I need to enable spec-gate, branch-gate, test-checkpoint-gate, and worker-loop.\" You think \"I want the SHTD development pipeline.\" Workflows group related modules so you enable one name and get a complete enforcement regime. Disable it and they all go silent. This is how you manage 115+ modules without losing track.\n\n**3. Portability.** Export your module config as YAML (`--export`), sync it to another machine (`--sync`), or share a workflow definition. Workflows also make it easy to switch contexts — enable `customer-data-guard` during incident response, disable it after.\n\n## Integrating with other Claude Code tools\n\nhook-runner is one piece of a larger Claude Code tooling ecosystem. Here's how the pieces connect:\n\n- **context-reset** — When a session's context gets long, `context-reset` saves conversation state to `SESSION_STATE.md` and starts fresh. hook-runner's `SessionStart` modules inject active workflow status on the new session so Claude picks up where it left off without losing enforcement context.\n\n- **skill-maker** — Skills are reusable prompts; hooks are enforcement. A skill tells Claude *how* to do something, a hook tells it *what it must not do*. Use skill-maker to create workflows that call hook-runner's CLI (`--workflow start`, `--health`, `--report`).\n\n- **mcp-manager** — MCP servers provide Claude with tools (browser automation, API access). hook-runner gates *which* tools Claude can use and *how*. For example, a PreToolUse module can block `Bash` commands that hit production endpoints, while mcp-manager provides the staging endpoint via an MCP tool.\n\n- **emu skill marketplace** — hook-runner is available on the [emu skill marketplace](https://github.com/trend-ai-taskforce/ai-skill-marketplace). Install the skill to get `--workflow`, `--report`, and the full module catalog. The marketplace copy stays in sync with this repo.\n\n- **OpenClaw** — hook-runner gates are portable to [OpenClaw](https://openclaw.ai) via the Plugin SDK. The `openclaw-plugin/` directory contains a ready-to-install plugin with 3 ported gates (force-push, secret-scan, commit-quality). Install with `bash openclaw-plugin/install.sh`. See [openclaw-plugin/README.md](openclaw-plugin/README.md) for the conversion table.\n\n## Quick Start\n\n```bash\n# One-liner install (enables default workflows)\nnpx grobomo/hook-runner --yes\n\n# Or step by step\ngit clone https://github.com/grobomo/hook-runner.git\ncd hook-runner \u0026\u0026 node setup.js\n```\n\nThe setup wizard will:\n1. Scan your current hooks and generate a styled HTML report\n2. Back up existing hooks to `~/.claude/hooks/archive/`\n3. Install the runner system\n4. Enable the `starter` workflow (with `--yes`) — 42 universally useful modules\n\nReady for more? Enable the full development pipeline:\n```bash\nnode setup.js --workflow enable shtd    # 101 modules: spec-first, test-first, PR discipline\n```\n\nTo undo everything: `node setup.js --uninstall --confirm`\n\n**Want to see it in action first?** Run the interactive demo — no install needed:\n```bash\nnpx grobomo/hook-runner --demo          # terminal demo\nnpx grobomo/hook-runner --demo-html     # shareable HTML page\n```\n\n## What does a block look like?\n\nWhen Claude tries something a module blocks, the hook fires and Claude sees the block reason inline. Two examples from the `starter` workflow:\n\n**Force push blocked:**\n```\nBLOCKED: Force-push to main is destructive and irreversible.\nUse a regular push or create a revert commit instead.\n```\n\n**Destructive git command blocked:**\n```\nDESTRUCTIVE: git reset --hard destroys uncommitted changes permanently.\nAlternatives:\n  git stash        — save changes for later\n  git reset --soft — move HEAD but keep changes staged\n  git checkout \u003cfile\u003e — revert specific files only\nIf you truly need --hard, ask the user first.\n```\n\nClaude reads the block message and adjusts its approach — no user intervention needed. Modules that pass return `null` silently, so there's zero overhead on normal operations.\n\n## Workflows\n\nWorkflows are the primary abstraction. Instead of managing 115+ individual modules, you enable a workflow and its modules activate automatically.\n\n```bash\nnode setup.js --workflow list              # see available workflows\nnode setup.js --workflow enable shtd       # enable the SHTD pipeline\nnode setup.js --workflow disable shtd      # disable it\nnode setup.js --workflow audit             # coverage report\nnode setup.js --workflow query Edit        # which workflows affect Edit?\n```\n\n### Built-in Workflows\n\n| Workflow | Modules | What it enforces |\n|----------|---------|-----------------|\n| `starter` | 42 | **Start here.** Safe defaults for any user — blocks force-push, destructive git, secret commits, file deletion. Adds commit quality checks, test reminders, and session context. |\n| `shtd` | 101 | Spec-Hook-Test-Driven — the full development pipeline. Enforces spec → branch → test → implement → PR, plus code quality, infrastructure safety, messaging guards, session lifecycle, and self-improvement. |\n| `gsd` | 101 | GSD-driven development — replaces shtd's spec-based flow with phase-based flow (.planning/ → ROADMAP.md → phase plan → branch → execute → PR). Same safety and quality modules as shtd. |\n| `customer-data-guard` | 3 | Read-only incident response — blocks env changes, data exfil, and V1 modifications. |\n| `dispatcher-worker` | 3 | Role-aware fleet workflow. Dispatcher specs/distributes, workers implement/test/PR. |\n| `no-local-docker` | 1 | Blocks local Docker commands, forces remote infrastructure. |\n| `cross-project-reset` | 0 | Step template for cross-project context switching (cwd-drift-detector is in shtd). |\n\n### Workflow State Machine\n\nActive workflows track progress through steps:\n\n```bash\nnode setup.js --workflow start shtd        # activate the pipeline\nnode setup.js --workflow status            # see current step\nnode setup.js --workflow complete spec     # mark spec step done\nnode setup.js --workflow reset             # clear active workflow\n```\n\n### Custom Workflows\n\nCreate `workflows/my-workflow.yml`:\n\n```yaml\nname: my-workflow\ndescription: What this workflow enforces\nversion: 1\nsteps:\n  - id: setup\n    name: Set up environment\n  - id: build\n    name: Build the thing\n    gate:\n      require_step: setup\nmodules:\n  - my-gate-module\n```\n\nTag modules with `// WORKFLOW: my-workflow` in the first 5 lines.\n\n### Workflow Templates\n\nStart from a curated template instead of a blank scaffold:\n\n```bash\nnode setup.js --workflow templates                              # list available templates\nnode setup.js --workflow create my-sec --from-template security # pre-populated with 10 modules\n```\n\n| Template | Modules | Focus |\n|----------|---------|-------|\n| `security` | 10 | Git safety, secret scanning, account protection |\n| `quality` | 9 | Code quality, testing discipline, commit hygiene |\n| `lifecycle` | 11 | Session management, continuity, health monitoring |\n| `minimal` | 3 | Absolute minimum safety (force-push, destructive-git, secrets) |\n\n### Workflow CRUD\n\n```bash\nnode setup.js --workflow create my-flow                         # blank scaffold\nnode setup.js --workflow create my-flow --from-template quality # from template\nnode setup.js --workflow add-module my-flow my-gate             # create tagged module\nnode setup.js --workflow sync-live                              # copy to live hooks dir\n```\n\n### Relaxed SHTD Mode\n\nProjects without full speckit ceremony can use **TODO.md** as the task source:\n\n- `spec-gate` accepts `- [ ] TXXX: description` entries in `TODO.md` (not just `specs/*/tasks.md`)\n- `test-checkpoint-gate` auto-detects `scripts/test/test-TXXX*.sh` files as test coverage\n- `worker-loop` gates `gh pr create` on test results — runs the test and blocks if it fails\n\nThis means a simple project needs only:\n1. `TODO.md` with `- [ ] T001: ...` entries\n2. `scripts/test/test-T001-*.sh` for each task\n3. Feature branch per task (`git checkout -b 001-T001-slug`)\n\n### Dispatcher/Worker Model\n\nFor fleet operations (CCC), enable the `dispatcher-worker` workflow. Roles are set via `CLAUDE_ROLE` env var:\n\n- **Dispatcher** (`CLAUDE_ROLE=dispatcher`): specs tasks, writes acceptance tests, creates branches, distributes to workers, monitors, merges PRs\n- **Worker** (`CLAUDE_ROLE=worker`): receives task + tests, implements until tests pass, creates PR\n- **Single instance** (no `CLAUDE_ROLE`): both roles active, all gates enforced\n\n## Modules\n\nModules are the building blocks. Each is a single `.js` file that receives hook input and returns a decision.\n\n### Module Contract\n\n```javascript\n// ~/.claude/hooks/run-modules/PreToolUse/my-gate.js\n// WORKFLOW: shtd\n// WHY: Explain the real incident that caused this module to exist.\nmodule.exports = function(input) {\n  // input.tool_name: \"Edit\", \"Write\", \"Bash\", etc.\n  // input.tool_input: { file_path, command, content, ... }\n  if (shouldBlock) {\n    return { decision: \"block\", reason: \"WHY this is blocked\" };\n  }\n  return null; // pass — allow the action\n};\n```\n\nRules:\n- **Return null** to pass, `{decision: \"block\", reason: \"...\"}` to block\n- **Sync or async** — return a Promise for async work (4s timeout)\n- **Dependencies** — `// requires: mod1, mod2` in first 5 lines\n- **Workflow tag** — `// WORKFLOW: name` restricts module to that workflow (comma-separated for multiple: `// WORKFLOW: shtd, starter`)\n\n### Event Types\n\n| Event | When it fires | Module returns |\n|-------|--------------|----------------|\n| **SessionStart** | New session begins | `{text: \"context to inject\"}` |\n| **UserPromptSubmit** | User sends a message | `{decision: \"block\"}` or `null` |\n| **PreToolUse** | Before Edit/Write/Bash | `{decision: \"block\"}` or `null` |\n| **PostToolUse** | After Edit/Write | `{decision: \"block\"}` or `null` |\n| **Stop** | Session ending | `{decision: \"block\"}` or `null` |\n\n### Write Your First Module\n\nCreate a file that blocks `rm -rf` commands:\n\n```bash\n# Create the module file\ncat \u003e ~/.claude/hooks/run-modules/PreToolUse/no-rm-rf.js \u003c\u003c 'EOF'\n// WORKFLOW: shtd\n// WHY: Accidentally ran rm -rf on a project directory.\nmodule.exports = function(input) {\n  if (input.tool_name !== \"Bash\") return null;\n  var cmd = (input.tool_input || {}).command || \"\";\n  if (/rm\\s+-rf/.test(cmd)) {\n    return { decision: \"block\", reason: \"Blocked rm -rf. Use archive/ instead.\" };\n  }\n  return null;\n};\nEOF\n```\n\nThat's it. Next time Claude tries `rm -rf`, this module blocks it with a helpful message. No settings.json changes needed — the runner auto-discovers modules in the folder.\n\nTest it in isolation before waiting for a real hook trigger:\n\n```bash\nnode setup.js --test-module ~/.claude/hooks/run-modules/PreToolUse/no-rm-rf.js\n```\n\n### Project-Scoped Modules\n\nModules in a subfolder matching your project name only run for that project:\n\n```\nrun-modules/PreToolUse/\n  global-gate.js              # runs for ALL projects\n  my-project/\n    custom-gate.js            # runs ONLY when project name = \"my-project\"\n```\n\n## Architecture\n\n```\n~/.claude/hooks/\n  run-pretooluse.js            # PreToolUse runner\n  run-posttooluse.js           # PostToolUse runner\n  run-stop.js                  # Stop runner\n  run-sessionstart.js          # SessionStart runner\n  run-userpromptsubmit.js      # UserPromptSubmit runner\n  load-modules.js              # shared loader (global + project-scoped + workflow filtering)\n  hook-log.js                  # centralized logging (JSONL)\n  run-async.js                 # async module executor (Promise detection, 4s timeout)\n  workflow.js                  # workflow engine (YAML state machine)\n  run-modules/\n    PreToolUse/*.js            # gate modules\n    PostToolUse/*.js           # post-action checks\n    Stop/*.js                  # session-end controls\n    SessionStart/*.js          # context injection\n    UserPromptSubmit/*.js      # prompt processing\n  workflows/*.yml              # workflow definitions\n```\n\nEach runner reads stdin, discovers modules via `load-modules.js`, calls each in order. First block wins.\n\n## CLI Reference\n\n```bash\n# Setup \u0026 Management\nnode setup.js                          # full setup wizard\nnode setup.js --yes                    # non-interactive setup + default workflows\nnode setup.js --report [--open]        # HTML hooks report\nnode setup.js --health                 # verify runners + modules\nnode setup.js --uninstall [--confirm]  # remove (--confirm restores backup)\n\n# Modules\nnode setup.js --list                   # catalog vs installed comparison\nnode setup.js --sync [--dry-run]       # sync from GitHub per modules.yaml\nnode setup.js --export [file.yaml]     # export config as shareable YAML\nnode setup.js --upgrade [--dry-run]    # fetch latest from GitHub\n\n# Workflows\nnode setup.js --workflow list          # available workflows\nnode setup.js --workflow enable \u003cname\u003e [--global]\nnode setup.js --workflow disable \u003cname\u003e [--global]\nnode setup.js --workflow audit         # coverage + orphan report\nnode setup.js --workflow query \u003ctool\u003e  # which workflows affect a tool\nnode setup.js --workflow create \u003cname\u003e # generate YAML + stubs\nnode setup.js --workflow add-module \u003cworkflow\u003e \u003cmodule\u003e\nnode setup.js --workflow sync-live     # copy to live hooks\n\n# Monitoring\nnode setup.js --stats                  # text summary of hook activity\nnode setup.js --perf                   # module timing analysis\nnode setup.js --integrity [--json]     # verify live modules match repo\nnode setup.js --report --analyze       # heuristic quality analysis\nnode setup.js --prune [N]             # prune log entries older than N days\n\n# Demo \u0026 Development\nnode setup.js --demo [--fast]          # interactive demo (no install needed)\nnode setup.js --demo-html              # generate standalone HTML demo page\nnode setup.js --test-module \u003cfile\u003e [--input \u003cjson\u003e]  # test one module\nnode setup.js --test                   # run all test suites\nnode setup.js --version                # show version\nnode setup.js --help                   # show all commands\n```\n\n## Logging\n\nEvery module invocation is logged to `~/.claude/hooks/hook-log.jsonl` with timestamp, event, module name, result, execution time, and context. Log auto-rotates at 10MB.\n\nThe HTML report (`--report`) visualizes this data with hit counts, latency charts, and a flow diagram. The `--stats` command gives a quick text summary.\n\n## Module Sync\n\nSync modules from GitHub to a new machine or keep an existing install updated:\n\n```bash\n# Create modules.yaml (pick which modules you want)\ncurl -fsSL https://raw.githubusercontent.com/grobomo/hook-runner/main/modules.example.yaml \\\n  \u003e ~/.claude/hooks/modules.yaml\n\n# Sync\nnode setup.js --sync              # install/update selected modules\nnode setup.js --sync --dry-run    # preview first\n```\n\n## Available Modules\n\nFull catalog in `modules/` directory:\n\n### PreToolUse (gates before tool execution)\n| Module | Description |\n|--------|-------------|\n| `archive-not-delete` | Blocks file deletion, suggests archiving instead |\n| `aws-tagging-gate` | Enforces required tags on AWS resource creation |\n| `block-local-docker` | Blocks docker/docker-compose commands |\n| `blueprint-no-sleep` | Blocks sleep between Blueprint MCP calls (pages load during prompt processing) |\n| `branch-pr-gate` | Enforces feature branch → task branch → PR workflow |\n| `claude-p-pattern` | Enforces correct `claude -p` invocation pattern |\n| `commit-counter-gate` | Forces commit after every 15 edits — prevents losing work on context reset |\n| `commit-quality-gate` | Blocks generic commit messages (\u003c 5 words, \"fix\"/\"update\" without detail) |\n| `victory-declaration-gate` | Blocks vague success claims in commit titles (\"all tests pass\", \"all green\", \"100%\") |\n| `unresolved-issues-gate` | Scans TODO.md for unchecked FAIL/WARN/timeout tasks before allowing commit |\n| `continuous-claude-gate` | Blocks code without tracked task workflow |\n| `crlf-ssh-key-check` | Blocks SSH key copy without CRLF stripping |\n| `cwd-drift-detector` | Blocks cross-project file access |\n| `deploy-gate` | Blocks deploy commands when git tree is dirty |\n| `deploy-history-reminder` | Shows last 5 commits before deploy — prevents repeating failed approaches |\n| `disk-space-guard` | Blocks destructive commands after disk space errors |\n| `e2e-self-report-gate` | Alias → `test-checkpoint-gate` (legacy name) |\n| `enforcement-gate` | Requires git repo + TODO.md before edits |\n| `env-var-check` | Blocks edits if required env vars missing |\n| `force-push-gate` | Blocks git push --force to main/master |\n| `gh-auto-gate` | Forces gh_auto wrapper for all gh/git push commands (EMU account safety) |\n| `gsd-gate` | Alias → `test-checkpoint-gate` (legacy name) |\n| `gsd-branch-gate` | Enforces GSD branch naming (seq-phase-N-slug) for new branches |\n| `gsd-plan-gate` | Blocks code edits without a phase plan in GSD workflow |\n| `gsd-pr-gate` | Validates PR creation follows GSD conventions |\n| `git-destructive-guard` | Blocks git reset --hard, checkout ., clean -f without diagnosis |\n| `git-rebase-safety` | Warns about reversed --ours/--theirs during rebase |\n| `hook-editing-gate` | Enforces WORKFLOW tag, WHY comment, exit(1) in hook files |\n| `hook-log-review-gate` | Requires hook-log.jsonl review before creating/editing hook modules |\n| `instruction-to-hook-gate` | Converts user directives into hook modules |\n| `messaging-safety-gate` | Blocks outbound messaging unless authorized |\n| `cross-project-todo-gate` | Blocks writing cross-project TODOs into local TODO.md |\n| `no-adhoc-commands` | Blocks raw aws/ssh/docker/kubectl/az/terraform, forces scripts/ |\n| `no-focus-steal` | Blocks background processes that steal window focus |\n| `no-fragile-heuristics` | Blocks pixel-counting heuristics |\n| `reflection-gate` | Blocks edits if self-reflection found unresolved issues |\n| `no-hardcoded-paths` | Blocks hardcoded absolute paths in code |\n| `no-hook-bypass` | Blocks Bash cat/echo writes when Write/Edit is gated |\n| `no-nested-claude` | Blocks nested claude -p calls (use context-reset for cross-project) |\n| `no-passive-rules` | Blocks .md rules when a hook module is better |\n| `no-playwright-direct` | Blocks raw mcp__playwright__* calls, requires Blueprint Extra MCP |\n| `no-polling-gate` | Blocks LLM-driven polling (loops+sleep, log tailing, comment watching, watch) |\n| `no-rules-gate` | Blocks creation of ~/.claude/rules/ files (use hook modules instead) |\n| `hook-system-reminder` | Reminds Claude that enforcement is ONLY via hook-runner modules |\n| `inter-project-priority-gate` | Blocks non-XREF work when P0 inter-project TODOs are pending |\n| `pr-first-gate` | Blocks spec/code edits on branches without an open PR |\n| `pr-per-task-gate` | Requires task ID in PR titles |\n| `preserve-iterated-content` | Warns on full-file rewrites of iterated files |\n| `publish-json-guard` | Blocks edits to .github/publish.json and git remote config |\n| `remote-tracking-gate` | Blocks edits if branch not pushed to remote |\n| `root-cause-gate` | Blocks retry without root cause diagnosis |\n| `secret-scan-gate` | Blocks commits with API keys or tokens |\n| `settings-change-gate` | Requires rationale when modifying config |\n| `settings-hooks-gate` | Blocks adding hooks directly to settings.json |\n| `spec-before-code-gate` | Forces spec/TODO entry before first file modification after commit |\n| `spec-gate` | Blocks code without specs/tasks.md |\n| `task-completion-gate` | Blocks marking tasks complete without PR evidence |\n| `test-checkpoint-gate` | Blocks code without e2e test (auto-detects `scripts/test/test-TXXX*.sh`) |\n| `why-reminder` | Reminds to explain WHY before every code edit |\n| `worker-loop` | Blocks PR creation until task's e2e test passes |\n| `workflow-compliance-gate` | Blocks if globally enforced workflow disabled at project level |\n| `workflow-gate` | Enforces step order in active workflows |\n| `windowless-spawn-gate` | Blocks module writes using execSync without windowsHide:true |\n| `worktree-gate` | Blocks feature branch edits unless session is in a git worktree |\n\n#### Project-Scoped PreToolUse\n| Module | Project | Description |\n|--------|---------|-------------|\n| `no-customer-env-changes` | ep-incident-response | Blocks infrastructure changes during incident response |\n| `no-data-exfil` | ep-incident-response | Blocks data export/download during incident response |\n| `v1-read-only` | ep-incident-response | Blocks Vision One write operations during incident response |\n| `rdp-testbox-gate` | ddei-email-security | Reminds Claude of proven RDP pattern, separates user/Claude test servers |\n| `share-is-generic` | ddei-email-security | Domain-specific gate for email security project |\n| `use-workers` | hackathon26 | Forces delegation to fleet workers |\n\n### PostToolUse (checks after tool execution)\n| Module | Description |\n|--------|-------------|\n| `background-task-audit` | Warns when background tasks return zero output — forces root cause investigation |\n| `commit-msg-check` | Blocks WIP/fixup commits and long first lines |\n| `crlf-detector` | Warns when Write/Edit produces CRLF in shell scripts, YAML, Python |\n| `disk-space-detect` | Detects disk space errors in tool output, activates alert mode |\n| `hook-autocommit` | Auto-commits hook module edits |\n| `hook-health-monitor` | Detects hook crashes, exit code mismatches, timeouts, repeated failures |\n| `rule-hygiene` | Validates rule files are single-topic, under 20 lines |\n| `settings-audit-log` | Records config modifications to audit log |\n| `test-coverage-check` | Warns when source files modified without tests |\n| `troubleshoot-detector` | Detects fail-fail-succeed patterns |\n| `update-stale-docs` | Detects stale docs after code edits |\n| `empty-output-detector` | Warns when ls/cat/find/curl/kubectl/az return empty output |\n| `inter-project-audit` | Logs inter-project TODO writes to JSONL audit trail |\n| `result-review-gate` | Injects review checklist when reading report/PDF/coverage files |\n| `test-evidence` | Records test pass/fail counts to evidence file for victory-gate validation |\n\n### UserPromptSubmit (processes user prompts)\n| Module | Description |\n|--------|-------------|\n| `instruction-detector` | Detects \"always/never\" directives for enforcement |\n| `interrupt-detector` | Detects user interrupts, triggers self-analysis |\n| `hook-integrity-monitor` | Spot-checks live module integrity each prompt (async, rate-limited) |\n| `prompt-logger` | Logs prompts to JSONL for audit |\n\n### Stop (controls session ending)\n| Module | Description |\n|--------|-------------|\n| `auto-continue` | Blocks stopping — always find the next task |\n| `chat-export` | Auto-exports session to HTML on stop |\n| `config-sync` | Auto-commits and pushes ~/.claude changes to cloud backup |\n| `drift-review` | Checks work matches the active spec task |\n| `log-gotchas` | Captures debugging lessons before stopping |\n| `mark-turn-complete` | Writes turn marker for interrupt detection |\n| `never-give-up` | Blocks \"impossible\" — forces research first |\n| `push-unpushed` | Blocks stop with unpushed commits |\n| `reflection-score` | Gamified scoring system — tracks autonomy, corrections, streaks |\n| `self-reflection` | LLM-powered review of recent gate decisions (async, calls claude -p) |\n| `session-brain-analysis` | Sends session summary to unified-brain for cross-session analysis |\n| `test-before-done` | Reminds to run e2e tests before done |\n| `unresolved-issues-check` | Blocks session end with stale TESTING NOW/IN PROGRESS/WIP tasks |\n\n#### Project-Scoped Stop\n| Module | Project | Description |\n|--------|---------|-------------|\n| `delegate-and-monitor` | hackathon26 | Delegates tasks to fleet workers |\n\n### SessionStart (injects context)\n| Module | Description |\n|--------|-------------|\n| `backup-check` | Warns if config backup is stale |\n| `drift-check` | Daily drift detection against last snapshot |\n| `load-instructions` | Injects working instructions at session start |\n| `load-lessons` | Injects recent self-analysis lessons |\n| `hook-self-test` | Validates runner exit codes and block processing at session start |\n| `lesson-effectiveness` | Detects repeated self-analysis lessons, escalates to gate candidates |\n| `project-health` | Runs health check, warns about issues |\n| `reflection-score-inject` | Injects reflection score/level/streak into session context |\n| `session-cleanup` | Sweeps orphaned session-scoped temp files from crashed sessions |\n| `session-collision-detector` | Warns if another Claude Code session is active on the same project |\n| `terminal-title` | Sets terminal title to project folder name |\n| `inter-project-priority` | Injects P0 inter-project TODOs (XREF tags) at session start |\n| `workflow-summary` | Injects active workflow summary |\n\n## Troubleshooting\n\n**Module not running?**\n- Check `node setup.js --health` for load errors\n- Check `node setup.js --workflow audit` for workflow tag issues\n- Check `node setup.js --list` to see if it's installed\n\n**Hook blocked something it shouldn't?**\n- Check `node setup.js --stats` to see which module blocked\n- Read the module's `// WHY:` comment to understand intent\n- Disable its workflow: `node setup.js --workflow disable \u003cname\u003e`\n\n**Want to see what's happening?**\n- `node setup.js --report --open` for visual overview\n- `node setup.js --perf` for timing data\n- Check `~/.claude/hooks/hook-log.jsonl` for raw logs\n\n**Uninstall cleanly:**\n- `node setup.js --uninstall --confirm` restores your original settings.json\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrobomo%2Fhook-runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrobomo%2Fhook-runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrobomo%2Fhook-runner/lists"}