用 dsh-workbench 给 DeepSeek Harness 网页界面加上 VS Code 风格三栏工作台

前言

DeepSeek Harness(dsh)的核心理念是「一切皆插件」:模型、工具、会话、沙箱和 Web UI 都可以在配置层替换或重组。官方仓库把这件事写得很清楚,开发者预览版也已经把源码公开。实际用 npx @deepseek-ai/dsh web 打开网页界面时,中间一列通常还是会话:智能体在沙箱里改文件,人要核对内容,往往得另开编辑器,或者来回切换标签。

社区插件 dsh-workbench 做的就是这块界面:给 Web GUI 加上接近 VS Code 的三栏布局——左侧边栏保持原样,中间在「会话」和「文件内容」之间切换,右侧常驻 Explorer 文件树。点开文件后,中间列变成 Monaco 编辑器;打开 Markdown 还可以切到渲染预览。它由 Dpf555 维护,MIT 许可证,仓库地址是 Dpf555/dsh-workbench。社区目录目前把它归在「记忆」分类,GitHub 星标 6;从 README 和 package.json 看,它解决的是工作台布局,不是跨会话记忆。

需要先说明一点:社区插件目录(deepseek-harness-plugin.com)是独立站点,和 DeepSeek / 幻方没有官方从属关系,不能当成官方应用商店。下文按目录详情页、GitHub README、package.json 与源码交叉核对后整理。

这是什么

dsh-workbench 是面向 DeepSeek Harness Web GUI 的 Cordis 插件,npm 包名是 @dsh-local/dsh-workbench,当前 package.json 版本为 0.2.0dsh.client.platform 声明为 web。维护者是 Dpf555,许可证为 MIT。

它要解决的问题很具体:默认客户端壳没有「常驻右栏 + 点击文件切换中间视图」的公开扩展点。这个插件自己补上 Explorer 槽位,再用 Monaco(VS Code 的编辑器核心,仓库固定为 monaco-editor 0.52.2)把中间列变成可编辑的代码视图。

布局可以按 README 里的示意来理解:

┌─────────┬──────────────────────────┬────────────┐
│ 左侧边栏 │  中间:会话 ⇄ 文件内容     │ 右侧:文件树 │
│ (不变) │  点文件 → Monaco 编辑器    │ Explorer   │
└─────────┴──────────────────────────┴────────────┘

