Back to home@Amouren7

dsh-plugin-desk

DeepSeek Harness 插件管家:用人话说明每个插件是做什么的,一键停用/启用(热生效),安全卸载。Settings → Plugins → 插件管家

Stars
0
Language
JavaScript
Created
Sep 11, 2026
Updated
Sep 11, 2026
GitHub repo

Introduction

dsh-plugin-desk · 插件管家

用人话看懂每个插件和技能是做什么的,一键停用/启用,安全卸载。

DeepSeek Harness 的「设置 → 插件」页是一份只读清单:它列出模块名,却不告诉你这个插件到底干什么用;想关掉一个插件,只能去手改 cordis.patch.yml。技能那边更糟 —— 装了 57 个技能,其中 14 个模型根本看不到,只能靠记住 /handoff 这类命令来用。

这个插件在同一个「插件」页里加一个插件管家标签页,分「插件」「技能」两段,补上这些事。

四个痛点

痛点官方界面插件管家
看不懂插件是做什么的只显示英文模块名中文名 + 一句话说明 + 来源徽章
关不掉 / 卸不掉插件纯只读,「已启用」只是个标签一键停用/启用(热生效)+ 卸载
不知道技能怎么用模型目录与 / 菜单互不可见每个技能标明唯一可用的触发方式
不知道技能怎么关没有开关,只能手改 SKILL.md两个真开关(模型自动加载 / / 命令),热生效

插件管理

功能

1. 用人话说明每个插件的作用

按质量优先级取说明:dshhub.summarypackage.jsondescriptionREADME.md 首段(自动剥离 Markdown / HTML、按语义边界截断)。

实测覆盖率(本机 168 个已安装包):dshhub 仅 1 个包使用,description 覆盖 164 个 —— 所以 description 才是主力,dshhub 是锦上添花。

2. 来源徽章

徽章判定依据
官方包名在 @deepseek-ai/ 命名空间下
社区lockfile 里是普通 semver 版本号
GitHub 直装lockfile specifier 为 github:owner/repo#tag
本地链接specifier 为 file: / link:

判定读 pnpm-lock.yamlimporters 段,不看目录类型 —— 本环境用 nodeLinker: hoisted,真实目录并不代表来自 registry。

3. 一键停用 / 启用

走 Cordis 官方的 entry 更新通道 Entry.update({ disabled }):停用时 loader 会 await _dispose(fiber),该插件的工具、路由、监听立即注销;启用时重新 init() 装配。热生效,不需要重启。

选择会记在 ~/.dsh/plugin-manager.json,每次启动自动重放,所以重启后仍然保持你选的状态。

