---
name: agent_hooks_design
description: 当需要继续讨论或实现本项目的 hooks / 生命周期钩子功能时，应该索引本记忆
---

# Hooks / 生命周期钩子功能设计讨论（进行中）

## 调研结论

### 主流实现
- **Claude Code**：最完整，20+ 事件、5 种 handler（command/http/mcp_tool/prompt/agent）、多层配置（全局/项目/本地/组织/插件/SDK）。
- **OpenAI Codex**：11 个事件、command 回调为主、有信任审查机制和企业托管 hooks。
- **Cursor**：`.cursor/hooks.json`，Beta，command 回调，项目/用户/企业三级。
- **GitHub Copilot**：`.github/hooks/*.json`，command/http/prompt 三种回调，Cloud Agent 也支持。
- **Windsurf/Cascade**：`.windsurf/hooks.json`，exit 2 阻断，12 个事件。
- **Aider / Continue.dev / Kimi Code / Devin**：无原生 hooks 或资料有限。

### 共性模式
```
Agent 事件发生
    ↓
stdin 发送 JSON 事件载荷 → Hook 脚本 / HTTP 端点
    ↓
返回决策（allow/deny/ask/modify/injectMessage）
    ↓
Agent 根据决策继续执行
```

## 用户（项目 owner）对 hooks 的理解

> 钩子 = 发生一件事件之前/中/后 → 自动触发另一个事件。用 JSON 格式写条件和行为，分为全局/项目级，放在数据存储目录下/工作区内。

用户认可的核心：**事件驱动 + JSON 配置 + 全局/项目两级 + before/after 拦截**。

## 已达成的设计共识

### 1. 配置位置
- 全局：`~/.astrion/astrion/config/hooks.json`
- 项目级：`<project>/.astrion/hooks.json`
- 未来可扩展：`.astrion/hooks.local.json`、企业策略级。
- 多层配置**合并执行**，不是覆盖（更安全）。

### 2. 优先事件（MVP 范围建议）
- `PreToolUse`：工具执行前拦截/修改
- `PostToolUse`：工具执行后触发后续动作
- `Stop`：模型/turn 结束时注入反馈
- `PreCompact`：上下文压缩前备份

### 3. 优先回调类型
- MVP 只做 `command`（shell/python/任意可执行文件）。
- 后续可扩展 `http`、`prompt`、`agent`、`mcp_tool`。

### 4. 通信协议（对齐 Claude Code/Codex）
- stdin 输入 JSON 事件载荷
- stdout 返回 JSON 决策
- exit code：0=通过，1=非阻断错误，2=阻断

### 5. JSON 结构草案

```json
{
  "version": 1,
  "disabled": false,
  "hooks": {
    "PreToolUse": [
      {
        "name": "block-dangerous-rm",
        "matcher": "run_command",
        "if": "command contains 'rm -rf /'",
        "enabled": true,
        "max_repeats": null,
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.astrion/astrion/hooks/block_dangerous.py",
            "timeout": 5,
            "statusMessage": "检查危险命令...",
            "fail_policy": "continue",
            "on_error": "log"
          }
        ]
      }
    ],
    "Stop": [
      {
        "name": "remind-check-completion",
        "max_repeats": 3,
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.astrion/astrion/hooks/remind_check.py",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
```

## 已讨论的具体例子

### 例子 1：拦截危险命令
- 事件：`PreToolUse`
- 条件：`matcher=run_command` + `if=command contains 'rm -rf /'`
- 行为：调用脚本，返回 `permissionDecision: deny`

### 例子 2：edit_file 单行全替换触发审核
- 事件：`PreToolUse`
- 条件：`matcher=edit_file` + `old_string` 只有一行 + `replace_all=true`
- 行为：返回 `permissionDecision: ask`

### 例子 3：Stop 时自动插入 user 消息，最多 3 次
- 事件：`Stop`
- 行为：返回 `injectMessage: {role: "user", content: "请仔细检查是否真的完成了所有工作"}`
- "最多 3 次"可用 `max_repeats` 或由脚本自己维护状态文件。

## 尚未决定的决策点

1. **`if` 条件表达式语法**：
   - 选项 A：简单规则 DSL（如 `command contains '...'`）
   - 选项 B：结构化 JSON（如 `{"field": "...", "op": "contains", "value": "..."}`）
   - 选项 C：交给 hook 脚本自己判断，`if` 只保留工具名匹配

2. **"最多 N 次"由谁负责**：
   - 框架负责 `max_repeats`（简单，但状态语义固定）
   - 脚本自己维护状态文件（灵活，框架更轻量）

3. **注入消息语义**：
   - `injectMessage.user`：会触发模型再回复一轮
   - `addContext.system`：只是给下一轮加提示，不立刻触发回复

4. **hook 失败时的主流程策略**：
   - 默认 `continue`（用户配置错误不瘫痪智能体）
   - 或提供 `fail_policy: block` 让管理员强制策略

5. **工具名匹配**：
   - 是否同时支持内部工具名（`run_command`/`edit_file`）和 Claude Code 风格别名（`Bash`/`Edit|Write`）

## 推荐后续路线

1. 先定 JSON schema 和 `if` 语法。
2. MVP 实现 `command` 回调 + `PreToolUse`/`PostToolUse`/`Stop`。
3. 新增 `modules/hook_manager.py`。
4. 在 `core/main_terminal_parts/tools_execution.py` 和 `core/web_terminal.py` 插入 hook 调用。
5. 确保 API task 模式也走 hooks。
6. 补文档 `docs/hooks.md`。

## 参考资料位置

- 调研报告：`research/claudecode_hooks/claudecode_hooks.md`
- 调研报告：`research/codex_hooks/codex_hooks.md`
- 调研报告：`research/other_agents_hooks/other_agents_hooks.md`
