dsh-manager-analysis

@deepseek-ai/dsh-manager

⚠️ 版本适配标注:本包当前版本 0.35.5,与 DSH 0.1.0-rc.7 的 web 端配套(在 rc7 web profile 上开发并验证)。 它和目前最新版 DSH 存在一定差距(DSH 后续版本可能已调整宿主接口/技能注册契约,本包未随新版本适配)。 建议使用 rc7 web 端的用户安装本版本;若你的 DSH 高于 rc.7,请先确认兼容性或等待适配版本。

DSH Web 的管理面板合集(静态插件包,0.6.0 起由 @deepseek-ai/dsh-skill-manager 更名合并而来)。

一个包覆盖五大模块:

模块 说明
Skills 管理 技能目录汇总、Agent/用户调用开关、回收站、备注/别名、拼音匹配、配置编辑、观察与自优化开关
部署补丁管理 目录驱动的 replace/script/override 三类补丁引擎(快照 + 链重放 + 事务 + RECOVERY.md + CLI 兜底)
本地仓库面板 多根目录扫描、GitHub 克隆/镜像、git 状态与 fetch、仓库详情、Skill 仓库同步、AI 讲解
服务面板 本地服务识别、静默启动配置(venv launcher)、进程/端口/健康阶梯测试、日志、AI 诊断
随包治理技能集 6 个随包分发的技能:local-governance / dsh-repo-clone / dsh-review / service-config / skill-optimize / dsh-plugin-lifecycle

随包技能集(治理与工作流)

skills/ 目录随包自动扫描注册(0.34.5 起目录即真相,新增技能只需建目录放 SKILL.md),构成一套完整的本地治理工作流:

技能 职责
local-governance 本地治理体系总纲:装配清单(MANIFEST.md)、仓库注册表(REPOS.md)、机器账本(repos.json)、归档/装配/升级/回滚、更新后审核钩子与待办提醒
dsh-repo-clone 克隆远端仓库到本地 DSH 目录树 + 登记治理账本(代理检查、schannel 应急、克隆后快速分析与 DSH 插件装配询问)
dsh-review 审核/复核项目更新:读待审核队列 → 定位 diff → 一审 7 维 → 二审源码证伪 → 修复前评估 → 修复验证并写回
service-config 给本地项目配置服务面板的服务:识别类型 → 生成静默启动配置 → 写入 services.json → 阶梯测试
skill-optimize 处理技能观察记录并落地技能优化(去噪评估 → 最小方案 → 用户确认 → 落地 → 写回),判据为 writing-for-agents
dsh-plugin-lifecycle DSH 插件全生命周期:从零到发布/退役(仅模型自动调用)

配套机制:更新后主动询问审核(代码/配置变更发版后询问立即/推迟,登记/克隆静默入队 _governance/pending-reviews.json);技能观察与自优化(面板卡片「启动优化检测」开关,任务结束统一复盘一次,收尾只记录、修改永远过用户确认,状态存 _governance/skill-observations.json)。

Skills 管理

按 全局 / 项目 / 插件 / 预设 / 系统内置 五组汇总当前技能目录(0.8.5 起把「插件 / 预设」拆为两组: custom + 全局作用域 = 插件,custom + 预设作用域 = 预设),展示并独立切换每个技能的 Agent 可调用 与 用户可调用 两个开关(直接改写技能文件的 frontmatter),支持:

部署补丁管理(0.7.0:目录驱动)

侧边栏 Skills 上方新增「补丁」按钮(同款样式)→ 目录驱动的补丁面板。补丁是一个声明文件 + 可选配套文件的集合,放在补丁目录里即被识别:

~/.dsh/dsh-manager/patches/
├── *.dsh-patch.json        声明文件(根目录 =「默认」类别;一级子目录 = 类别)
├── *.dsh-patch.js          script 类型的纯函数配套(module.exports = { apply(text) })
├── <name>.override/        override 类型配套:目录内单个名为 file 的整文件替换
├── .state/files/<sha1(abs)>.json   每目标文件的机器状态(官方快照 + 启用链 + 校验和)
├── .state/snapshots/<sha256>        官方快照(文件名 = 内容 sha256 hex)
└── RECOVERY.md             人类可读恢复手册(dsh 打不开时的复原指南)

