DeepSeek Harness Hub
← 返回列表

工作区级 Hookschendefine/dsh-hooks-claude-code-per-workspace

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

让每个工作区独立加载并运行自己的 Claude Code 命令钩子

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/21 · 已提供中文文档

DeepSeek Harness 插件:运行每个工作区自己的 Claude Code 命令钩子(按会话发现 .claude/settings.json)

综合分
27.3
GitHub 分
27.3
用户评分
★ Stars
0
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add chendefine/dsh-hooks-claude-code-per-workspace
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-llm
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-hooks-claude-code-per-workspace

npm
license

一个 DeepSeek Harness (dsh) 插件,用于运行每个工作区自己的 Claude Code command hooks。

官方的 @deepseek-ai/dsh-hooks-claude-code bridge 在加载时只读取一个进程级的 configPath(上游的 TODO(per-session-hook-config))。本插件为多工作区的 web 界面填补了这一空白:在每一个 hook 拦截点,它解析当前会话自己的 cwd,加载该工作区的 .claude/settings.json(以及 .claude/settings.local.json,按顺序拼接),并按 mtime:size 缓存——编辑文件后,下一个 hook 点即会拾取,无需重载或重启。当单个 dsh web 实例打开了多个工作区时,每个工作区的项目级 hooks 保持独立。

事件 → 扩展点映射、stdin payload 以及决策语义均为官方 bridge 的忠实移植;执行、解码与合并来自 @deepseek-ai/dsh-hook-protocol。

安装

从 registry 安装(预构建,无需构建权限)
dsh plugin --profile web add dsh-hooks-claude-code-per-workspace
或等价写法
dshpm install dsh-hooks-claude-code-per-workspace --profile web

从 GitHub 安装(源码;需要 pnpm allowBuilds 许可——见 dsh 发布文档)
dsh plugin --profile web add github:chendefine/dsh-hooks-claude-code-per-workspace

你也可以从 Web GUI 的插件管理器安装。之后重启该 profile(bundle 成员变化在启动时加载)。

关于配置、工作区 hook 格式、信任模型以及与官方 bridge 的对比,请参见下方的中文文档。

中文文档

每个工作区(session)运行自己的 Claude Code command hooks 的 DeepSeek Harness 插件。

官方 @deepseek-ai/dsh-hooks-claude-code bridge 在进程加载时读取一个 configPath(进程级、读一次,TODO(per-session-hook-config))。本插件补上这一层:在每个 hook 拦截点,取当前 session 自己的 cwd,加载该目录下的 .claude/settings.json(以及 .claude/settings.local.json,两组按序合并),按 mtime:size 缓存 —— 编辑文件后下一个 hook 点即生效,无需重载或重启。

单个 dsh web 实例打开多个工作区时,每个工作区各自的项目级 hooks 互不干扰。事件 → 扩展点映射、stdin payload、决策语义均为官方 bridge 的忠实移植;执行/解码/合并来自 @deepseek-ai/dsh-hook-protocol。

安装

从 npm 安装(预构建产物,无需构建许可)
dsh plugin --profile web add dsh-hooks-claude-code-per-workspace
或等价的 dshpm 用法
dshpm install dsh-hooks-claude-code-per-workspace --profile web

从 GitHub 安装(源码;需在 profile 的 pnpm-workspace.yaml 里 allowBuilds,见 dsh 发布文档)
dsh plugin --profile web add github:chendefine/dsh-hooks-claude-code-per-workspace

也可以在 Web GUI 的插件管理器中直接安装。安装后重启该 profile(bundle 成员变化需要重启加载)。

配置(全部可选)

profile 的 cordis.patch.yml 中按 id patch 该行(插件不导出 schema,config 原样传入,缺省键在插件内兜底):

- id: hooks-claude-code-per-workspace
config:
settingsPaths: ['.claude/settings.json', '.claude/settings.local.json']
defaultTimeoutMs: 600000        # hook 未写 timeout 时的默认超时(ms)
stderrSummaryMaxChars: 500      # hook/result 事件里 stderr 摘要的长度上限
allowDirs: []                   # 目录前缀白名单;空 = 所有工作区都允许

- settingsPaths:相对每个工作区 cwd 解析(绝对路径原样使用);多个文件的 hook 组按序拼接 —— 与 Claude Code 项目级两份文件的行为对齐。也可指向 .claude/hooks.json(裸事件映射格式同样接受)。
- allowDirs:非空时,只有 cwd 等于或位于这些目录之下的 session 才加载 hooks;其余静默跳过。

