DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

chendefine /

chendefine/dsh-hooks-claude-code-per-workspace

Verified

DeepSeek Harness plugin: run each workspace's own Claude Code command hooks (per-session .claude/settings.json discovery)

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@9b686bb8

dsh-hooks-claude-code-per-workspace

npm license

English | 中文

A DeepSeek Harness (dsh) plugin that runs each workspace's own Claude Code command hooks.

The official @deepseek-ai/dsh-hooks-claude-code bridge reads one process-level configPath once at load (TODO(per-session-hook-config) upstream). This plugin closes that gap for the multi-workspace web surface: at every hook interception point it resolves the current session's own cwd, loads that workspace's .claude/settings.json (plus .claude/settings.local.json, concatenated in order), cached by mtime:size — edit the file and the next hook point picks it up, no reload or restart. When a single dsh web instance has several workspaces open, each workspace's project-level hooks stay independent.

Event → extension-point mapping, stdin payloads, and decision semantics are a faithful port of the official bridge; execution, decoding, and merging come from @deepseek-ai/dsh-hook-protocol.

Install

# from the registry (prebuilt, no build permission needed)
dsh plugin --profile web add dsh-hooks-claude-code-per-workspace
# or equivalently
dshpm install dsh-hooks-claude-code-per-workspace --profile web

# from GitHub (sources; needs the pnpm allowBuilds allowance — see the dsh publish docs)
dsh plugin --profile web add github:chendefine/dsh-hooks-claude-code-per-workspace

You can also install it from the Web GUI's plugin manager. Restart the profile afterwards (bundle membership changes load at boot).

See the 中文文档 below for configuration, the workspace hook format, the trust model, and a comparison with the official 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 <dsh 源码>/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),文件头保留上游署名。

—/ 5

No ratings yet

Verified DSH bundle

Commit 9b686bb86c31

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout