JohnXu22786/hooks-adapter
把 Claude Code、Codex、opencode 配置里声明的 hooks 原样复用到 dsh,执行 shell、webhook、oracle、proxy 四类 handler,零运行时依赖。
这是一个 DeepSeek Harness(DSH)插件。本站汇总其 GitHub README、安装信息、维护状态与公开安全信号。
hooks-adapter
一个面向 DeepSeek Harness(dsh)的 hooks 配置兼容层:读取主流 agent harness 已有的 hooks 配置文件(如 .claude/settings.json 中的 hooks 声明、.codex/hooks.json、opencode.json 的 hooks 段),把它们的生命周期事件映射到 dsh 的扩展点,并执行 shell / webhook / oracle / proxy 四类 handler——让同一份 hooks 配置在不同的 harness 之间原样复用。
- 零运行时依赖(Node ≥ 18,纯 ESM + JSDoc 类型)
- 配置只读不迁移:你已有的 hooks 声明不用改写
- 四类 handler 全支持:命令执行、HTTP 回调、LLM 评估、子代理委派
- 超时控制、失败降级策略、友好的配置校验(
validate子命令) - 三种接入方式:dsh 插件(Cordis
apply)、stdio JSON-lines 协议(任意宿主)、一次性 CLI
hooks-adapter/
├── package.json # dsh bundle 清单(dsh.bundle + exports)
├── cordis.patch.yml # 组合包层:向插件树插入本插件
├── dsh/plugin.js # dsh 入口:Cordis 插件(name + apply(ctx, config))
├── lib/ # 运行时核心(可独立于 dsh 使用)
│ ├── index.js # CLI 入口 + 编程接口导出
│ ├── events.js # 规范事件目录 + 四方言映射表 + matcher 语义
│ ├── discover.js # 配置文件发现(全局/项目/本地)
│ ├── parse.js # 四方言解析器(全部走诊断,不抛错)
│ ├── config.js # 运行时组装:合并、disableAllHooks、默认值
│ ├── contract.js # stdin JSON 契约构造 + 响应解码 + 决策折叠
│ ├── execute.js # 四类 handler 执行器 + 超时 + 进程树清理
│ ├── dispatch.js # 分发管道:matcher 匹配、顺序执行、blockable 约束
│ └── serve.js # stdio JSON-lines 协议服务
├── docs/ # 配置格式、事件映射、契约、接入说明、CLI 指南
├── examples/ # 四方言示例配置 + 本地 mock LLM
└── test/ # node:test 测试(111 项)
它能做什么
在 .claude/settings.json 里声明 hooks(无论你之前为哪个 harness 写的),在 dsh 中它们照常生效:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "guard.sh", "timeout": 10 }
]
}
],
"Stop": [
{ "hooks": [ { "type": "command", "command": "notify-send done" } ] }
]
}
}
配置文件须为严格 JSON(不支持注释);examples/ 下有完整的四方言示例。
PreToolUse→ 工具执行前的拦截点:handler 退出码 2 / JSONdecision: "block"会阻止工具调用(或转为 ask 交人工确认)PostToolUse/PostToolUseFailure→ 工具执行后(互斥触发):拒绝写回为结果反馈、追加上下文UserPromptSubmit/SessionStart/Stop/SubagentStart/SubagentStop/SessionEnd→ 注入上下文、拒绝提示词、强制模型继续Notification/PreCompact→ 手动或经 stdio 协议触发
四类 handler(配置里的 type 字段按各 harness 习惯书写,内部归一):
| 配置 type | 内部 kind | 行为 | 默认超时 |
|---|---|---|---|
command | shell | 起 shell 进程,stdin 喂 JSON 契约 | 600s |
http | webhook | POST JSON 到 URL,响应体即决策 | 600s |
prompt | oracle | 调 LLM 端点评估,{ok:false} 即拒绝 | 30s |
agent / subagent | proxy | 委派给子代理 runner(可配置命令) | 60s |
快速开始
方式一:dsh 插件(推荐)
# 在包含本插件 checkout 的目录中
dsh plugin --profile demo add ./hooks-adapter
dsh --profile demo
加载后插件自动发现项目与用户目录下的 hooks 配置(见下)。也可在 profile 的 cordis.patch.yml 中覆盖配置行:
- replace:
- id: hooks-adapter
config:
configPath: /abs/path/to/hooks.json # 固定使用单一文件(跳过发现)
discover: false
llm: { baseUrl: "https://api.example.com/v1", model: "eval-small" }
proxy: { command: "dsh run --quiet" }
接入细节见 docs/INTEGRATION.md。
在 DSH 中安装
直接用 dsh 插件命令从 GitHub 仓库安装:
dsh plugin --profile demo add github:JohnXu22786/hooks-adapter
本包是 dsh bundle(dsh.bundle.patch → cordis.patch.yml),添加后即插入插件树,下次启动 dsh 时自动发现 hooks 配置。卸载:
dsh plugin --profile demo remove hooks-adapter
方式二:stdio 协议(任意宿主)
echo '{"op":"ping"}' | node lib/index.js listen --config hooks.json
echo '{"op":"dispatch","event":"PreToolUse","payload":{"tool_name":"Bash","tool_input":{}}}' | node lib/index.js listen
协议说明见 docs/CONTRACT.md。
方式三:一次性 CLI
node lib/index.js validate # 检查所有可发现的配置,退出码 0/1
node lib/index.js run --event PreToolUse --payload payload.json
node lib/index.js dump # 打印合并后的生效配置
node lib/index.js list # 列出发现到的配置文件
配置从哪里来
自动发现并按顺序合并(后者追加同名事件的组;disableAllHooks 以最具体的文件为准):
| 顺序 | 文件 | 方言 |
|---|---|---|
| 1 | ~/.claude/settings.json | claude |
| 2 | ~/.codex/hooks.json | codex |
| 3 | ~/.config/opencode/opencode.json | opencode |
| 4 | ~/.config/hooks-adapter/hooks.json | native |
| 5 | <项目>/.claude/settings.json | claude |
| 6 | <项目>/.codex/hooks.json | codex |
| 7 | <项目>/opencode.json | opencode |
| 8 | <项目>/.dsh-hooks.json | native |
| 9 | <项目>/.claude/settings.local.json | claude |
- 环境变量
HOOKS_ADAPTER_CONFIG(等价于--config)与HOOKS_ADAPTER_HOME(等价于--home) - 任意文件缺失都静默跳过;存在的文件若有问题,只产生诊断,不阻止启动
- 配置文件格式细节见 docs/CONFIG.md
事件映射
每种 harness 的事件名映射到一套规范事件(session:start、tool:before……),再绑定到 dsh 的扩展点:
| 规范事件 | claude 方言 | codex 方言 | opencode 方言 | dsh 扩展点 |
|---|---|---|---|---|
session:start | SessionStart | SessionStart | session.created | agent/session-start |
session:end | SessionEnd | SessionEnd | session.deleted | session/disposed |
prompt:submit | UserPromptSubmit | UserPromptSubmit | chat.message | agent/pre-step |
tool:before | PreToolUse | PreToolUse | tool.execute.before | tools/pre-execute |
tool:after | PostToolUse / PostToolUseFailure | PostToolUse | tool.execute.after | tools/post-execute |
turn:stop | Stop | Stop | session.idle | agent/turn-stopping |
subagent:start | SubagentStart | SubagentStart | tool.execute.before.subagent | subagent/start |
subagent:end | SubagentStop | SubagentStop | tool.execute.after.subagent | subagent/end |
notice | Notification | Notification | notification | 手动 / stdio |
compact:before | PreCompact | — | experimental.session.compacting | 手动 / stdio |
完整语义(可阻塞性、matcher 规则、载荷字段)见 docs/EVENTS.md。
契约
- stdin JSON:
session_id、transcript_path、cwd、hook_event_name、permission_mode+ 事件字段(tool_name/tool_input/tool_use_id/tool_response/prompt/source……) - 退出码:
0= 放行(stdout 为 JSON 时解析决策);2= 拒绝(stderr 为原因);其他非零 = 非阻塞错误 - stdout JSON:
decision、continue/stopReason、systemMessage、hookSpecificOutput.permissionDecision(allow/deny/ask)、additionalContext、updatedInput;oracle 应答{ok: true|false, reason} - 多 hook 折叠:
deny > ask > allow;任一continue:false即停;上下文按 hook 顺序累加 - 细节与 stdio 协议见 docs/CONTRACT.md
测试
node --test
(默认测试发现模式即可跑全部 111 项测试;辅助脚本在 test-support/,不会被误当测试。)
许可证
基于 MIT License 发布。
安全与安装证据
该分数只基于公开仓库元数据与本站登记的安装证据,不等同于代码安全审计。
来自公开插件目录,并链接到公开 GitHub 仓库。
仓库声明 MIT 许可证。
最近 180 天内有代码更新。
尚未登记可复验的精确安装元数据,请按仓库说明手动检查。
已检查的包元数据未声明安装生命周期脚本。