声明文件 schema 示例(*.dsh-patch.json,file 为部署根内相对路径):

{
  "id": "slash-seed",
  "name": "斜杠播种",
  "description": "空输入框默认 /,裸 / 视为空不发送,发送后重置回 /",
  "apply": "refresh",
  "prerequisites": [],
  "conflicts": [],
  "files": [
    {
      "file": "node_modules/@deepseek-ai/dsh-client-ui-conversation/lib/client.js",
      "kind": "replace",
      "marker": "dsh-skill-manager-seed",
      "pairs": [
        { "find": "draft = \"\";", "replace": "draft = \"/\"; // dsh-skill-manager-seed", "count": 1 }
      ]
    }
  ]
}

kind 允许 replace / script / override:

本地仓库面板(0.9.0:多根目录)

侧边栏第三个按钮 → 本地仓库面板。把本地仓库纳入治理视图:

服务面板(service-config)

侧边栏第四个按钮 → 服务面板。为本地项目配置静默启动的本地服务:

治理体系(local-governance)

本包携带完整的本地治理工作流(local-governance 技能为总纲),账本集中在 _governance/ 目录:

文件 用途
MANIFEST.md 装配资产清单:包名/装配方式/装配版本/归档版本/路径/上游/备注
REPOS.md 仓库注册表:所有本地仓库的状态总账(人工可读)
repos.json 机器账本:面板读取的仓库真相(v2 schema,type ∈ {local, mirror})
pending-reviews.json 待审核队列:更新后按流程入队,dsh-review 审核写回 done
skill-observations.json 技能观察记录:观察开关状态 + 优化建议,skill-optimize 消费

核心纪律:版本只增不覆盖、账实一致(目录实况 = repos.json = REPOS.md 三者一致)、 更新后主动询问审核(代码/配置变更类询问立即/推迟;登记/克隆静默入队不打扰)。

定位定义(在 harness 架构中的归类)

一句话:dsh-manager 是一个安装树外(out-of-tree)的双面(dual-face)web profile bundle 插件—— 宿主半边是一条 webServer 路由注册行,浏览器半边是一个 client 模块入口(纯 UI 槽位插件), 两端通过包私有同源 HTTP 路由通信。

四层拆解:

  1. 组合层:profile bundle patch 层(dsh.bundle.patch 声明)。由 dsh plugin 以 npm 包形式装入 $DSH_HOME/profiles/web 并被 reconcile 进 dsh.profile.bundles 栈;启动时该补丁向 profile 组合根 插入一条宿主平面行。它与 dsh-base / dsh-web-app 同属一个补丁栈,但位于安装树外、 由 profile 自己的 pnpm 管理,依赖经 $DSH_HOME/profiles/node_modules 回退场解析。
  2. 宿主半边:普通 Cordis 行,inject: ['webServer']。属于传输面注册型宿主行: 不 provide 任何 Cordis 服务(因此不参与服务注册冲突审计,也不受 preset isolate realm 规则约束), 消费宿主平面的 webServer 注册一条包私有路由;业务上只读消费宿主注册表 (skills / sessions / agents / agentPresets),并借助宿主 fs 服务读写技能配置文件。 生命周期 = 进程组合生命周期(boot 激活,无 per-session 挂载,无审批流程)。
  3. 浏览器半边:经 dsh.client: { platform: 'web' } + exports["./client"] 声明被 client-modules 扫描进 window.__DSH_BOOT__ 入口图的 client module entry(即部署所称的 “dsh.client 行”, 与 ui-skill / ui-workspace 同族),由浏览器内核以插件形式采纳;inject: ['slots'] 的纯 UI 槽位插件——向 sidebar.footer.action 与 shell.overlay 注册组件、向 locale 注册字典、注入页面级样式。
  4. 通信面:包私有同源 HTTP 路由——既不是 api-proxy 的固定 RPC 表,也不是 Typert 编译期 Remote 描述符,更不是动态插件的 harness.handle / host.call;与内置插件市场同构。

