run observable commands at agent boundaries
Lifecycle hooks
#Configure hook commands under hooks in ~/.dgc/config.json. Native local/API turns can call six lifecycle events: SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PreCompact, and Stop. Delegated subscription turns call SessionStart and Stop; their vendor-owned prompt and internal tool loop is not visible to DGC's prompt/tool hook events.
- /hooks — show every supported event, its bounded configured count, redacted exact tool matchers, and invalid configuration state. Shell commands and environment values are never shown.
PreToolUseandUserPromptSubmitcan block an action with a non-zero exit.PostToolUseoutput is returned to the model as bounded feedback.- Hook batches share the workspace mutation lease, own a process group, have one bounded deadline, drain a bounded redacted head/tail, and honor
/sandbox. - Headless controllers use
{"type":"list_hooks","request_id":"hooks-1"}and receivehook_catalog. Natural execution emitshook_activitywithstartedand exactly one terminal status; there is deliberately no command that executes a hook outside its lifecycle boundary. - ACP represents configured hook runs as ordinary command-free tool-call lifecycle updates.
Configuring one
#Each event takes a list of entries. command is required; matcher is optional and narrows a tool event to one tool:
{
"hooks": {
"PreToolUse": [{"matcher": "bash", "command": "./scripts/guard.sh"}],
"PostToolUse": [{"command": "./scripts/format.sh"}],
"UserPromptSubmit": [{"command": "./scripts/log-prompt.sh"}]
}
}The event payload arrives on stdin as JSON, so a hook reads it rather than taking arguments:
#!/usr/bin/env bash
# ./scripts/guard.sh — refuse a bash command that touches the release directory
payload=$(cat)
case "$payload" in
*dist/release*) echo "release artifacts are off limits to the agent"; exit 1 ;;
esacExit status is the control surface:
- a
PreToolUseorUserPromptSubmithook that exits non-zero blocks the action, and its output becomes the reason the agent is shown; - a
PostToolUsehook's output is appended to the tool result as feedback, so the agent reads it and can react; - every other event ignores the exit status.
Use /hooks to confirm what DGC actually loaded — it reports the configured count and redacted matchers per event without echoing your commands.