DSHCodingMode
Manifest validDSH coding mode: coding-only agent preset plus host-plane tool mask for DeepSeek Harness.
@suntion/dsh-coding-mode —「编码模式」DSH 预设
给 DeepSeek Harness Desktop 增加一个只有编码刚需能力的 agent preset(预设 id:coding,界面名:编码模式)。
组成
| 文件 | 作用 |
|---|---|
package.json | bundle 包声明,dsh.bundle.patch 指向下面的 patch |
cordis.patch.yml | 挂载 preset-coding(宣告预设)与 coding-tools-restrict(屏蔽插件) |
index.js | coding-tools-restrict:在本预设作用域内屏蔽非编码工具(组装期过滤 + 注册表 restrict) |
预设本体是 @deepseek-ai/dsh-agent-preset 的一个实例,其 config.plugins 复刻 standard 预设的名单,去掉了与编码无关的行。
保留的能力
- 人格/指令/时间上下文:
persona、agent-instructions、time-context - 执行与文件:
tool-bash(非 Windows)、tool-pwsh(Windows)、tool-fs、tool-fs-search - 后台作业:
tool-jobs - 技能:
skill-filesystem、tool-skill - 计划模式:
planning组(plan-mode,含计划章节) - 压缩/委派/上下文:
compaction组(bili 插件)、delegation组(subagent 系) - 交互与交付:
tool-ask-user、tool-todo、tool-web、present
移除的能力
- 定时任务:
tool-schedule(不再挂载) - 目标编排:
command-goal、tool-goal(只用于单个编码任务) - 工作流:
workflow-ptc、tool-workflow - 插件面板:
tool-plugin-manager、tool-plugin-market(避免在编码会话里改宿主插件)
为什么还要一个屏蔽插件
browser_*、dsh_browser_*、create_skill、terminal_*、create_worktree、plugin_manager、cordis_inspect_*、load_workspace_dependencies 这些工具由预设法管不到的作用域注册(profile bundle:bridge-browser、skills-manager、实验性 terminal / worktree bundle,以及 web-app 的宿主行),预设法没法按会话摘掉它们。因此 index.js 用两条互补的路子:
第一路(主力):system-prompt/assemble 瀑布流。 运行时把 { sections, contexts, tools, variables } 组装完毕、跑完瀑布流之后,以瀑布流的返回值作为发给模型的内容(@deepseek-ai/dsh-system-prompt 的 assemble())。所以在这里按名字过滤 assembly.tools 与 assembly.sections,就是对模型隐藏工具的最终手段——无论该工具由哪个作用域注册:
scope.on('system-prompt/assemble', async (assembly, _context, next) => {
const result = (await next()) ?? assembly // 先跑完整条链,后面的监听器无法再加回来
return filterAssembly(result) // 只剔除名单内的 tool / section
})
第二路(注册表层):tools.restrict()。 官方文档里「对某个 agent 隐藏工具」的正式手段(只减不增,schema、查找、执行三者保持一致),可同时让工具从 agent 的 schema 视图(含 GUI 工具列表)里消失:
scope.tools.restrict({ deny: ['browser_navigate'] })
它只对本作用域能看到的注册层里的工具生效:命中别处注册的名字会让 restrict 抛错。所以这里一个名字一次调用、逐个 try/catch——被拒绝的名字不会连累其余名字(早期版本一次传整个数组,只要有一个名字不合法就整批失效,这正是上次回归的根因)。插件工具是逐条注册的,所以还有一个 tools/change 监听器做补拦;因为限制本身也会改变工具集合,这一路带重入保护 + 100ms 去抖(曾经因为没有保护而递归到 Maximum call stack size exceeded),只让当前这一遍跑完、再补一遍。
两条路都在预设根 ctx(自身即 agent 作用域)与每个新 agent 的 ctx 上各执行一遍,效果叠加;都挂在 effect 作用域上,插件卸载时自动恢复。
被屏蔽名单(66 项,见 NON_CODING_TOOLS):browser_*(15 个,bridge-browser 的旧名字)、dsh_browser_*(34 个,dsh-builtin-browser 的 tool-browser 行注册的全部工具)、bsk_*(6 个,BrowserSkill)、cordis_inspect_list、cordis_inspect_query、create_skill、load_workspace_dependencies、plugin_manager、terminal_*(6 个)。
刻意保留:create_worktree(@deepseek-ai/dsh-experimental-tool-worktree)。它和本插件要屏蔽的工具一样是「宿主层注册、预设法管不到」,但它让多个 agent 并行开发,属于编码刚需。该 bundle 另提供 worktrees 服务,且不往系统提示词里插段落,所以两个名单都没有它。
提示词段落名单(NON_CODING_PROMPT_SECTIONS):tool:bridge-browser(浏览器桥段落)、tool:browser(dsh-builtin-browser 的 dsh_browser_* 指引段落)、tool:pty、tool:terminal(持久终端 bundle 的段落,按名字预置)。今后再有插件塞入非编码段落,把它的 section 名加进来即可。
调整名单:coding-mode.policy.json(不用改代码、不用重启)
在本目录放一个可选的 coding-mode.policy.json,插件每秒检查一次 mtime,改动即时生效:
{
"keepTools": ["terminal_open", "terminal_list", "terminal_read", "terminal_send", "terminal_signal", "terminal_close"],
"keepSections": [],
"denyTools": ["..."],
"denySections": ["..."]
}
keepTools/keepSections:从默认名单里减去。离开名单的名字会被主动解除注册层限制,工具重新可用(不只是重新出现在提示词里)。denyTools/denySections:整体替换默认名单(省略即用内置名单)。- 文件解析失败或字段类型不对时绝不半生效:继续用上一份可用名单,并在诊断日志里记一行。
- 删掉该文件即回到内置名单。
诊断:插件会往系统临时目录写 %TEMP%\dsh-coding-mode-diag.log,只在观测内容变化时记一行——restrict ok=[...] refused=[...] released=[...] 与 assemble tools=[...] sections=[...](后者是过滤后真正发给模型的工具与段落名)。想确认某次会话里屏蔽是否真的生效,看这个文件最快;不需要时可删掉 index.js 里的 diag() 调用。
环境要求
- DeepSeek Harness 0.2.x。
- Node.js
^22.19 || >=24,见package.json的engines.node;CI 在 22 / 24 上跑测试。桌面端插件实际运行在 DSH 内置的 Electron/Node 上,无需另装 Node;只有在源码里跑测试或用dshCLI 时才需要本机 Node。 engines只是元数据:npm 默认只在不匹配时给出EBADENGINE警告,不会阻止安装;要硬拦截需在消费侧开启engine-strict。
自测
node selftest.mjs # 在本目录运行
7 项检查:默认名单的组装过滤(含 MCP 工具、未知工具、create_worktree 保留)、插件导出契约、整表屏蔽、tools/change 自触发不再递归、迟注册工具被补拦、keepTools 释放、坏 policy 文件保持上一份名单。自测会把 index.js 复制到临时目录再 import,不影响正在运行的会话。
安装与启用
dsh plugin --profile desktop add link:<本目录的绝对路径>
然后在 $DSH_HOME/profiles/desktop/package.json(DSH_HOME 默认是 ~/.dsh)的 dsh.profile.bundles 末尾确认有 @suntion/dsh-coding-mode(dsh plugin add 会自动追加),重启 DSH 生效。
也可以在 GUI 里用 plugin_manager install_bundle,target 填本目录的绝对路径。以 link/junction 方式安装后,pnpm 会把它记为 link:<本目录的绝对路径>,Node 也能经 junction 解析 @suntion/dsh-coding-mode;已安装时无需重装。
改 cordis.patch.yml / package.json 时加载器会即时重算,无需干预;但改 index.js 后必须重启 Desktop,否则进程里留着的还是旧 ESM 模块。实测对该 bundle 执行「禁用 → 启用」无效:plugin_manager 返回 application: restart-required,禁用和启用都只是改写 dsh.profile.bundles、等下次启动才落地。所以名单类微调请走 coding-mode.policy.json(见上),只有改代码才需要重启。
启用方式:GUI 新建会话时选择预设 编码模式;已存在的会话仍用旧预设。
验证要点
plugin_manager list_bundles中应出现@suntion/dsh-coding-mode,行preset-coding→@deepseek-ai/dsh-agent-preset。plugin_manager list_plugins中include:preset-coding应为enabled: true、patchId: preset-coding,且无诊断信息。- 预设内嵌的插件行(含
coding-tools-restrict)不会出现在list_plugins中,这是正常现象。
端到端自检(30 秒)
- GUI 新建会话 → 预设选「编码模式」。
- 让模型回答「列出你当前可用的工具名」。
- 应看不到
browser_*、dsh_browser_*、schedule_*、create_goal/update_goal、plugin_manager、create_skill、terminal_*、load_workspace_dependencies、workflow、cordis_inspect_*;应能看到read/write/edit/glob/grep/pwsh、create_worktree、job_*、todo_write、exit_plan_mode、subagent*、skill、acp_*/compress、present、以及任意 MCP 工具。 - 打开会话的「系统 → 初始系统提示词」标签页:不应再出现
A browser bridge may be connected. ... browser_snapshot ...,也不应出现Use the dsh_browser_* tools to operate the built-in browser.这一段;其余段落应与普通模式一致。
注意事项
- 本预设的 compaction 组带
inject: [biliBasicCompactionPolicy],用于让 billion-context 的压缩策略覆盖到本预设(insert 行的inject会替换而非追加)。 - 按仓库实践,profile 的
package.json不要手改,安装一律走plugin_manager或dsh plugin add。
发布
发布由 .github/workflows/release.yml 处理。发布 vX.Y.Z 格式的 GitHub Release 后,工作流会:
- 校验 Release tag 与
package.json的version一致; - 查询 npm registry,确认
@suntion/dsh-coding-mode@X.Y.Z尚未发布; - 运行测试,用
pnpm pack生成 tarball,再用npm publish发布到 npm(pnpm与npm共用同一个 registry,不需要分别发布)。
发布到 npm 后工作流即结束,不再轮询 registry 做二次确认:npm publish 返回 0 就代表 tarball 已被接收,而 npm 会对新版本做自动审核,审核完成前 registry 一直对该版本返回 404(npm 网站上状态显示为「验证」,实测需要几分钟)。想看结果直接打开 https://www.npmjs.com/package/@suntion/dsh-coding-mode。
首次使用前,在仓库 Settings → Secrets and variables → Actions 中添加 NPM_TOKEN,token 需要拥有该包的发布权限。工作流也支持手动触发:填写已有的 Release tag 即可重试。
Comments
Loading…
Similar plugins
by wenhao4126
Expose Herdr workspaces, panes, and coding agents as DeepSeek Harness tools.
★ 0
BSD-3-Clause
TypeScript
Aug 26, 2026
dsh plugin --profile web add @dsh-external/dsh-herdr-toolkitby leonardoxr
Secure bounded coding tools for DeepSeek Harness
★ 0
MIT
TypeScript
Aug 24, 2026
dsh plugin --profile web add dsh-coding-toolsby lisycotana
Observability for DeepSeek Harness code-mode sub-dispatches: the tool calls a run_code program makes that the model never sees.
★ 0
MIT
JavaScript
Aug 14, 2026
dsh plugin --profile web add dsh-code-lensby jiangr100
DeepSeek Harness plugin: switch a session's agent preset (Standard / Code / Minimal / Creator) mid-conversation, straight from the session header.
★ 0
MIT
JavaScript
Aug 16, 2026
dsh plugin --profile web add dsh-in-convo-mode-changeby Kevinwu901113
Dots-style always-on agent for DeepSeek Harness (dsh): its own computer, reachable over IM, scheduled work, hard budget limits
★ 0
MIT
JavaScript
Oct 17, 2026
dsh plugin --profile web add dsh-dotby KouzakiUmi
DeepSeek Harness 插件:按 Agent preset 限制每个 Agent 可见的工具,保留全局 provider 挂载;基于 agent/created 与 ctx.tools.restrict()。
★ 0
MIT
JavaScript
Oct 19, 2026
dsh plugin --profile web add dsh-preset-tool-guard