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 (for example Cursor → .cursor/hooks.json, Claude Code → .claude/settings.json). Unsupported providers get a warning and are skipped — install does not fail.