AtomCode Hooks
Hooks 系统允许你在 AtomCode 的关键执行点插入自定义逻辑,实现灵活的扩展能力。
快速开始
三步配置:目录 → 脚本 → TOML
步骤 1:创建 hooks 目录
# 全局 hooks(对所有项目生效)
mkdir -p ~/.atomcode/hooks
# 项目级 hooks(仅当前项目生效,可覆盖同名全局 hook)
mkdir -p .atomcode/hooks
步骤 2:编写 hook 脚本
创建 ~/.atomcode/hooks/my_hook.sh:
#!/bin/bash
# 通 过 stdin 接收上下文 JSON
INPUT=$(cat)
# 解析关键信息(推荐安装 jq:brew install jq / apt-get install jq)
if command -v jq &> /dev/null; then
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
echo "Hook saw tool: $TOOL" >&2
else
# 无 jq 时可用 python 替代:
# TOOL=$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_name',''))" 2>/dev/null)
echo "Hook: raw input received" >&2
fi
# 返回执行结果
echo "ok"
赋予执行权限:
chmod +x ~/.atomcode/hooks/my_hook.sh
步骤 3:配置 hooks.toml
创建 ~/.atomcode/hooks/hooks.toml:
[[hooks]]
name = "my-hook"
description = "My custom hook"
trigger = "post_tool" # 触发时机
script = "my_hook.sh"
script_type = "shell" # shell | python
enabled = true
timeout_secs = 2
完成!启动 AtomCode 后 hook 会自动加载。
配置方式总览
AtomCode 支持 三种 hook 实现,通过两个配置文件管理:
| 方式 | 配置文件 | 实现 | 适用场景 |
|---|---|---|---|
| TOML ScriptHook | hooks.toml → [[hooks]] |
本地脚本(shell/python) | 本地定制、快速原型 |
| TOML Webhook | hooks.toml → [[webhooks]] / [[async_webhooks]] |
HTTP 远程调用 | 云端服务、外部集成 |
| JSON CC 兼容 | .hooks.json / hooks.json |
Shell 命令(旧协议) | 兼容 CC 插件 |
三种方式可以共存。实际上都是通过
HookEngine::load_all()统一加载:
- JSON hooks(
hooks.json)- TOML hooks(ScriptHook + WebhookHook,来自
hooks.toml)- 内置 Hook(Rust 原生,自动注册)
全局 hooks 先加载,项目 hooks 后加载。项目级同名 hook 覆盖全局同名 hook(后加载优先)。
TOML ScriptHook(推荐)
支持的 trigger 值
| trigger 值 | 别名 | 触发时机 | 可影响流程 |
|---|---|---|---|
pre_tool |
pre_tool_execution |
工具执行前 | ✅ 可阻止/修改参数 |
post_tool |
post_tool_execution |
工具执行后 | ❌ fire-and-forget |
post_turn |
— | Turn 完成后 | ❌ fire-and-forget |
system_prompt |
— | 构建系统 prompt 时 | ✅ 追加指令 |
脚本输入(stdin JSON)
{
"tool_name": "edit_file",
"tool_args": "{\"file_path\": \"...\", ...}",
"working_dir": "/path/to/project",
"session_id": "session-123",
"turn_number": 5
}
post_tool 会额外包含 result_context:
{
"result_context": {
"tool_name": "edit_file",
"tool_args": "{...}",
"result": "File updated",
"success": true,
"duration_ms": 150
}
}
system_prompt 的 stdin 输入与 post_turn 一致(包含基础上下文,无 tool_args/result_context)。脚本应将追加的系统 Prompt 内容输出到 stdout(纯文本或 JSON 的 message 字段)。
脚本输出格式
ok # 继续(默认)
deny: <reason> # 阻止(仅 pre_tool 有效)
modify: <new_args> # 替换参数(仅 pre_tool 有效)
warning: <message> # 继续但打印警告
也可以输出 JSON(推荐):
{"result": "ok", "message": "checked"}
{"result": "deny", "message": "unsafe path"}
{"result": "modify", "modified_content": "{\"file_path\": \"/safe\"}"}
{"result": "warning", "message": "file is large, review carefully"}
完整配置示例
[[hooks]]
name = "pre-check"
description = "阻止危险的 write 操作"
trigger = "pre_tool"
script = "check_write.sh"
script_type = "shell"
enabled = true
timeout_secs = 3
TOML Webhook
支持的 trigger 值(逗号分隔多个)
| trigger 值(规范) | 别名 | 触发时机 |
|---|---|---|
turn_start |
— | Turn 开始前 |
tool_call_start |
— | 工具调用开始时 |
pre_tool |
before_tool |
工具执行前 |
post_tool |
after_tool |
工具执行后 |
turn_complete |
after_turn |
Turn 完成后(详细统计) |
post_turn |
— | Turn 完成后(旧版兼容) |
session_start |
— | 会话启动时 |
session_end |
— | 会话结束时 |
error |
— | 错误发生时 |
model_response |
— | 模型响应完成后 |
system_prompt |
— | 系统 Prompt 构建时 |
message² |
message_received |
用户消息接收时 |
使用 contains 匹配(逗号分隔多个 trigger)。例如
trigger = "pre_tool,post_tool"会在两个时机都触发。²
message:WebhookHook 已实现对应 trait,但引擎尚未注册触发槽位,当前实际不可用。
同步 Webhook
[[webhooks]]
name = "slack-notify"
description = "发送工具调用通知到 Slack"
trigger = "pre_tool,post_tool"
url = "https://hooks.slack.com/services/XXX"
method = "POST"
timeout_secs = 10
retries = 2
enabled = true
[webhooks.headers]
Authorization = "Bearer YOUR_TOKEN"
异步批量 Webhook(高频场景推荐)
[[async_webhooks]]
name = "audit-log"
trigger = "post_tool"
url = "https://log.example.com/batch"
timeout_secs = 10
batch_size = 20 # 默认 10,达到后发送
flush_interval_ms = 1000 # 默认 1000ms,定时刷新
retries = 2
enabled = true
[async_webhooks.headers]
Authorization = "Bearer AUDIT_TOKEN"
异步 Webhook 不阻塞主流程。详细用法见 Webhook 指南 和 异步 Webhook 指南。
JSON CC 兼容配置
兼容 Claude Code 插件的 .hooks.json。加载路径:
~/.atomcode/hooks.json— 全局<project>/.hooks.json— 项目(覆盖同名全局)
{
"hooks": {
"my-hook": {
"event": "pre_tool_use",
"matcher": "write*",
"command": "echo '{\"action\": \"allow\"}'",
"timeout_ms": 10000,
"disabled": false
}
}
}
支持的 event 值:pre_tool_use、post_tool_use、session_start、session_end、user_prompt_submit。
Hook 通过环境变量接收上下文(ATOMCODE_HOOK_EVENT、ATOMCODE_HOOK_CONTEXT、ATOMCODE_TOOL_NAME 等),stdout 需输出 {"action": "allow" | "block" | "modify"} JSON。
内置 Hook(无需配置,自动启用)
| Hook | 触发时机 | 功能 |
|---|---|---|
ToolAuditLogHook |
工具调用时 | 记录调用到审计日志(tracing) |
TurnStatsHook |
Turn 开始+完成 | 统计 Turn 耗时和操作 |
AutoCommitHook |
Turn 完成 | 每 N 个 Turn 自动 git commit |
SessionSummaryHook |
会话开始+结束 | 打印会话摘要 |
ErrorReportHook |
错误发生时 | 记录错误详情 |
ResponseValidationHook |
模型响应后 | 检测敏感信息 |
内置 Hook 自动注册,暂不支持通过配置禁用(后续 CLI 会提供 enable/disable 开关)。同名项目级 hook 无法覆盖内置 Hook(内置 Hook 是 Rust 原生,不在 TOML 配置体系内)。
CLI 命令
# 列出已加载的 hooks
atomcode hooks list
# 查看配置路径
atomcode hooks paths
# 测试单个 hook
atomcode hooks test my-hook
安全注意事项
- 项目 hooks 可覆盖全局 hooks 同名项(项目 hooks 后加载)
- Hooks 不能绕过权限系统 —
pre_tooldeny 不覆盖用户的always_allow设置 - 脚本执行有超时 — TOML ScriptHook 默认 2 秒,JSON 默认 10 秒,Webhook 默认 10 秒
- 脚本在用户权限下运行 — 注意脚本本身的安全性
- 超时/崩溃 fail-open — 脚本超时或崩溃时视为
ok,不阻塞流程
相关文档
- CLI 使用指南 —
atomcode hooks命令详解 - 完整时机列表 — 所有 hook 时机、可用配置方式
- Webhook 指南 — HTTP 远程调用
- 异步 Webhook 指南 — 批量异步发送
- 技术架构 — 面向开发者的架构参考