Hooks
Hooks run at agent lifecycle events (session start, before shell, after file edit, and more). You declare them once; capa translates each hook into the provider-specific config shape and tags its entries as capa:<id> so install/clean stay surgical.
Add a hook
Section titled “Add a hook”Edit hooks in the capabilities file, or use the CLI:
capa add --hook --id audit-shell --on beforeShell --command 'date >> ~/.capa/audit.log'capa add --hook --id greet --on sessionStart --type prompt --prompt 'Remember project conventions.'capa installSee CLI: add for source flags (--source, --command, --prompt, --type).
Hook shape
Section titled “Hook shape”| Field | Notes |
|---|---|
id | Stable id → capa:<id> in provider configs |
on | Canonical event (beforeShell, afterFileEdit, …) or provider-scoped (cursor:beforeShellExecution) |
type | command (default) or prompt |
command / prompt | Inline body when you do not use source |
source | inline, remote, github, gitlab, or local (path in the project) |
matcher, timeout, failClosed, sequential, providers | Optional controls; failClosed is Cursor-oriented today |
Canonical events include sessionStart, sessionEnd, userPromptSubmit, beforeTool, afterTool, afterToolFailure, beforeShell, afterShell, beforeFileRead, afterFileEdit, beforeMcpCall, afterMcpCall, subagentStart, subagentStop, preCompact, and stop.
hooks: - id: audit-shell description: Timestamp every shell invocation on: beforeShell command: 'date >> ~/.capa/audit.log' timeout: 5
- id: block-rm-rf on: cursor:beforeShellExecution matcher: 'rm -rf *' failClosed: true command: 'echo "blocked" && exit 1'
- id: log-bash-commands on: beforeShell source: type: local path: scripts/log-bash.shNon-local sources are materialized under ~/.capa/hooks/<projectId>/. source.type: local references your project file in place (no copy; capa clean will not delete it).
Installed per provider
Section titled “Installed per provider”capa installs hooks only for providers that support them. Unsupported providers get a warning and are skipped: install does not fail.
| Provider | Config file |
|---|---|
| Claude Code | .claude/settings.json → hooks |
| Codex | .codex/config.toml → [hooks] |
| Cursor | .cursor/hooks.json |
| Gemini CLI | .gemini/settings.json → hooks |
matcher is written in each provider’s native field: for Cursor that is matcher on the hook entry (use it, for example, to filter postToolUse to Write|Edit).
Re-installs and capa clean edit only entries tagged capa:<id>. If several capa hooks share one config file, capa still finds and removes each of its entries even after earlier ones were removed or moved, so no stale capa entries are left behind.