Skip to main content

Hooks

中文版

Hooks run a command around an Agent event. Use them for policy checks, notifications, or extra context, and enable them only from a source you trust.

Enable and manage Hooks

Define them in ~/.copilot-shell/config.toml or a trusted project config:

[hooks]
enabled = true

[[hooks.PreToolUse]]
name = "security-check"
command = "/usr/local/bin/my-security-hook"
matcher = "shell"
timeout = 60000

In the interactive terminal:

/hooks
/hooks history
/hooks trust-project
/hooks enable <id>
/hooks disable <id>

Project Hooks do not run until the project root is trusted. Use /hooks untrust-project to remove that trust. Shell Hook state is session-local; Agent Hook state is persisted by the registry.

Event names

EventWhen it runsCan block?
PreToolUseBefore a tool callYes
PostToolUseAfter a successful tool callYes
PostToolUseFailureAfter a failed tool callNo
UserPromptSubmitWhen a prompt is submittedYes
SessionStartAfter session initializationNo
StopWhen the Agent stopsYes
BeforeModel / AfterModelAround a model requestNo

Use matcher to limit tool events. Hook commands receive one JSON object on stdin. The object includes hook_event_name, session_id, cwd, and event data such as tool_name and tool_input.

Return a decision

Write one JSON object to stdout:

{
"decision": "block",
"reason": "Dangerous command",
"systemMessage": "Command blocked by security policy"
}

allow continues, block/deny stops the operation, ask requests user confirmation, and an empty response passes through. Exit code 2 also blocks; other non-zero exits are warnings. The default timeout is 60 seconds; set a shorter timeout when a check must be quick. Use sequential = true when multiple Hooks for an event must run in order.

Add context or child-process variables

hookSpecificOutput.additional_context adds text to the Agent context. An env map is injected into the Hook child only:

[[hooks.SessionStart]]
name = "load-context"
command = "/usr/local/bin/load-context"
env = { TEAM = "platform" }

The host process is not changed. Environment names must match [A-Za-z_][A-Za-z0-9_]*; values are not printed. Extension Hooks use the same config and protocol; see Extensions.