工作台开发规范

版本:2026-10-08 · 以官网版本为准,DSH Desktop 内附文档副本供离线取用。

官方地址:https://dshdesktop.com/workbench/docs/development/

Markdown 原文(供 Agent 读取):https://dshdesktop.com/workbench/docs/development.md

六步速览:https://dshdesktop.com/workbench/docs/quickstart/ (Markdown 原文)。

本文是开发工作台时由 AI 直接执行的规范。只在本地开发、自己使用时,满足本文即可:按第 3 节写好包,装到本机 DSH Desktop,按第 8 节自测通过,就可以正常使用,不需要公开代码,也不需要上传到任何地方。

如果之后想把工作台上架到工作台市场,再阅读《工作台市场验收规范》:https://dshdesktop.com/workbench/docs/market-acceptance/ 。仓库公开、发布、简介、截图和收录 PR 的要求都在那一份里,本文不涉及。

工作台是一种 DSH 插件。它首先必须是一个合格的 DSH 插件包,能被 dsh plugin add 安装、被 Harness 加载;在此基础上,再向 Desktop 注册业务面板,并遵守工作台与会话、工作区的交互规则。

规则分三级:必须(不满足就不能安装或加载)、建议(强烈推荐,不满足会影响体验或以后上架)、可选。

1. 执行原则

需求确认闸门(先于写代码):先确认用户要开发的工作台的业务场景、目标用户和最小核心流程。复制 Desktop 的通用“开发指令”、打开了某个目录、目录里已有项目或依赖,均不能替代用户对本次开发目标的说明;不要仅凭目录名或现有代码替用户选定产品方向。若本次请求和用户已确认的上下文仍不足以明确这三项,用一个合并问题询问,例如:“这个工作台要服务谁、解决什么业务场景?用户从进入到完成任务的核心步骤是什么?”等待用户答复,停在需求确认阶段;此前可以只读检查目录、版本、脚本和宿主能力,不得创建或修改业务代码、界面,不得运行构建、打包、安装或提交投稿。空目录不能被当作已确认需求;代理收到通用开发指令后直接开工属于执行失误。

需求明确后,从项目读取名称、作者、版本、说明和测试命令,只询问无法查明且会影响实现的必要信息。开发请求本身不代表授权公开代码、商业数据或凭证。

开发前必须检查:

一页执行流程

  1. 确认需求:从用户本次请求及已确认的上下文记录业务场景、目标用户、用户完成一次任务的核心流程。通用开发指令或项目目录本身不算确认;三项不明确时执行上述闸门,等待答复。
  2. 检查项目:确定项目根目录,运行 pwd、git status --short(若是 Git 仓库),查看已有代码、包管理器、未提交改动和目标 Desktop 版本;保留无关改动。
  3. 确定最小业务流程与布局:写下入口、主要动作、完成状态及失败恢复;按第 4 节明确选择标准分栏或 customFrame、首次无会话时的入口,再决定所需宿主能力。
  4. 实现:按第 3 节建立插件包和注册;第 4–7 节按责任及实际使用的能力落实。
  5. 包校验:运行 pnpm pack,检查 tarball 内 package.json、声明的入口和 cordis.patch.yml,检查大小和敏感文件。
  6. 本机安装实测:按 3.6 探测当前 Desktop 的安装能力、安装该 tarball、完成所需重启,并按第 8 节记录真实 UI 与加载证据。在目标 DSH Desktop 内开发时,按下方“同机重启边界”交给用户手动重启。

同机重启边界:如果 Agent 正运行在需要重启的这台 DSH Desktop 会话内,安装后不要自行关闭、重启 DSH Desktop 或 Harness,也不要用 ps、pgrep 等进程探测来尝试管理这次重启。告知用户完整退出并重新打开 DSH Desktop;在用户回来确认已重开后,才继续检查插件加载、已安装列表、左侧入口和真实界面。此前将这些重启后的验收项标为待验证,不能宣称已通过。运行在目标应用之外的开发 Agent 可按正常重启流程操作。

空目录演练:若目录为空、用户只粘贴 Desktop 的“开发指令”或只说“做个工作台”,此时第 1 步尚未通过。Agent 应先提出合并问题:“这个工作台要服务谁、解决什么业务场景?用户从进入到完成任务的核心步骤是什么?”可以运行 pwd、查看目录及 Desktop 能力;在用户答复前,流程停在第 1 步,不创建 package.json、组件或业务页面,也不构建、安装或投稿。

2. 工作台是什么

一个工作台包同时是:

同一个工作台有三个标识,职责不同,不能混用:

标识在哪里用途
npm 包名package.json 的 name安装、依赖解析、cordis.patch.yml 的 name:
插件条目 idcordis.patch.yml 中 insert 行的 idHarness 插件树中定位这一行
工作台身份规范的 GitHub repository URL、市场条目 id小写 owner/repository;市场卡片、侧栏入口和会话归属共用
兼容用旧 ID老包 register({ id })、旧目录 workbenchId仅迁移旧数据时使用;新包和新投稿都不填写