与“动态插件”的关系:本包是动态插件 skmgr 的静态固化形态——同一份业务代码,但从 “运行进程内、会话拥有、需审批的 Dynamic Package”变为“磁盘上的 npm 包、profile 拥有、 随启动组合加载的 bundle 层”。动态形式随进程退出消失,静态形式随安装持久。

目录结构(lib/ 即产物,无构建步骤)

dsh-manager/
├── package.json      # dsh.bundle + dsh.client 双声明(files 白名单见下)
├── cordis.patch.yml  # bundle 补丁层:向 profile 组合插入本包行
├── lib/
│   ├── index.js      # 宿主半边:/api/dsh-manager 路由(webServer),全部 rpc 实现
│   ├── client.js     # 浏览器半边:__ModuleLoader__ 入口,4 按钮 + 4 面板 + CSS
│   ├── service-core.js  # 服务面板引擎(识别/配置/启停/日志/诊断)
│   ├── repo-core.js     # 本地仓库引擎(扫描/检测/详情/git 状态)
│   └── ai-core.js       # AI 讲解引擎(provider/流式/缓存)
├── skills/           # 随包技能(6 个,自动扫描注册:目录即真相)
│   ├── local-governance/  dsh-repo-clone/  dsh-review/
│   ├── service-config/    skill-optimize/  dsh-plugin-lifecycle/
├── examples/         # 示例补丁(*.dsh-patch.json,随 tarball 分发但不自动安装)
├── scripts/          # CLI 兜底与验证脚本(不打包进 tarball)
└── README.md

安装(dsh plugin → pnpm 转发器)

仓库根目录携带当前最新版 tarball(如 deepseek-ai-dsh-manager-0.35.5.tgz,随版本更新提交), 克隆仓库即可直接安装,无需自行打包:

# 1) 克隆仓库(或直接从 GitHub 下载仓库内的 .tgz)
git clone https://github.com/as1350/dsh-manager
cd dsh-manager

# 2) 装进 web profile(dsh plugin 会把参数原样转发给 profile 目录里的 pnpm,
#    并在安装成功后自动把本包名追加进 dsh.profile.bundles)
dsh plugin --profile web add .\deepseek-ai-dsh-manager-0.35.5.tgz

# 3) 重启 web(组合与 client-modules 扫描都发生在启动时)
dsh web

想从 GitHub 网页安装:打开仓库 → 点击 deepseek-ai-dsh-manager-0.35.5.tgz → Download → 对下载文件执行 dsh plugin --profile web add .\下载路径\deepseek-ai-dsh-manager-0.35.5.tgz。 包名/版本会随更新变化,以仓库内实际 tgz 文件名为准。

安装后 profile 里会发生:

  1. $DSH_HOME/profiles/web/node_modules/@deepseek-ai/dsh-manager/ 就位;
  2. $DSH_HOME/profiles/web/package.json 的 dsh.profile.bundles 末尾追加 @deepseek-ai/dsh-manager(由 dsh plugin 的 reconcile 步骤自动完成);
  3. 启动时该 bundle 的 cordis.patch.yml 把行 { id: dsh-manager, name: '@deepseek-ai/dsh-manager' } 插入组合 → 宿主半边注册路由;client-modules 扫描到 dsh.client 声明后把 lib/client.js 作为 /plugins/@deepseek-ai/dsh-manager/client.js 注入 window.__DSH_BOOT__;
  4. 宿主半边启动时自动扫描 skills/ 目录,把 6 个随包技能注册进技能注册表 (registerPackagedSkills:frontmatter 的 name/description/whenToUse/invocation 元数据透传, 逐条 try/catch 隔离,坏条目只 warn 不拖垮整体)。

宿主依赖(skills / sessions / agents / agentPresets / webServer)全部由 dsh-base + dsh-web-app bundle 提供;Node 侧模块解析走 $DSH_HOME/profiles/node_modules 回退符号链接场。运行时 npm 依赖仅 pinyin-pro 与 js-yaml(由 profile 的 pnpm 随安装解析); peerDependencies 仅作文档,autoInstallPeers: false 下不会被安装。

升级(直接加装,无需先删)

# 包名相同,装上更高版本 tgz 即覆盖升级(无需 remove):
dsh plugin --profile web add .\deepseek-ai-dsh-manager-0.35.5.tgz
# 重启 dsh web 生效(备注/回收站/补丁状态/观察记录都在 ~/.dsh 与 _governance,与包无关,零损失)