4. 安全卸载

  • 先快照 entry 的 options,再 loader.remove(),然后校验确实移除;若仍在,按快照 loader.create() 恢复原状。
  • 官方 @deepseek-ai/* 组件禁止卸载(卸载会破坏启动),UI 上按钮直接置灰,只允许停用。
  • 卸载后同样记入状态文件,重启不会自己装回来。

5. 噪声过滤

本机装了 168 个包,其中绝大多数是传递依赖,真正能管理的插件只有个位数。列表会自动剔除:

  • 非插件库(没有 dsh.bundle 的普通依赖)—— 实测过滤 154 个
  • 框架内部条目(cordis:includenode:* 等)—— 实测过滤 4 个

技能管理

插件管家页顶部有 插件 | 技能 分段控制。技能页复用同一套卡片语言。

1. 每个技能标明「唯一可用的触发方式」

技能的 invocation 策略有两个互相独立的维度,界面把它们翻译成一句人话:

模型自动加载/ 命令可用界面直接告诉你
模型会自己调用;也可用 /name 手动唤起
模型看不到它 —— 只能用 /name 手动唤起
仅模型自动调用(/name 不可用)
已停用

第二行是本机 14 个技能的真实状态。它们在模型侧完全不存在,靠翻文件夹是发现不了的。

实测(本机 60 个技能):

模型看不到、只能用 / 唤起 = 14
两个开关都开的           = 46
来源:用户安装 57 / 插件提供 3

2. 两个真开关

不是「障眼法」:插件注册一个 rank 0 的影子 provider,把策略按需置 false。注册表按层合并、同层内 rank 升序取胜,而三个消费点都按策略过滤:

消费点过滤后果
tool-skill 模型目录filter(isModelInvocable)不进 <available_skills>
tool-skill 加载守卫isModelInvocableskill 工具拒绝加载
session-controller 命令目录filter(isUserInvocable)不进 / 菜单

关键实现细节:这些技能住在 agent preset 作用域,不在全局层。而服务读取走 topology-sensitive 属性代理 —— ctx.skills(声明式注入)返回绑定到访问上下文的反射,ctx.get('skills') 读的是全局存储。插件必须为每个 preset createScope 并走该作用域的 .skills 反射注册,否则候选会被更近的层直接盖掉。这一步不需要修改任何预设文件(shipped 与用户预设一并覆盖)。

3. 清理线索

标记实测数量判定依据
目录内有不生效的 SKILL.md40加载器只认 <技能名>/SKILL.mdsegments.length > 2 一律忽略
目录内混入非技能文件2根目录出现 package.json / package-lock.json
缺少描述0模型与命令菜单都无法判断用途

嵌套那份不只是冗余 —— 抽样确认它与生效那份内容不同brainstorming 10047 vs 15456 字节)。

4. 来源与升级对象

从指令文件路径反解归属:

  • 路径含 node_modules/<pkg>/ → 「插件提供 · 升级对象 <pkg> v<version>
  • 路径在 ~/.agents/skills/~/.dsh/skills/ 下 → 「用户安装」

source 字段在本部署不可信:host 进程 cwd 是家目录,预设把用户根报成 project-agents。所以分类以路径为准。

5. 没有「自动升级」按钮

实测本机 57 个技能:0 个是 git 仓库、无清单、无安装元数据(~/.agents/plugins/marketplace.json 与技能无关,它只有一条指向不存在路径的条目)。通用自动升级路径不存在,因此不提供按钮 —— 只标注该升级什么。


安装

dsh plugin --profile web add "github:Amouren7/dsh-plugin-desk#v0.2.1"

装完重启 dsh web,然后打开 设置 → 插件 → 插件管家

页面是懒加载的,浏览器可能缓存旧前端;若看不到新标签页,按 Ctrl+Shift+R 强制刷新。

暂未发布到 npm:dsh-plugin-manager / dsh-plugin-hub / dsh-plugin-console 三个相近名字均已被他人占用, 因此先用 GitHub 源码安装。本包名 dsh-plugin-desk 在 npm 上是可用的。

兼容性

DSH>=0.1.5-rc.1(依赖 0.1.5 的 settings.plugins.tab 插槽)
Node>=20
Profileweb
实测环境Windows 11 · DSH 0.1.5-rc.1 · Node 24.18.1

技能功能需要部署提供 skillsagentPresets 服务,以及可解析的 @deepseek-ai/dsh-scope;缺任一项时技能开关会如实拒绝并在界面说明原因,插件页其余功能不受影响。

@deepseek-ai/dsh-scope两个解析根依次尝试:profile 根(<DSH_HOME>/profiles/)与 DSH 自身的安装根。任一可用即可,因为预设作用域覆盖要靠它建立;两个都不可用时才会降级,且失败信息会列出实际找过的路径。

自检与测试

node scripts/selftest.mjs   # 离线复验插件元数据链路(不启动 loader)
npm test                    # 22 项单元测试:路由自愈 / 客户端错误硬化 / 技能派生 / 作用域解析 / apply 冒烟

技能功能的端到端实测记录见 tests/acceptance.md(含未验证项的如实标注)。

已验证(全部为实测结果)

界面(设置 → 插件 → 插件管家):

验证项结果
标签页接入与官方 插件配置/插件列表 并列出现,官方页面 data-slot-error 为空
插件卡片5 张卡片,名称/说明/来源徽章/版本/状态齐全
噪声过滤168 个已安装包 → 只保留 5 个真插件,过滤 154 个非插件依赖 + 4 个框架内部条目
分段控制`插件
技能卡片60 张,含作用、whenToUse、来源、指令文件路径、用法提示
技能开关60/60 可开关;写入后赢得该名字的 provider 变成本插件
界面一键停用点「停用」→ fiber 已 dispose,徽章变「已停用」,按钮变「启用」
界面一键启用点「启用」→ fiber 重新装配完成,徽章回「运行中」
状态持久化~/.dsh/plugin-manager.json / ~/.dsh/plugin-desk-skills.json 落盘,启动时重放

系统级验证技能停用真的生效(由 harness 自身确认,非插件自证):

动作本会话 <available_skills> 目录的变化
brainstorming 模型自动加载 = 关brainstorming 消失
恢复默认回来
grilling 模型自动加载 = 关grilling 消失
恢复默认回来

覆盖跨插件重载存活(开机即装,非懒装)。

宿主能力(HTTP 接口层):

验证项结果
元数据解析5 个插件全部解析出中文名与说明;来源判定 github/community/linked/official 全部正确
安全卸载移除 → 校验确认 → 该插件路由端点随之失效(证明真 dispose)→ 记忆落盘
官方组件保护@deepseek-ai/* 卸载被拒,只允许停用
技能盘点完整性60 个技能;与独立文件系统扫描(57 个目录 / 14 个模型不可见)逐项吻合
预设作用域安装连续三次读取 installed=[standard,ptc,minimal,cordis] 稳定不变
解析根回退人为移除 profile 根的 @deepseek-ai/dsh-scope 后:旧代码 installed=[] 且报「不可解析」,新代码仍为 installed=[standard,ptc,minimal,cordis];恢复后无差异

实现说明

  • 零构建lib/*.js 既是源码也是产物,没有打包步骤,改完直接生效。
  • 文件职责lib/index.js 插件清单与 API;lib/skills.js 技能盘点、派生函数与覆盖 provider;lib/skill-overrides.js 可按预设单独装配的入口;lib/client.js 前端。
  • 宿主侧零依赖:只用 Node 内置模块。技能作用域需要 @deepseek-ai/dsh-scope动态解析并 import(不是静态依赖,保住装配可移植性),并依次尝试 profile 根与 DSH 安装根两个解析根。
  • 前端模块信封lib/client.js 按 DSH 的 client-modules 约定包成惰性 CJS 工厂(window.__ModuleLoader__.load({ id, factory })),模块体在首次物化时才执行。
  • React 取自 shell 的冻结模块表require('react') 即可,无需 import;但必须在模块作用域解析一次,放进组件体内会在渲染期炸掉整个 section。详见 docs/SLOT-CONTRACT.md
  • 注册值是函数组件SlotComponent<P> = (props) => ReactNode。返回 DOM 节点或 { render() } 对象会被 React 拒绝,并让官方插件页变成空白。
  • 持久化为什么不写 patch 层:bundle 装配会用自己的 id 组合出同名条目,patch 层的 disabled: 条目并不能可靠阻断它。因此状态由本插件自管,启动时重放。

权限与数据

说明
读取profile 的 node_modules(仅 package.json / README.md)、pnpm-lock.yaml、运行中的 loader 条目、技能注册表、技能指令文件所在目录(判断清理标记)
写入~/.dsh/plugin-manager.json(插件停用/卸载记忆)、~/.dsh/plugin-desk-skills.json(技能开关覆盖)
网络
凭据不读写

技能开关不修改任何 SKILL.md:状态由影子 provider 覆盖,删掉状态文件即完全复原。

HTTP 接口

界面之外,宿主能力也可直接调用:

方法路径说明
GET/dsh-plugin-desk/api/list插件清单(含中文名、说明、来源、状态)
POST/dsh-plugin-desk/api/toggle{ entryId, enabled } 热启停
POST/dsh-plugin-desk/api/uninstall{ entryId } 安全卸载
GET/dsh-plugin-desk/api/skills技能清单(含用法提示、来源、清理标记、presetInstall 诊断)
POST/dsh-plugin-desk/api/skills/toggle{ name, model?, user? } 设置技能开关
POST/dsh-plugin-desk/api/skills/reset{ name } 恢复该技能的默认策略

卸载本插件

dsh plugin --profile web remove dsh-plugin-desk

状态文件 ~/.dsh/plugin-manager.json~/.dsh/plugin-desk-skills.json 会保留;若不再需要,可自行删除。删除技能状态文件后,所有技能立即回到默认策略。

License

MIT