DSH Plugins Marketplace

DSH Plugins

Plugins

/

DSHCodingMode

S

DSHCodingMode

Manifest valid

DSH coding mode: coding-only agent preset plus host-plane tool mask for DeepSeek Harness.

hasBundlePatch

@suntion/dsh-coding-mode —「编码模式」DSH 预设

给 DeepSeek Harness Desktop 增加一个只有编码刚需能力的 agent preset(预设 id:coding,界面名:编码模式)。

组成

文件作用
package.jsonbundle 包声明,dsh.bundle.patch 指向下面的 patch
cordis.patch.yml挂载 preset-coding(宣告预设)与 coding-tools-restrict(屏蔽插件)
index.jscoding-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;只有在源码里跑测试或用 dsh CLI 时才需要本机 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 秒)

  1. GUI 新建会话 → 预设选「编码模式」。
  2. 让模型回答「列出你当前可用的工具名」。
  3. 应看不到 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 工具。
  4. 打开会话的「系统 → 初始系统提示词」标签页:不应再出现 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 后,工作流会:

  1. 校验 Release tag 与 package.json 的 version 一致;
  2. 查询 npm registry,确认 @suntion/dsh-coding-mode@X.Y.Z 尚未发布;
  3. 运行测试,用 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

dsh-herdr

by wenhao4126

Expose Herdr workspaces, panes, and coding agents as DeepSeek Harness tools.

Development & InfrastructureManifest valid

★ 0

BSD-3-Clause

TypeScript

Aug 26, 2026

dsh plugin --profile web add @dsh-external/dsh-herdr-toolkit

by leonardoxr

Secure bounded coding tools for DeepSeek Harness

Manifest valid

★ 0

MIT

TypeScript

Aug 24, 2026

dsh plugin --profile web add dsh-coding-tools

by lisycotana

Observability for DeepSeek Harness code-mode sub-dispatches: the tool calls a run_code program makes that the model never sees.

Manifest valid

★ 0

MIT

JavaScript

Aug 14, 2026

dsh plugin --profile web add dsh-code-lens

by jiangr100

DeepSeek Harness plugin: switch a session's agent preset (Standard / Code / Minimal / Creator) mid-conversation, straight from the session header.

Manifest valid

★ 0

MIT

JavaScript

Aug 16, 2026

dsh plugin --profile web add dsh-in-convo-mode-change

by Kevinwu901113

Dots-style always-on agent for DeepSeek Harness (dsh): its own computer, reachable over IM, scheduled work, hard budget limits

Manifest valid

★ 0

MIT

JavaScript

Oct 17, 2026

dsh plugin --profile web add dsh-dot

by KouzakiUmi

DeepSeek Harness 插件:按 Agent preset 限制每个 Agent 可见的工具,保留全局 provider 挂载;基于 agent/created 与 ctx.tools.restrict()。

Manifest valid

★ 0

MIT

JavaScript

Oct 19, 2026

dsh plugin --profile web add dsh-preset-tool-guard