主机半部在 index.js 里注册 /wb/* 静态资源,以及 /wb/api/ 下的文件操作;浏览器半部由 client.js 加载 /wb/workbench-client.js。文件读写走 DSH 的 ctx.fs,并按当前会话的工作区做围栏。

核心功能

右侧 Explorer

右栏是常驻文件树,设计参考 microsoft/vscode,图标用的是 VS Code 官方 seti 字体。仓库已经提交了 assets/seti.cssseti-map.jsonseti.woff

README 列出的能力包括:

  • 展开 / 折叠目录
  • 新建文件、新建文件夹
  • 刷新、全部折叠
  • 面板可拖宽;宽度范围在补丁说明里是 240–420px,默认 300px
  • « 收起;收起后右侧留 28px 窄条,点击即可重新展开

文件树的根不是整个磁盘,而是当前活跃会话的工作区,对应会话的 header.cwd,也就是该会话自己的沙箱边界。切换会话时,右栏和编辑器标签页会跟着重建。没有活跃会话时,回退到 sandboxPolicy 的部署根,这个根可以在 profile 的 cordis.patch.yml 里固定。

中间列:Monaco 编辑器

点击文件后,中间列从会话视图切到代码编辑器。编辑器是 monaco-editor 0.52.2,README 写明它提供:

  • 多标签页
  • 语法高亮
  • minimap
  • Ctrl+S 保存
  • 未保存的脏标记
  • 保存冲突时的「重新加载 / 强制覆盖」(写入用版本号 CAS,避免互相覆盖)

编辑时,下方输入框和停靠条会自动隐藏,编辑器占满整列。切回会话可以用顶部的「对话 / 代码」标签,或「返回会话」按钮。

index.js 把单文件读取上限设为 5MB;二进制文件按 FS_NOT_TEXT 拒绝,不会当文本打开。

Markdown 预览

打开 .md 文件后,标签行会出现「预览」按钮,一键切到渲染视图,并随编辑实时刷新。渲染器是插件自带的,不额外拉依赖。

README 写明它覆盖 GFM 的一个子集:标题、粗斜体、行内代码与围栏代码、列表与任务清单、引用、表格、链接、图片、分隔线。暂不支持嵌套列表、脚注,以及 HTML 透传——HTML 一律转义,避免注入。

安全边界

文件操作都经过 DSH 的 ctx.fs。主机半部会再做一次路径围栏:先解析工作区根,再 fs.contains 检查目标是否落在根内,越界返回 outside-workspace。写入带版本号,遇到 FS_STALE_VERSION 时按冲突处理,而不是直接覆盖。

客户端会把当前活跃会话 id 带到每个 /wb/api/* 请求里,服务端用 sandboxPolicy.resolve({ session }) 决定栅栏根。index.js 暴露的操作为:describelistDirreadFilewriteFilecreateFilecreateDirassetText

安装与启用

目录详情页给出的安装命令如下,在 DeepSeek Harness 终端里运行即可:

dsh plugin add github:Dpf555/dsh-workbench

如需可复现安装,按目录页的写法固定 commit 哈希。仓库 main 分支截至 2026-08-15 的最新提交是 16f20acf544abcefa9e40b6159fd1b9badd425a6

dsh plugin add github:Dpf555/dsh-workbench#16f20acf544abcefa9e40b6159fd1b9badd425a6

只跑这一条,通常还不够用出 README 描述的完整三栏界面,原因有两条。

第一,Monaco 发行版不入库。assets/vs/ 要靠 npm run setup:assets 下载,大约 13MB;scripts/install-profile.mjs 会检查 assets/vs/loader.js,没有就直接退出。仓库里现成的是 UI bundle 和 seti 图标,没有编辑器核心文件。

第二,三栏布局依赖对 DSH 检出的三处补丁。README 写明:不打补丁时,往往只有浮窗、没有右栏。补丁基于 DSH 0.1.0-rc.6 生成,直接改检出里的客户端 bundle;DSH 按请求读取这些文件,并且带 cache-control: no-cache,硬刷新即可生效,不用再构建。

README 给出的完整步骤如下。前置条件是 Node.js ≥ 18、git,以及能访问 npm registry 的网络:

git clone https://github.com/Dpf555/dsh-workbench.git dsh-workbench
cd dsh-workbench

# 1. 下载 monaco 资产并生成 seti 图标(约 13MB)
npm run setup:assets

# 2. 安装到 DSH profile(下次 `dsh web` 重启后加载 /wb 路由与客户端引导)
node scripts/install-profile.mjs --profile web

# 3. 给当前 DSH 检出打三栏布局补丁
node scripts/apply-patches.mjs --checkout <checkout-root>
# 不传 --checkout 时,脚本会尝试探测 ~/.npm-cache/_npx 下的检出

然后重启 dsh web,并在浏览器里 Ctrl+F5 硬刷新。

检出根目录指包含 node_modules/@deepseek-ai/ 的那一层。用 npx 安装时,常见位置在 ~/.npm-cache/_npx/ 下面。install-profile.mjs 默认把包装进 ~/.dsh/profiles/web/node_modules/@dsh-local/dsh-workbench/(可用环境变量 DSH_HOME 改根目录),并在该 profile 的 cordis.patch.yml 里追加 workbench 这一行。

三处补丁各自做一件事:

  1. ui-layout.patch:AppFrame 增加第 4 条网格轨道 explorer,加上 slot、拖宽手柄和 toggleExplorer
  2. ui-conversation.patch:暴露 window.__DSH_CONV_BRIDGE__[sessionId].setView,点击文件才能切中间视图
  3. ui-sidebar.patch:页面加载时挂上 UI bundle,刷新后也能自愈

DSH 升级之后,如果补丁打不上,需要对照新的 bundle 重新生成,README 建议用 git diff --no-index 对比原始文件和补丁后的文件。

使用方法

按 README 的操作顺序:

  1. 硬刷新页面,右栏应出现文件树。
  2. 点目录展开,点文件后,中间列切到 Monaco,输入框隐藏。
  3. Ctrl+S 保存。顶部「对话 / 代码」标签或「返回会话」按钮可以切回去。
  4. 右栏头部可以新建文件或文件夹、刷新、全部折叠、收起面板;左边缘拖动改宽度。

改完 index.jsclient.js 之后,需要重新启动 dsh web 再硬刷新。会话级工作区解析依赖主机半部注入 sessions 服务,只刷新前端不够。

卸载也按 README:

  1. 删掉 <DSH_HOME>/profiles/web/cordis.patch.yml- insert:workbench 行,重启 dsh web
  2. 删除 <DSH_HOME>/profiles/web/node_modules/@dsh-local/dsh-workbench/
  3. 补丁回退:重装对应 npm 包(npm i @deepseek-ai/dsh-client-ui-{layout,conversation,sidebar}@0.1.0-rc.6 后覆盖检出的 lib/client.js),或 git apply -R patches/*.patch

适用场景与注意事项

适合已经在用 dsh web、希望在同一页里浏览和修改当前会话工作区文件的人。它不是终端 TUI,也不是给 Agent 用的记忆存储。GitHub 上还有同名或近名的仓库(例如其他维护者的 workbench / explorer 插件),安装时认准 Dpf555/dsh-workbench 和目录页上的这条命令。

使用前把这几条限制看清楚:

  • ctx.fs 目前没有 rename / delete 契约,所以暂不支持重命名和删除文件
  • 二进制文件不能当文本读;单文件读取上限 5MB。
  • 没有打开会话时,右栏仍可能可见,但点击文件不会切换中间视图(视图环是会话级的),文件树此时显示部署根。
  • Markdown 预览只覆盖上面列出的 GFM 子集。
  • 补丁针对 0.1.0-rc.6。DSH 还在开发者预览阶段,客户端 bundle 一变,补丁就可能失效。

插件以当前 dsh 进程的权限运行,安装时可能执行代码。目录页也写了同样的警告:安装前检查源代码仓库和许可证;需要可复现安装时,固定 commit 哈希。社区目录不是官方应用商店,不要只凭分类名称或星标决定是否安装。

小结

dsh-workbench 把 DeepSeek Harness 的网页会话界面,补成「左边栏不变、中间会话与编辑器切换、右边文件树常驻」的工作台。编辑器用的是 Monaco 0.52.2,Markdown 可以预览,文件操作限制在当前会话工作区里。要让三栏真正出现,除了目录页上的 dsh plugin add,还需要按 README 下载 Monaco 资源,并对 DSH 检出打那三处补丁。

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-workbench/

GitHub:https://github.com/Dpf555/dsh-workbench

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