工作区里怎么写 hooks

与 Claude Code 完全同格式(.claude/settings.json 的 hooks 键,其余键被忽略):

{
"hooks": {
"PreToolUse": [
{ "matcher": "bash", "hooks": [{ "type": "command", "command": "./scripts/guard.sh" }] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "notify-done.sh", "timeout": 10 }] }
]
}
}

- hook 命令在该工作区目录里执行;CLAUDE_PROJECT_DIR 指向它;命令串里的 ${CLAUDE_PROJECT_DIR} 会被替换。
- 支持 7 个事件:SessionStart、UserPromptSubmit、PreToolUse、PostToolUse、Stop、SubagentStart、SubagentStop。其余 CC 事件的配置被忽略;仅 type: "command" 执行(http/mcp_tool/prompt/agent 跳过并告警)。
- 输出契约与 CC 一致:exit 2 = 阻断(stderr 为原因);exit 0 + stdout JSON 的 hookSpecificOutput.permissionDecision(deny/ask)与 additionalContext 生效。
- 每次 hook 运行写入 hook/invoked / hook/result 会话事件(dialect 标记 claude-code),可在会话日志中审计。

事件 → 扩展点映射

| CC hook | Harness 扩展点 | 语义 |
|---|---|---|
| SessionStart | agent/session-start | additionalContext → 注入新会话(不可阻断) |
| UserPromptSubmit | agent/pre-step | deny → 拒绝本轮;additionalContext → 追加到下游 enter 决策 |
| PreToolUse | tools/pre-execute | deny → 拒绝工具;ask → 转人工确认 |
| PostToolUse | tools/post-execute | deny → block 并回传原因;additionalContext → 附加到下游决策 |
| Stop | agent/turn-stopping | 阻断 → steer() 原因,强制再走一步 |
| SubagentStart | subagent/start | additionalContext → 注入子代理 |
| SubagentStop | subagent/end | 仅观察 |

容错

- 工作区没有 settings 文件 → 零 hook(正常,静默)。
- JSON 损坏 / matcher 非法 regex → 该文件告警一次并被忽略,绝不拖垮会话。
- hook 执行失败(无法 spawn 等)→ 非阻断错误,轮次继续。

与官方 bridge 的差异

| | 官方 dsh-hooks-claude-code | 本插件 |
|---|---|---|
| 配置来源 | 单个 configPath,加载时读一次,进程级 | 每个工作区 cwd 下的 settings 文件,逐点解析 |
| 生效范围 | 整个进程所有 session | 仅该工作区的 session |
| 配置热更新 | 无 | 改文件即生效(mtime+size 缓存) |
| configPath/pluginRoot/projectDir 配置 | 有 | 无(pluginRoot 不替换;projectDir 恒为工作区 cwd) |
| 限制(事件子集、字段缺口、Stop 无限续步、updatedInput 不生效) | — | 完全相同,见官方 bridge README |

信任模型(必读)

打开一个工作区 = 允许该工作区 settings.json 里声明的任意 shell 命令在 hook 点执行。默认放行所有工作区,每个工作区首次激活会打一条 info 日志(含 hook 数量)。如需收紧,用 allowDirs 白名单。

开发

node test/smoke.mjs    # 35 项断言的离线冒烟测试(伪造 ctx/shell/session)

- vendor/ 是 @deepseek-ai/dsh-hook-protocol(MIT)逐文件移植:发布版 npm 包不在 harness 安装闭包内,无法作为依赖装进 profile,故内联保持自包含。唯一外部运行时依赖是 @deepseek-ai/dsh-llm(peerDependency,由 $DSH_HOME/profiles/node_modules 平铺兜底解析);本地跑测试可 ln -s /packages/llm/llm node_modules/@deepseek-ai/dsh-llm。
- 真实环境 E2E(已在开发中验证):一次性 DSH_HOME + headless profile,工作区放 exit-2 的 UserPromptSubmit hook → 会话日志出现 hook/invoked/hook/result(decision=block, exitCode=2),turn 以 blocked 结束;无配置目录的对照会话零 hook 触发。

卸载

dshpm remove dsh-hooks-claude-code-per-workspace --profile web
或
dsh plugin --profile web remove dsh-hooks-claude-code-per-workspace

许可

MIT — 见 LICENSE。vendor/ 内联自 @deepseek-ai/dsh-hook-protocol(MIT,DeepSeek Harness),文件头保留上游署名。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群