Make quality and safety
a deterministic flow.
Agent_hook is the shared hook source repo for 4 AI CLIs (opencode / codex / cursor / kimi).
Claude Code-style Python scripts — one source, four adapters.
Block dangerous bash, protect .env, format on save,
run tests on Stop — enforced by code, not by prompt.
REAL EVIDENCE
Real node load. Real Python block. Real exit 2.
Not mock. opencode truly spawns
python3 hook.py, talking the same
stdin/stdout/exit-code protocol as Claude Code. When the LLM tries to write
.env, the hook returns
{block: true, reason: ...} and the write is refused.
$ echo '{"tool":"Write","parameters":{"filePath":"/proj/.env"}}' \
| python3 registry/protect-sensitive-files/source/hook.py
{
"block": true,
"reason": "protect-sensitive-files: blocked write to '/proj/.env'
— matches exact name '.env'. Override via
AGENT_HOOK_ALLOW_SENSITIVE=path1:path2 if intentional."
}
$ echo $?
2
9 HOOKS
From SessionStart to PreCompact — full event coverage.
protect-sensitive-files
PreToolUse blocks .env / *.pem / credentials / migrations.
guard-bash
PreToolUse blocks rm -rf, git reset --hard, curl|sh, DROP TABLE.
post-edit-format
PostToolUse runs prettier / ruff / gofmt / shfmt.
session-context-injector
SessionStart injects branch / last commit / active plans.
final-verify
Stop reports changed files / open TODOs / test results.
prompt-context-enricher
UserPromptSubmit appends issue / branch / working-tree state.
subagent-acceptance
SubagentStop catches "should work" / "did not run" patterns.
notify-on-idle
Notification fires macOS osascript desktop alerts.
pre-compact-save
PreCompact snapshots plans / TODOs / state for recovery.
$ agent-hook list
name events opencode cursor kimi
final-verify Stop managed absent managed
guard-bash PreToolUse managed managed managed
post-edit-format PostToolUse managed absent managed
protect-sensitive-files PreToolUse managed managed managed
session-context-injector SessionStart managed managed managed
4-CLIENT ADAPTERS
One Python script, four client shapes.
opencode gets a JS plugin wrapping the real Python. cursor gets a degraded Rule (soft constraint). kimi gets a config.toml hooks=[] entry. codex has no native hook concept and is skipped. Each hook explicitly declares native/adapter/unsupported per client in its manifest.
See the full architecture →Built for people who don't want LLM mistakes to nuke the repo.
Your .env can't be touched
protect-sensitive-files uses stdin/stdout/exit-2 to actually block writes — not prompt-cajole.
Your repo refuses rm -rf
17 dangerous patterns + 3 env-var escape hatches when you really need them.
You want Stop to be a quality gate
final-verify returns changed-files summary, residual TODOs, optional test run.
One command, four clients.
agent-hook install final-verify --client all.
Every write to a client config gets a timestamped backup and a managed-by anchor.