Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Model: claude-opus-4-6 (anthropic/claude-opus-4-6) Generated: 2026-04-03 Book: Claude Code VS OpenCode: Architecture, Design and The Road Ahead 章节: 第12章 — 解剖一个13万行代码的插件 Token Usage: ~120,000 input + ~6,800 output

12.5 钩子系统深度剖析

从 8 到 41:多路复用的秘密

12.2 节介绍了 8 个 hook handler。但 OMO 内部实际有 41 个 hook。OpenCode 只给了少数入口,41 个 hook 怎么挂上去?

答案是 多路复用(Multiplex)

💡 什么是多路复用? 你家一根网线(物理通道)能同时看视频、下载、视频通话(多个逻辑通道)。OMO 一样——少量宿主 hook 入口承载多个内部策略。

graph TD
    subgraph Inputs["OpenCode Hook Points - Few"]
        H1["tool.execute.before"]
        H2["tool.execute.after"]
        H3["event"]
        H4["messages.transform"]
        H5["chat.message"]
    end

    subgraph Outputs["OMO Internal Hooks - Many"]
        A["fileGuard, labelTrunc<br/>rulesInject, commentCheck<br/>...10+ hooks"]
        B["outputTrunc, compaction<br/>ctxMonitor, recovery<br/>...10+ hooks"]
        C["autoUpdate, todoCont<br/>ralphLoop, atlas<br/>...10+ hooks"]
        D["ctxInjector<br/>thinkingValidator"]
        E["variantGate, keyword<br/>autoSlash, startWork"]
    end

    H1 --> A
    H2 --> B
    H3 --> C
    H4 --> D
    H5 --> E

五层分类

📁 文件说明:src/hooks/create-hooks.ts Hook 系统的总工厂。合并三大类 hook:core hooks、continuation hooks、skill hooks。

flowchart TD
    Factory["createHooks()"] --> Core["createCoreHooks()"]
    Factory --> Cont["createContinuationHooks()"]
    Factory --> Skill["createSkillHooks()"]

    Core --> Session["Session Layer"]
    Core --> Guard["Tool-Guard Layer"]
    Core --> Transform["Transform Layer"]

41 个 hook 分五层:

graph TD
    subgraph L1["Layer 1: Session"]
        S1["autoUpdate"]
        S2["ccHooks"]
        S3["bgNotification"]
        S4["sessionNotification"]
        S5["ctxWindowMonitor"]
        S6["thinkMode"]
    end
    subgraph L2["Layer 2: Tool-Guard"]
        T1["writeFileGuard"]
        T2["labelTruncator"]
        T3["commentChecker"]
        T4["rulesInjector"]
        T5["directoryInjectors"]
    end
    subgraph L3["Layer 3: Transform"]
        R1["contextInjector"]
        R2["thinkingValidator"]
    end
    subgraph L4["Layer 4: Continuation"]
        C1["todoContinuation"]
        C2["ralphLoop"]
        C3["stopGuard"]
        C4["compactionPreserver"]
    end
    subgraph L5["Layer 5: Skill"]
        K1["agentReminder"]
        K2["categorySkillReminder"]
    end
层级关注什么典型例子
Session会话生命周期后台通知、上下文报警
Tool-Guard工具执行保护防误覆盖、注入规则
Transform消息历史改写注入上下文、校验结构
Continuation持续执行策略todo 自动继续、Ralph Loop
Skill辅助提醒提醒可用 agent/skill

执行顺序就是优先级

原则:先安全防护 → 再规范化 → 再注入规则 → 最后具体策略。

tool.execute.before 流水线

📁 文件说明:plugin/tool-execute-before.ts 工具执行前拦截。按优先级依次执行十几个 hook。

flowchart TD
    Input(["Tool Call"]) --> S["Safety Layer"]
    subgraph S["1. Safety"]
        S1["writeFileGuard"]
    end
    S --> N["Normalize Layer"]
    subgraph N["2. Normalize"]
        N1["labelTruncator"]
    end
    N --> Compat["Compat Layer"]
    subgraph Compat["3. Compatibility"]
        CP1["ccHooks"]
        CP2["nonInteractive"]
    end
    Compat --> Rules["Rules Layer"]
    subgraph Rules["4. Rules Injection"]
        R1["commentChecker"]
        R2["directoryInjectors"]
        R3["rulesInjector"]
    end
    Rules --> Policy["Policy Layer"]
    subgraph Policy["5. Specific Policies"]
        P1["todowriteDisabler"]
        P2["prometheusGuard"]
        P3["sjNotepad"]
        P4["atlas"]
    end
    Policy --> Rewrite["Arg Rewrite Layer"]
    subgraph Rewrite["6. Argument Rewrite"]
        RW1["task: category -> subagent_type"]
        RW2["task: session_id -> resolve agent"]
    end
    Rewrite --> Exec(["Tool Executes"])

