Deeptop 项目说明手册

August 31, 2026 · View on GitHub

本手册描述当前仓库实现,不是 DSH 官方 API 的替代文档。Deeptop 运行时来自 vendor/dsh 子模块锁定的 DSH 提交;更新子模块后应重新生成并验证 dsh-runtime,再检查 Profile、ApiProxy 和 Remote 契约。

1. 项目定位

Deeptop 是 DSH 的原生桌面工作台:

  • DSH 提供 Agent、Session、Tool、Model、Storage、Workspace、Skill、Goal、Provider、权限和事件等领域能力;
  • Tauri/Rust 启动并监管 DSH 子进程,负责 Profile 物化、JSONL stdin/stdout、超时、重启和桌面系统能力;
  • cordis/ 按插件独立保存 Deeptop 的 Cordis 源码;它们以兼容运行时 Bundle deeptop-bridge 在 DSH 内部运行,把 DSH Host/API 能力转换为受控的桌面协议;
  • React 提供会话、输入、设置、运行台和 Inspector 等原生界面,并将事件映射为 UI 状态。

因此,项目的核心目标是:

复用 DSH 的官方运行时和契约,在桌面端提供原生交互;而不是把 WebUI 搬进 Tauri,也不是重新实现一套 Agent。

2. 快速开始

2.1 环境要求

  • Node.js 22.19+ 或 24+;
  • Rust/Cargo 和 Tauri 桌面开发环境;
  • Node.js 在 PATH 中可用(npm 仅用于开发依赖安装);
  • 首次生成内嵌 DSH 运行时时可访问 npm registry,或构建机已有源码依赖缓存;
  • Windows 上需要可用的 WebView2 环境。

安装依赖并启动桌面应用:

npm install
npm run tauri:dev

仅启动 Vite 前端:

npm run dev

Vite 浏览器预览没有 Tauri 的 invoke、事件通道和 DSH 子进程,只适合做 UI 开发。

2.2 构建与测试

npm run dsh:sync
npm run dsh:verify
npm run build
npm run tauri:build
npm run test:bridge
npm run test:retry
npm test
npm run version:check

项目提供统一的 npm test,但暂未配置 lint 或 format 脚本。修改前端后运行 npm run build;修改 cordis/ 插件、Bridge 路由、来源校验或消息重试时运行对应的专项测试。src-tauri/tauri.conf.json 已启用 Tauri bundle,npm run tauri:build 会构建原生应用和平台包。推送 v<SemVer> Tag 会触发 GitHub Actions 的跨平台构建、校验和 Release 发布,详见 CI/CD 与发布

2.3 首次启动与用户流程

  1. 启动 npm run tauri:dev,等待 DSH runtime status 进入 ready。开发命令会先从 vendor/dsh 生成并校验内嵌运行时,应用启动不会访问 npm registry。
  2. 在 Settings/Workbench 中配置 Provider 和凭据(如果当前 Profile 暴露这些域);凭据由 DSH API 管理,不应提交到仓库。
  3. 选择或创建 Workspace。新会话使用选定目录作为 cwd,已存在的 Session 不会被隐式改写。
  4. 创建 Session、选择模型并发送消息;运行中可通过 queue 或 steering 模式追加上下文。
  5. 在 Interaction 面板处理 Approval 和 User Question;根据事件可执行单选、多选或自定义回答。
  6. /skill 选择 Skill,通过 Subagent/Goal 面板使用对应能力,用 Runtime Inspector 查看 Profile、插件和路由。
  7. 通过会话操作执行 retry、fork、archive、restore、export 或删除。刷新 DSH 会重启子进程,pending request 可能失败,应重新加载当前状态。
  8. 从系统托盘的“未读”“最近”或“更多”入口恢复窗口并打开对应会话;“新会话”会回到空白输入页。Windows 使用固定宽度的 Deeptop WebView 弹窗并复用当前应用主题,弹窗不可用时回退到系统原生菜单。

3. 代码结构