Desktop 将 GitHub owner 和 repo 规范化为小写,例如 https://github.com/Owner/Repo 对应 owner/repo。仓库改名或转移会改变工作台身份,需按迁移规则处理原有会话,不能仅改 URL。旧版 wb-owner-repo 只作为兼容映射,不是新包的注册 ID。

3. 包格式

3.1 目录结构

一个包只放一个工作台。典型结构:

package.json          # npm 与 DSH 插件声明
cordis.patch.yml      # 把服务端入口插入插件树
dsh/index.js          # 服务端入口(exports["."])
lib/client.js         # 已构建的客户端入口(exports["./client"])
README.md  LICENSE

3.2 package.json

字段级别要求
name、version必须普通 npm 字段,version 为完整 SemVer(如 1.2.0)
"type": "module"建议所有官方示例都使用 ES 模块
main 与 exports["."]必须指向服务端入口,cordis.patch.yml 导入的就是它
dsh.bundle.patch必须例如 "dsh": { "bundle": { "patch": "./cordis.patch.yml" } },路径相对包根目录。没有它,包只会被当作普通依赖安装,不会激活任何插件层
dsh.client.platform必须固定为 "web",否则客户端模块不会被加载
dsh.client.inject必须字符串数组,必须包含 dsh-desktop-workbenches,保证工作台服务先于你的客户端加载;用到其他客户端包时一并列出。这里只决定加载顺序,不是 Cordis 服务注入
exports["./client"]必须声明了 dsh.client 就必须导出已构建的客户端文件,否则启动时报错
dsh.client.external可选客户端需要 require 共享基线以外的模块(包括子路径)时列出;不能列自己
exports["./package.json"]、exports["./cordis.patch.yml"]建议与官方包保持一致
files建议必须把 cordis.patch.yml、服务端入口和构建产物包含进去
peerDependencies建议官方 @deepseek-ai/* 包(如 @deepseek-ai/cordis、@deepseek-ai/dsh-client-connection)写在 peerDependencies,不要写在 dependencies,避免装进第二份宿主代码。版本范围要显式包含预发布分支,例如 ">=0.1.5-rc.2 <0.2.0-0",否则预发布版的 Harness 会被排除,安装时报 ERESOLVE
@deepseek-ai/schemastery建议服务端 Config 使用它定义;它是运行时依赖
license、author、description建议真实填写

不要依赖未文档化的 dsh 字段(例如 dsh.client.inline),它们会被静默忽略。

3.3 cordis.patch.yml

文件是一个 YAML 数组。工作台通常只需要一条 insert:

- insert:
    - id: my-workbench            # 插件条目 id
      name: my-workbench-package  # 必须写 npm 包名,Node 才能解析到安装的代码
      config:
        root: !!js dshHomePath('my-workbench')   # 可选:业务数据目录

3.4 服务端入口

import Schema from '@deepseek-ai/schemastery'

export const name = 'my-workbench'
export const inject = ['connection']
export const Config = Schema.object({ root: Schema.string().required() })

export function apply(ctx, config) {
  // 注册本工作台自己的本机接口,例如 /api/my-workbench/...
}

3.5 客户端入口

客户端文件必须是已构建好的单文件模块,通过模块加载器注册:

window.__ModuleLoader__.load({
  id: 'my-workbench-package',
  factory: (require) => {
    const React = require('react')
    function BusinessPanel({ service, entry }) { /* 业务面板 */ }
    function apply(ctx) {
      ctx.effect(() => ctx.desktopWorkbenches.register({
        title: '我的工作台',
        repository: 'https://github.com/owner/repository',
        description: '说明它解决什么问题'
      }, BusinessPanel))
    }
    return { apply, inject: ['desktopWorkbenches'] }
  }
})

3.6 构建与本地安装

4. 界面边界

工作台是一种面向具体工作场景的插件。本规范约束工作台、会话、工作区的关联关系和切换行为,不规定统一的业务面板设计。

工作台作者或用户可以定义业务面板的布局、内容、工具栏和业务操作。接入已有工作台时,优先复用原有界面和业务绑定流程,不要求加入统一顶部工具栏、会话下拉框、业务区折叠按钮或“通用聊天”按钮。

4.1 先按主任务选择布局

无论选择哪种布局,都要按业务内容容器的实际宽度设计响应式布局;整窗媒体查询不能代表侧栏展开、分栏及嵌入后的可用宽度。可用容器查询或测量业务根容器,在空间不足时让多列内容重新排布、折叠次要信息或允许有界滚动;长中文标题、英文标识、数字和操作按钮均应保持可读可用,避免单字竖排、按钮裁切和整页横向溢出。