tool.execute.after 流水线

flowchart TD
    Result(["Tool Result"]) --> M["1. Metadata Rewrite"]
    M --> CC["2. CC Compat Hooks"]
    CC --> Trunc["3. Output Truncator"]
    Trunc --> Compact["4. Preemptive Compaction"]
    Compact --> Monitor["5. Context Monitor"]
    Monitor --> Check["6. Comment + Dir + Rules"]
    Check --> Detect["7. Empty Task Detector"]
    Detect --> Remind["8. Agent/Category Reminder"]
    Remind --> Recover["9. Edit/JSON Recovery"]
    Recover --> Retry["10. Delegate Task Retry"]
    Retry --> Atlas["11. Atlas + Resume Info"]
    Atlas --> Hash["12. Hashline Enhancer"]
    Hash --> Output(["Final Output"])

event hook 分发

flowchart TD
    Event(["Session Event"]) --> Dedup["500ms Dedup"]
    Dedup --> Dispatch["dispatchToHooks()"]

    Dispatch --> G1["autoUpdate"]
    Dispatch --> G2["ccHooks"]
    Dispatch --> G3["bgNotification"]
    Dispatch --> G4["todoContinuation"]
    Dispatch --> G5["ctxWindowMonitor"]
    Dispatch --> G6["rulesInjector"]
    Dispatch --> G7["thinkMode"]
    Dispatch --> G8["ralphLoop"]
    Dispatch --> G9["atlas"]
    Dispatch --> G10["...more"]

降级策略:一个 hook 坏了不影响全局

flowchart TD
    Create["safeCreateHook()"] --> Try{Creation OK?}
    Try -->|Yes| Active["Hook Active"]
    Try -->|No| Null["Return null<br/>Skip this hook"]
    Null --> Others["Other 40 hooks<br/>continue normally"]

优雅降级:41 个家电中一个灯泡坏了,换灯泡就好,不用给整栋楼断电。


版本自适应

flowchart TD
    Check["directoryAgentsInjector"] --> Version{Host supports<br/>this natively?}
    Version -->|Yes| Disable["Auto-disable OMO hook"]
    Version -->|No| Keep["Keep OMO hook active"]

宿主升级后原生支持某功能,OMO 自动关闭兼容 hook。


特性门控

有些 hook 需要同时满足两个条件:

flowchart TD
    Check1{Hook disabled?} -->|Yes| Off["Not Created"]
    Check1 -->|No| Check2{Needs experimental?}
    Check2 -->|No| Create["Create Hook"]
    Check2 -->|Yes| Check3{Experimental enabled?}
    Check3 -->|Yes| Create
    Check3 -->|No| Off
    Create --> Safe{Creation OK?}
    Safe -->|Yes| Active["Active"]
    Safe -->|No| Null["Graceful Degradation"]

Hook 系统的本质

📁 文件说明:src/config/schema/hooks.ts 41 个 hook name 明确列在 schema 中——它们是公开配置面的一部分,用户可以精确控制每一个。

graph LR
    Agents["Agents provide ROLES"] --> System["OMO System"]
    Tools["Tools provide ACTIONS"] --> System
    Hooks["Hooks provide GOVERNANCE"] --> System

Hook 系统是带执行顺序、降级策略、版本适配和配置开关的策略路由器


本节要点

  • 多路复用:41 个内部 hook 通过少数宿主入口承载
  • 五层结构:Session → Tool-Guard → Transform → Continuation → Skill
  • 顺序 = 优先级:安全防护最先,具体策略最后
  • 优雅降级:一个 hook 失败不拖垮其他 40 个
  • 版本自适应:宿主升级后自动关闭不需要的兼容 hook
  • 可配置到每一个:用户可精确关闭 41 个 hook 中的任何一个