路径职责
src/App.tsx组装桌面工作台、加载会话和订阅运行时状态
src/components/会话侧栏、消息转录、输入框、设置、运行台和交互面板
src/app/会话、消息、轨迹、事件、重试和设置等前端状态模型
src/lib/desktop.tsTauri 命令、Bridge 请求、事件类型和 DSH 数据类型
src/lib/desktop-client-runtime.tsRemote loopback 调用和 Host Remote 事件订阅
src-tauri/src/main.rsDSH 进程管理、Profile 物化、JSONL 请求/响应、系统托盘和诊断转发
src-tauri/Tauri 应用配置和 Rust 工程
cordis/*/index.mjs各个内置 Cordis 插件的独立入口和服务依赖声明
cordis/desktop-bridge/bridge.mjsdeeptop/1 JSONL 协议、请求处理和事件转发
cordis/desktop-bridge/routes.mjs桌面 API allowlist、Host API 转发和原生边界操作
cordis/cordis.patch.yml内置 desktop Profile 的 DSH Host/Cordis 插件组合
cordis/desktop-profile.jsondesktop Profile 的基础 Bundle 清单
PLUGIN_COMPATIBILITY.md插件兼容分层和未完成事项
DEEPTOP_UI_RUNTIME.mdClient Module、Slot、Bridge 能力和桌面 UI 插件的实施设计
REFACTORING_CORDIS_UI_RUNTIME.md合并 UI Runtime 后的重构基线、功能归属和实施顺序
CORDIS_UI_RUNTIME_HANDOFF.md新会话接手迁移、测试、风险和工作区保护事项
WEBUI_PARITY.md功能对齐清单和 WebUI 明确排除项

4. 启动生命周期

桌面窗口初始化时,Rust 侧创建 BridgeManager 并启动 DSH。启动流程如下:

Tauri setup
  -> materialize_desktop_profile()
  -> discover dsh on PATH, npm global, $DSH_HOME, or npx cache
  -> npm install --prefix $DSH_HOME (only when every existing source is unavailable)
  -> launch dsh or npm exec --offline -- dsh --profile desktop
  -> pipe stdin/stdout/stderr
  -> receive { type: "ready", protocol: "deeptop/1" }
  -> emit dsh-runtime-status
  -> React starts DSH API calls

启动器会从 PATH 查找本机 Node.js 和 npm;Windows 下会直接调用 npm 的 CLI JavaScript 文件,避免依赖 shell 和 GUI 进程中的 .cmd 脚本解析。DSH 的 stdout 用于结构化 JSONL,stderr 转为诊断事件;非 JSONL 输出不会被当作 API 响应。

Bridge 进程退出、启动失败或请求超时后,Rust 会更新运行时状态并结束等待中的请求。应用可以调用 refresh_dsh 重启 DSH 子进程。

5. DSH_HOME 与 Profile

5.1 默认目录

DSH_HOME 由环境变量控制:

  • Windows:显式设置时使用该目录,否则默认为 %USERPROFILE%\.dsh
  • Unix-like:显式设置时使用该目录,否则默认为 $HOME/.dsh

Deeptop 使用或创建:

$DSH_HOME/
├─ profiles/
│  ├─ desktop/
│  │  ├─ package.json
│  │  ├─ cordis.patch.yml       # 用户持久化扩展
│  │  └─ pnpm-workspace.yaml
│  └─ node_modules/
│     └─ deeptop-bridge/        # 应用物化的 Bridge Bundle
├─ node_modules/                 # npm prefix 下安装的 DSH 及依赖
├─ storages/                     # 默认 JSON storage 配置使用的目录
├─ themes/                       # 主题 CSS 目录;内置主题随包送达,用户可放入 .css 作为新主题
└─ ...                           # 其他 DSH 数据

5.2 物化规则

应用启动时:

  • 如果 desktop Profile 不存在,则使用仓库内 cordis/desktop-profile.json 模板;
  • 始终确保 @deepseek-ai/dsh-basedeeptop-bridge 位于 Bundle 列表前部;
  • 保留用户添加的其他 Bundle;
  • 只在用户文件不存在时,才由 cordis/profile.patch.yml 模板创建 profiles/desktop/cordis.patch.yml,并创建 workspace 文件;
  • cordis/<plugin>/ 的嵌套布局写入 profiles/node_modules/deeptop-bridge,以兼容包名供 DSH 解析;
  • 升级时先写嵌套模块,再切换 package manifest 和 patch,最后清理旧平铺生成文件;
  • 每次启动都会同步内置 Bundle,因此不要直接修改生成目录。

用户要添加 Cordis 插件时,应修改:

$DSH_HOME/profiles/desktop/cordis.patch.yml

示例:

- insert:
    - id: local-plugin
      name: 'C:/work/local-plugin/src/index.ts'

6. 当前 DSH 能力面

内置 cordis/cordis.patch.yml 当前组合了以下类型的服务:

  • storage、JSON storage、storage domain;
  • message feedback、message annotations、session pins;
  • session log export、session stats、projection cache;
  • workspace、native directory picker、plugin inventory;
  • Host ApiProxy 和 Cordis Host runner;
  • Agent Presets、Skill installer 和桌面 Bridge。

如果历史会话引用的 Agent Preset 已被删除,桌面端不会静默改用其他 Preset;打开时会明确告知缺失项,用户选择可用替代项并确认后,才创建保留原历史的迁移副本。原会话保持不变,迁移副本可能因工具、系统提示词和能力不同而产生不同后续结果。

部分工具在 Profile patch 中标记为 disabled,是为了避免与 standard Agent Preset 重复挂载,并不表示桌面端放弃这些 DSH 工具。Windows PowerShell、文件、搜索和 Job 等工具由现有 Preset 提供。

7. API 与事件使用方式

React 侧通过 bridgeRequest 发送请求:

const result = await bridgeRequest<DshSessionModels>("session.models", {
  sessionId,
});

Bridge 在 cordis/desktop-bridge/routes.mjs 中生成 DSH RPC request,并只暴露显式列出的 method,例如:

session.list              session.history         session.prompt
workspace.list            workspace.create        workspace.attachSession
subagent.history          skill.list              goal.resume
settings.describe         credentials.set         llm.models
remote.invoke             plugin.list             respond

真实可用的方法以 cordis/desktop-bridge/routes.mjs 和对应 DSH ApiProxy 为准。未在 allowlist 中的方法会被拒绝。

事件通过两条流进入桌面端:

  • mux:Session、Agent、Projection 和会话相关事件;
  • host:Host 事件,包括 Remote 事件和 Host 生命周期/状态事件;stderr 与 Bridge diagnostic frame 通过独立的诊断通道转发。

Rust 将 Bridge 帧转发为 deeptop-bridge-event,React 再通过 bridge-event-handler.ts 更新当前会话状态。运行时状态使用 dsh-runtime-status,诊断文本使用 dsh-diagnostic。React 把现有会话指示器投影为有界的托盘快照;Windows 由 Rust 定位固定宽度的无边框 WebView,React 使用与主窗口相同的本地主题设置渲染快照,其他平台和弹窗创建失败时保留系统原生菜单。托盘入口按需加载独立的 JS 和 CSS,仅在快照、主题、尺寸或位置实际变化时更新;常规重复打开只显示并聚焦已预热的 WebView。会话与新建操作仍通过 tray-session-opentray-new-chat 事件交回主窗口。

8. 原生扩展指南

新增功能前先判断它属于哪一层:

问题首选位置
需要新增 Session、Agent、Tool、Storage 或权限语义DSH 官方插件 / desktop Profile
需要复用官方 Host 服务但桌面端没有入口cordis/desktop-bridge/routes.mjs + src/lib/desktop.ts
需要复用 Remote/Projection/Host eventdesktop-client-runtime.ts + bridge-event-handler.ts
需要展示或编辑状态src/components/ + src/app/
需要启动、停止、重启 DSH 或访问系统通知src-tauri/src/main.rs
需要目录选择、原生文件保存或下载通道Bridge/Tauri 的边界适配

推荐流程:

  1. 查 DSH 是否已有 Host/Cordis service、ApiProxy method、Remote namespace 或 Projection。
  2. 先把官方 Host 能力加入 Profile,验证依赖和加载顺序。
  3. desktop.ts 声明最小数据类型,避免在 UI 中散落 unknown 的领域假设。
  4. routes.mjs 增加参数校验和 allowlist 路由,并覆盖成功、失败、取消和缺失服务。
  5. 在 React 中只做状态映射和原生交互,不复制官方服务的决策逻辑。
  6. 更新 PLUGIN_COMPATIBILITY.mdWEBUI_PARITY.md,说明“功能兼容”与“WebUI 视觉/生命周期兼容”的差异。

9. 兼容边界

直接复用

优先复用 DSH Host/Cordis 的 Session、Agent Preset、Workspace、Tool、Skill、Subagent、Goal、Settings、Credential、LLM、Storage、Projection、ApiProxy 和事件服务。

通过原生入口适配

对有 Host/Remote 契约但只有 WebUI Client UI 的能力,复用官方参数、结果、错误、Projection 和事件语义,在 React 中实现原生入口。当前典型边界包括 Commands、Message Feedback、Permission、Plan、Session Stats、Session Log Export 和 Directory Picker。

明确不直接加载

以下 WebUI 基础设施不属于当前纯桌面目标:

  • window.__ModuleLoader__ 和动态客户端模块加载;
  • Cordis client runner、WebUI client context 和客户端生命周期;
  • slot registry、WebUI slot 注入和官方 Client bundle 的无改动安装;
  • WebUI layout/primitives/locale 和浏览器专用下载控制器。

这不是拒绝官方插件,而是把“官方 Host 能力”和“官方 WebUI 实现”分开处理。

10. 排障手册

DSH 未就绪

  1. 检查运行时 Inspector 的状态和诊断文本。
  2. 确认 Node.js 在 PATH 中可用,并检查安装包的 dsh-runtime.tar.gzdsh-runtime-manifest.json、应用本地数据中的版本缓存(目录名包含源码提交、平台、架构和摘要前缀)和 CLI 入口清单;若缓存被篡改或 treeSha256 不匹配,启动器会删除该缓存并重新解压。
  3. 确认 DSH_HOME 可写。
  4. 检查 $DSH_HOME/profiles/desktop/package.jsoncordis.patch.yml 是否为有效内容。
  5. 刷新 DSH 运行时,观察新的启动日志。

Profile 插件未加载

确认:

  • 修改的是 $DSH_HOME/profiles/desktop/cordis.patch.yml
  • 插件 name 使用绝对路径或可由 Profile 解析的包名;
  • 插件 ID 未与已有服务冲突;
  • 依赖已经能被 desktop Profile 解析;
  • 没有把改动写到自动生成的 profiles/node_modules/deeptop-bridge

某个面板不可用

先区分两种情况:

  • Profile 中没有对应 Host/ApiProxy 服务:这是能力缺失,应显示不可用,不应伪造数据;
  • 服务存在但调用失败:检查 DSH diagnostic、Remote 错误、参数和当前 Session 是否仍然有效。

浏览器预览与桌面表现不同

预览模式不运行 Rust、DSH 子进程和 Tauri event。涉及会话、模型、文件选择、通知、Remote 或 Profile 的验证必须使用 npm run tauri:dev

11. 版本漂移与证据范围

Deeptop 启动的是 vendor/dsh 固定提交构建的 DSH 版本;运行时清单记录源码提交、包版本和目标平台。仓库源码可以证明 Bridge 的启动命令、Profile 物化、路由 allowlist、JSONL 协议和已实现的 React 入口,但不能单独证明某个 DSH 版本内部服务的全部语义。不要把 Deeptop 描述为 DSH 官方桌面客户端、官方 fork 或“已覆盖全部官方插件”。

判断能力是否可用时,应以当前 Profile、cordis/desktop-bridge/routes.mjssrc/lib/desktop.ts 和事件处理代码为依据。未出现在这些边界中的 DSH 能力不能视为已支持;可选域缺失时,面板应保持不可用。版本升级后应重新验证:

  • desktop Profile 的 Bundle 依赖和插件加载顺序;
  • ApiProxy 方法的参数、返回值和错误结构;
  • Remote namespace/method、Projection 字段和事件语义;
  • 历史恢复、实时事件、取消、超时和 DSH 重启行为。

12. 提交前检查

  • npm run build 通过;
  • 修改 Bridge 时运行 npm run test:bridge
  • 修改消息重试时运行 npm run test:retry
  • 新方法具有 allowlist、参数验证、错误和取消语义;
  • 历史恢复与实时事件都能更新同一状态模型;
  • 快速切换 Session 时,晚到事件不会覆盖当前会话;
  • 插件缺失时 UI 不崩溃、不伪造成功;
  • 文档已说明新增能力位于 DSH、Bridge、Tauri 还是 React 层。