市场、工作台切换和设置等公共入口由 DSH 保留,业务面板不得遮挡。使用 customFrame(见 3.5)的工作台必须限制在宿主分配的主内容区域内:根容器应按正常 flex 布局填满该区域;内部使用绝对定位、窗口最大化或拖拽换位时,都不得越过宿主容器的定位与裁剪边界,也不得覆盖 Desktop 左侧会话栏。原生会话由宿主提供的 conversation 节点放进业务布局,不能再创建一套聊天界面。原生会话能力与模式切换沿用 Desktop 的规则。

macOS 收起侧边栏后,窗口按钮与侧边栏展开按钮占用主内容区左上角。宿主会给左侧嵌入式业务面板和 customFrame 的根节点内、作为首个子元素的语义 <header> 预留 --dsh-frame-leading-clearance 宽度;工具栏可留在原来的 48px 顶部行,主体无需整体下移。自定义工具栏若不是这个结构,应在自身样式中使用同一变量避让,不要覆盖窗口按钮或 shell.leading。

5. 工作台、会话与工作区

6. 未绑定会话时的使用

打开工作台后,即使没有会话或工作区,也应立即显示业务面板。浏览、创建、选择业务档案或项目,不得以已有原生会话或工作区为前提。

仅当用户执行向 Agent 发起请求、写入会话草稿等依赖会话的操作时,才检查当前会话是否属于该工作台。尚未绑定时,在该操作处引导创建或打开会话,不阻断其他业务功能。

工作台内部应提供“在此工作区新建工作台会话”或“选择资料位置并开始工作台会话”等明确动作。业务项目本身不需要文件系统时可以先创建业务记录;一旦需要保存文件或创建 DSH 工作区,必须先调用宿主目录选择器,由用户选择已有目录或在系统选择器中明确新建目录。工作台不得在默认位置、用户主目录、当前仓库或其他推测路径中静默创建文件夹。确认位置后再创建工作区和会话、登记归属、保存业务关联并填入开场草稿;取消时不得留下目录、空项目、工作区、会话或绑定。已有业务资料只能恢复用户此前确认的位置;位置不存在时重新选择,不得自动创建同名目录。失败时保留可重试状态,不得默默改用无关工作区。

先选择业务档案或项目,再创建第一条会话时,应保留当前业务选择。打开已有会话时,优先恢复该会话已有的业务映射,不被其他会话最近选择覆盖。

接入已有工作台时保留原有的项目创建引导和独立业务流程。用户无需先手工新建会话;工作台通过 Desktop 接口发起创建或恢复,由宿主校验并登记归属。开场草稿保留用户已输入的内容并由用户发送;创建失败或延迟时保留草稿供重试。自动执行的业务流程必须在正确归属的会话中运行,不能与开场草稿混用,也不能由隐藏工作台触发误发送。

7. 模式入口与切换

宿主在侧栏顶部提供单一模式切换器:按钮只显示当前模式,展开后可在“原生会话”和已添加工作台之间切换;“工作台管理”入口常驻最右侧。工作台不得复制、遮挡或替换这些公共入口。切换模式只改变前台展示和会话筛选,不执行卸载重装,也不停止后台任务。

“原生会话”和各工作台是平行模式,当前模式决定可见会话和新建归属:

显式打开未绑定会话时切换到“原生会话”;显式打开已绑定且 owner 可用的会话时切换到对应工作台。owner 已移除、卸载或不可用时按普通会话处理,不自动唤起或重装。异步创建期间如果用户继续导航、切换模式或移除 owner,不得把界面拉回旧模式、覆盖后续选择或绑定到失效 owner。

切换模式不得自动收起或展开左侧会话栏;侧栏状态由用户控制并在模式间保持。工作台会话标题前显示所属工作台的小图标,普通会话不显示;图标只表示归属,并提供可访问名称或提示。折叠态与展开态中的按钮、菜单、选中态和焦点轮廓都不得裁切、重叠或溢出。

首次进入工作台可以显示首页、空会话状态或按工作台约定初始化会话,但业务面板不能依赖会话初始化完成。后续进入恢复该工作台最近会话。导航和切换不得删除会话、业务资料、项目文件、收藏或笔记。

8. 本地自测清单

开发完成后按责任逐项确认。“宿主负责”是对当前 Desktop 能力的观察和问题反馈,插件作者不得为此复制宿主界面;标为“仅使用该能力时适用”的项,不使用时记“不适用”及原因。全部适用项有证据通过,才能称为本机自测通过。

包与加载

第 4 节:界面边界

第 5–6 节:工作区与会话

第 7 节:模式切换与保留

9. 失败时如何交付

最终必须列出真实结果和证据:修改的文件、包版本、本机安装与自测结果、未验证的项目。缺哪一项就写哪一项,不虚构成功。缺少工具链、安装失败或宿主接口不可用时,保留已完成的代码,说明原因和下一步。

参考