涉及源码 :Python 占位包
src/hooks/、src/plugins/、src/skills/与src/reference_data/subsystems/*.json;Rust 侧rust/crates/plugins(manifest/permission/hooks runner)。
1. "扩展三角"是什么
把可扩展系统拆成三角形,有一个很实用的工程直觉:
- Hooks(钩子):把扩展挂到"生命周期/事件点"上(例如工具调用前/后)。
- Plugins(插件) :把扩展作为一个可安装、可启停、可权限化的分发单元(manifest + registry)。
- Skills(技能):把扩展包装成"可被发现、可被路由/调用的能力块"(面向用户或面向 agent 的可复用能力)。
三者常常都会"能做同样的事",但成熟产品会刻意分工:一层稳定做约束,一层开放做生态,一层面向体验做组合。
2. 先看本仓库的现实:Python 侧多为占位,Rust 侧更像产品骨架
2.1 Python:占位包 = 元数据锚点(对照归档)
Python 的 hooks/、plugins/、skills/ 当前都是统一模板:读取 reference_data/subsystems/*.json,暴露 MODULE_COUNT 与 SAMPLE_FILES,用于 parity 对照与目录地图(见 result/12.md)。例如:
python
# 1:16:src/hooks/__init__.py
\"\"\"Python package placeholder for the archived `hooks` subsystem.\"\"\"
...
MODULE_COUNT = _SNAPSHOT['module_count']
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])
快照显示:
hooks在归档中体量大(module_count: 104),且包含toolPermission/*、通知类 hook 等(说明 hooks 往往是"横切层")。plugins在归档中体量很小(module_count: 2),更像"注册/捆绑索引"。skills中等体量(module_count: 20),多为 bundled skills 与加载目录逻辑。
这正好符合常见产品分工:hooks 多且细、plugins 少而硬、skills 处在体验与可发现层。
2.2 Rust:插件与钩子的"可执行语义"已经长出来
Rust crates/plugins 提供了较完整的插件 manifest、权限与 hooks runner:
PluginManifest:含permissions、hooks、lifecycle、tools、commands。PluginPermission:Read/Write/Execute。PluginToolPermission:read-only / workspace-write / danger-full-access(更贴近工具安全分级)。HookRunner:支持PreToolUse/PostToolUse,能运行外部 shell 命令并用 exit code 表示 allow/deny/warn。
例如 hooks runner:
rust
// 65:93:rust/crates/plugins/src/hooks.rs
pub fn run_pre_tool_use(&self, tool_name: &str, tool_input: &str) -> HookRunResult {
self.run_commands(
HookEvent::PreToolUse,
&self.hooks.pre_tool_use,
tool_name,
tool_input,
None,
false,
)
}
pub fn run_post_tool_use(...)
以及"拒绝语义":exit code 2 → deny(并且立刻停止后续 hook):
rust
// 174:186:rust/crates/plugins/src/hooks.rs
match output.status.code() {
Some(0) => HookCommandOutcome::Allow { message },
Some(2) => HookCommandOutcome::Deny { message },
Some(code) => HookCommandOutcome::Warn { ... },
None => HookCommandOutcome::Warn { ... },
}
这与 Python 文档 result/05.md 里谈的"拒绝要变成一等语义"高度一致:Rust 侧已经把 deny/allow/warn 变成 HookRunner 的稳定接口面。
3. 哪一层该稳定?(建议稳定面)
稳定层的核心是:一旦第三方依赖,就要尽量少破坏。在扩展三角里,建议优先稳定的是:
3.1 Hooks:稳定事件名 + 稳定 payload 形状
原因:hook 是"把系统切开一刀插针"的位置,生态会围绕 event 名与字段写脚本/插件。 \nRust 侧已经把事件名固定为 PreToolUse / PostToolUse,并构造 JSON payload:
hook_event_nametool_nametool_input(解析后的 JSON 或 raw)tool_input_jsontool_output(post)tool_result_is_error
这些字段一旦变动,外部脚本会大量断裂。因此:event 名与字段名应稳定,字段只做 additive 扩展。
3.2 Plugins:稳定 manifest schema + 权限模型
原因:插件分发与安装/启停需要可预测性。Rust 的 PluginManifest 与 permission 枚举就是典型"应稳定"的内容:\n\n- manifest 路径规范(.claw-plugin/plugin.json)\n- defaultEnabled 等开关\n- 权限枚举(以及工具权限分级)
一旦变动,安装器、市场、配置系统都要联动,成本极高。\n\n### 3.3 Skills:稳定"发现协议"和"调用契约",而不是稳定内部实现
skills 作为可发现能力,稳定的重点是:\n\n- skills 如何被索引(bundled/目录扫描/manifest)\n- skills 对外暴露的名称、描述、输入输出约定\n\nskills 内部实现可以更开放、更快迭代(因为它更贴近"内容层/体验层")。
4. 哪一层该开放?(建议开放面)
开放层的核心是:允许第三方创新与快速迭代,同时不破坏稳定层。
4.1 Skills 应该最开放(生态与体验的承载层)
skills 天生适合承载:prompt 模板、工作流脚本、领域知识封装、对工具链的组合调用。 \n只要调用契约稳定,skills 的数量和内容可以高速增长,且不会迫使核心 runtime 频繁发布破坏性版本。
4.2 Plugins 的"内容部分"开放,但"框架部分"稳定
插件里可以开放:\n\n- 自定义工具定义(tool spec + input schema + command)\n- 自定义命令(command spec)\n- hook 命令链(脚本)
但插件框架要稳定:manifest/registry/permissions/安装位置/启停语义。
4.3 Hooks 本身不宜太开放(事件点数量要克制)
hook 点越多越"自由",但也越难维护:\n\n- 每多一个 hook 事件名,都是一个稳定 API 面。\n- hook 点过细会导致行为难以推理("为什么工具没执行?哦是某个 hook deny 了")。
因此 hooks 最佳实践是:事件点少而关键 (如 pre/post tool use、session start/stop),并配合强审计(见 result/06.md)。
5. 三角如何协作(推荐职责边界)
可以把三角的"职责边界"写成一句话:
- Hooks 负责"什么时候/在什么事件点"(稳定)
- Plugins 负责"谁能装、装了能做什么、权限是什么"(稳定+部分开放)
- Skills 负责"怎么把能力组合成可复用体验"(开放)
一个成熟的工具调用链常见流程(抽象):\n\n1. 模型请求 tool_call\n2. Plugin registry 决定该 tool 是否存在/是否启用/权限等级\n3. HookRunner 在 PreToolUse 执行策略脚本 → allow/deny\n4. 真实工具执行\n5. HookRunner PostToolUse 记录或改写输出\n6. 运行史落盘(审计/回放)
claw-code 目前 Python 侧只把占位与审计位摆出来;Rust 侧已经具备 (2)(3) 的大量骨架。\n\n---
6. 与仓库现状的对齐建议(避免"开放把自己玩坏")
结合本仓库现状,比较稳的演进顺序是:\n\n1. 先稳定 hooks/插件的最小公共面 (事件名、payload、manifest、权限枚举)。\n2. 用 skills 承载快速迭代 (bundled skills、目录加载、模板化工作流)。\n3. 把拒绝与审计贯穿 :hook deny、plugin permission deny 都应进入统一的 PermissionDenial / event log(Python 文档已指出持久化缺口)。\n\n如果反过来(先让 hooks 事件点无限增长、先让插件 schema 频繁破坏性变更),就会在生态早期把自己拖进"兼容地狱"。
7. 小结
- 该稳定的:hooks 的事件名与 payload、plugins 的 manifest/registry/权限模型、skills 的发现/调用契约。
- 该开放的:skills 内容与组合方式;plugins 内的具体工具/命令实现;hook 命令脚本(在稳定 payload 上)。
- 该克制的:hook 事件点数量(每个都是长久维护承诺)。