Skip to main content

Hooks

Hooks let external scripts observe, audit, and control TalkOps lifecycle events—across interactive TUI sessions, headless CI/CD runs, and centralized talkops serve webhook investigations (src/talkops/hooks/ and src/talkops/webhooks/dispatcher.py).

When a matching tool call, subagent delegation, session event, or inbound webhook fires, TalkOps runs your configured shell commands in a sanitized environment (sanitize_hook_environ), passes structured context via JSON payloads and interpolation variables, and inspects the exit code or JSON decision to allow, modify, or abort execution.

Hooks execute shell commands with your user or server process permissions. Treat .talkops/hooks.json as executable code and only trust project hooks from repositories you have reviewed.


Where hooks are configured​

Declare hooks at the user-global or project-repository level:

File PathScopeTrust Model
~/.talkops/hooks.jsonUser-global (applies to all workspaces and talkops serve)Always trusted
.talkops/hooks.jsonProject-level (checked into Git)Prompts for interactive confirmation or requires --trust-project-hooks in headless mode

Supported hook events​

TalkOps supports three categories of hook triggers:

1. Lifecycle & agent events (Hooks v2 in src/talkops/hooks/models/)​

Event NameWhen It FiresCan Block / Modify Execution?
SessionStartWhen a new interactive, headless, or remote session starts (startup, resume, clear, compact)Can inject startup context
UserPromptSubmitWhen a user submits a prompt before the orchestrator runsYes (can block or append context)
PreToolUseImmediately before a tool executes (Bash, Write, Edit, Read, Glob, Grep, LS, mcp__*)Yes (allow, deny, ask, or modify input)
PermissionRequestWhen a tool triggers a human-in-the-loop permission interruptYes (allow or deny programmatically)
PostToolUseImmediately after a tool finishes successfullyCan append follow-up context
PostToolUseFailureWhen a tool execution raises an error or non-zero exit codeCan inject diagnostic recovery hints
SubagentStartWhen the orchestrator dispatches one of the 21 domain subagentsCan inject subagent instructions
SubagentStopWhen a delegated subagent finishes its runCan validate subagent output
PreCompactImmediately before context compaction (/compact or auto-compact)Can preserve custom state
StopWhen the main agent finishes responding to a turnCan force continuation if checks fail
NotificationWhen TalkOps emits an operational notificationObservational
SessionEndWhen a session terminates (exit, clear, logout)Observational

2. Webhook ingestion events (WebhookDispatcher in src/talkops/webhooks/dispatcher.py)​

When running talkops serve / talkops webhooks, the webhook dispatcher fires two dedicated lifecycle events:

Event NameWhen It FiresPayload Fields Passed to Hook
webhook.receivedImmediately when an actionable webhook is accepted (202 Accepted) and mapped to a LangGraph thread_iddelivery_id, thread_id, provider, event_type, severity, title, incident_id, source_service, rbac_role
webhook.completedWhen the background LangGraph investigation finishes and outbound RCA sinks completedelivery_id, thread_id, provider, event_type, severity, title, incident_id, status (completed or failed)

3. Direct tool wire-name matchers (src/talkops/hooks/tools.py)​

You can bind hooks directly to canonical tool wire names with ${input.<field>} interpolation:

Wire Tool NameInternal ToolAvailable ${input.<field>} Variables
Bashexecute (shell command)command, timeout
Writewrite_filefile_path, content
Editedit_filefile_path, old_string, new_string, replace_all
Readread_filefile_path, offset, limit
Globglobpattern, path
Grepgreppattern, path, glob, output_mode
LSlspath
mcp__<server>__<tool>External MCP tool callTool-specific input arguments

Execution flow & exit codes​

  • Exit code 0: Execution proceeds normally.
  • Non-zero exit code: For pre-execution hooks (PreToolUse, Bash, Write, Edit), TalkOps cancels the tool call, captures the hook's stderr, and feeds the message back to the agent so it can remediate the violation.
  • Secret Environment Sanitization (sanitize_hook_environ): TalkOps automatically strips sensitive LLM and cloud secret environment variables before spawning untrusted hook subprocesses while passing TALKOPS_SESSION_ID, TALKOPS_TOOL_NAME, TALKOPS_TOOL_INPUT, and TALKOPS_TOOL_OUTPUT.

Practical DevOps examples​

1. Auto-format Terraform and OpenTofu files on every write/edit
{
"hooks": {
"Write": {
"command": "if echo '${input.file_path}' | grep -qE '\\.(tf|tofu)$'; then tofu fmt '${input.file_path}' 2>/dev/null || terraform fmt '${input.file_path}' 2>/dev/null || true; fi"
},
"Edit": {
"command": "if echo '${input.file_path}' | grep -qE '\\.(tf|tofu)$'; then tofu fmt '${input.file_path}' 2>/dev/null || terraform fmt '${input.file_path}' 2>/dev/null || true; fi"
}
}
}
2. Block file writes containing hardcoded AWS keys or GitHub tokens
{
"hooks": {
"Write": {
"command": "python3 -c \"import sys, re; content = open('${input.file_path}').read(); sys.exit(1) if re.search(r'(AKIA[0-9A-Z]{16}|ghp_[0-9a-zA-Z]{36})', content) else sys.exit(0)\""
}
}
}
3. Audit inbound production webhooks (webhook.received & webhook.completed)

Log every webhook-triggered incident investigation and its resulting LangGraph thread_id to a local SIEM file or metrics collector:

{
"hooks": {
"webhook.received": {
"command": "jq -c '. + {\"hook\": \"webhook.received\"}' >> /var/log/talkops/webhook-audit.jsonl"
},
"webhook.completed": {
"command": "jq -c '. + {\"hook\": \"webhook.completed\"}' >> /var/log/talkops/webhook-audit.jsonl"
}
}
}

Next steps​