仓库内 tgz 随版本更新;升级时以仓库根目录实际携带的最新 tgz 为准。 版本纪律:每次发布只增不覆盖——新版本号只出现一次,历史版本归档于 _governance/MANIFEST.md 与本地 _snapshots/,不回写旧版本。

部署补丁(补丁面板为主通道,CLI 脚本为兜底)

完全平等原则:引擎不内置任何补丁定义、不自动创建任何补丁文件——目录里的每个 .dsh-patch.json 都是用户/agent 自己放进去的普通文件,删除即删除、绝不复活。

内置管线有两处硬编码(触发字符 //@、输入框初始内容),插件 API 够不着,本包在 examples/ 目录附带两个示例补丁(纯数据文件,随 tarball 分发但不会自动安装): 打开补丁面板 → 「导入」选择 examples/ 下两个文件(或直接复制到 ~/.dsh/dsh-manager/patches/)即可获得:

示例一 · 顿号触发(dunhao-trigger → dsh-client-ui-input-trigger/lib/client.js): 触发字符硬编码为 / 与 @。补丁把 detectTrigger 中的 、(U+3001)归一化为 /—— 中文输入法下敲 、 也能打开菜单,选中候选项后输入框照常写入 /技能原名 。

示例二 · 斜杠播种(slash-seed → dsh-client-ui-conversation/lib/client.js): 空输入框默认存在一个可见的 /——不敲触发字符,直接打字即可识别技能/命令。配套语义: 裸 / 视为空(Enter/发送按钮不发送孤立字符)、发送成功后重置回 /、未发送的草稿仍会优先恢复、 hero 大输入框保持原样。想正常聊天:按一下 Backspace 删掉 / 即可。

使用须知:

# 无参数:报告每个补丁的 id / 类别 / 状态(applied / adopted / lost / clean),并打印 RECOVERY.md 路径
powershell -ExecutionPolicy Bypass -File .\scripts\reapply-deployment-patches.ps1

# -restore:dsh 打不开时的救命通道——把 .state/snapshots 里所有官方快照复制覆盖回目标文件,
#            然后清空全部机器状态与快照(原子写,每个恢复的文件都会打印)
powershell -ExecutionPolicy Bypass -File .\scripts\reapply-deployment-patches.ps1 -restore

# -apply:重打所有 clean 补丁(replace/override;含 script 的补丁跳过,只能从面板启用)。
#         逐文件校验(find 出现次数、override 配套文件存在)通过后才原子写入,并写机器状态;
#         任一文件校验失败则整补丁跳过并打印原因
powershell -ExecutionPolicy Bypass -File .\scripts\reapply-deployment-patches.ps1 -apply

脚本幂等、自保护(目标文件缺失/出现次数不符时拒绝写入)、原子写(.dshskm-tmp + Move-Item)。

卸载

dsh plugin --profile web remove @deepseek-ai/dsh-manager
# 重启 dsh web 生效(技能随包消失,本地数据如备注/补丁/治理账本均保留在 ~/.dsh 与 _governance)

挂载后验证

  1. 重启后宿主启动日志无本包报错(route 注册失败、client bundle 缺失都会 loud throw);
  2. 刷新页面:侧边栏底部出现 补丁 / Skills / 本地仓库 / 服务 四个按钮;
  3. 打开 Skills 面板确认技能分组、Agent/用户开关、观察开关、删除按钮、备注编辑、配置弹窗正常, 且随包 6 技能(local-governance / dsh-repo-clone / dsh-review / service-config / skill-optimize / dsh-plugin-lifecycle)出现在插件组;
  4. 打开补丁面板确认类别分组、状态徽标、启用/禁用/导入/删除/类别管理、提醒模式开关、可执行总闸正常;
  5. 打开本地仓库面板确认多根目录扫描、git 状态、GitHub 镜像分组、Skill 仓库分组正常;
  6. 打开服务面板确认服务识别/配置/启停/日志正常;
  7. 开/关开关与保存配置:直接落盘生效(不受模型面沙箱限制)。

行为语义(与底层 @deepseek-ai/dsh-skill 一致)

开发备注