dsh-plugin-packs:把已装插件排成两栏的包管理器

前言

DSH(DeepSeek Harness)的插件机制不算复杂,难的是装多了之后的事。插件到几十个以后,问题不再是「哪个插件叫什么」,而是「我现在到底开着什么」。官方插件页给的是一张平铺的已安装清单,启用和停用的都在里面,只能靠记忆区分:装的时候顺手打开,用的时候忘了关,是常见状态。

下面介绍的 dsh-plugin-packs 解决的就是这个视角问题。它由 mmmmlp-cloud 维护,MIT 协议,当前版本 0.1.0,在社区目录中归为「工作流」分类。它把已安装数据重排成 Minecraft 资源包式的左右两栏(左栏正在用、右栏装了没启用),再叠一层可手工编辑的标签。仓库还比较新,公开星标数为 0,适合愿意先试用再反馈的用户。

这是什么

一句话定位:一个 DSH 插件包管理器,用两栏视图回答「这个包现在开没开」,用标签回答「它算哪一类」。

它不是卸载工具,也不是插件分组工具。区别在于视角:分组类插件回答「它属于哪一类」,组织方式是用户自定义层级;本插件回答「它现在在不在跑」,左栏是当前 profile 的 bundle 选择,右栏是闲置的包。两者可以同时安装,彼此不写同一份数据。

核心功能

装好后,插件在左侧栏「插件」页面顶部新增「插件包」标签页,能力如下:

  • 两栏视图:左栏「已启用 · 一起用」,右栏「未启用」。卡片为正方形,每栏一行两个。
  • 搬包:点卡片右上 → / ← 箭头,或直接拖到对面一栏,即完成启用/停用。
  • 批量操作:勾选多张卡片后,顶部浮出「批量启用 / 批量停用」。
  • 标签:卡片可挂自定义标签;顶部标签栏点一下即筛选,再点取消;「未标记」捞出还没归类的包。
  • 搜索:匹配中文名、包名、描述、版本和标签。
  • 范围筛选:默认只显示用户自己安装的包;可选官方可选包、全部;勾「显示系统核心」才露出只读区。
  • 详情展开:展开可看完整描述、来源、包内插件行及运行状态,并改中文名、勾标签。
  • 切换反馈:每次切换后提示区分四种结局:已生效 / 需重启 DSH / 被更高优先级覆盖 / 失败:<code>,前两种支持撤销。
  • 会话记忆:访问过一次「插件包」页后,本次会话内切走再回来,仍停在该页。

安装与启用

安装通过 DSH 官方 CLI 完成,指定 --profile web(浏览器 half 需要挂在 web profile 上):

# 官方 CLI:走 pnpm 安装并选中 bundle
dsh plugin --profile web add github:mmmmlp-cloud/dsh-plugin-packs

装完重启一次 dsh web(宿主 half 要挂路由),再按 Ctrl+F5 强刷页面,入口在左侧栏「插件」→ 顶部「插件包」。

注意 DSH 有两个都叫「插件」的入口:左侧栏是插件总页面,「设置 → 插件」是另一个面。本插件挂在前者,排错先确认这一点。

数据存在哪里

标签和中文名不写在浏览器 localStorage,而是写在一个普通 JSON 文件里,随 DSH_HOME 走:

<$DSH_HOME>/plugin-packs/packs.json
# 默认路径为 C:\Users\<用户名>\.dsh\plugin-packs\packs.json

文件格式:

{
  "version": 1,
  "tags": [{ "id": "novel", "label": "小说 · 阅读", "color": "#7B68EE" }],
  "packs": {
    "dsh-novel-writer": { "name": "小说写作助手", "tags": ["novel"] }
  }
}

要点:

  1. packs 的键是包名而不是 entry id,重装、升级、换目录 id 都不丢标签。
  2. 文件不存在时生成空表,附带 7 个通用分类标签(小说·阅读 / 联网搜索 / 界面美化 / 安全·渗透 / 模型渠道 / 记忆·知识 / 工具·其它)。出厂不预填任何包和归属,哪个包打哪个标签由用户决定。
  3. 可以直接手改,刷新即生效;格式写错不会静默丢数据,坏文件先改名留底(packs.json.broken-<时间戳>)再重建。
  4. 写入是原子写(临时文件 + rename)且串行化,连续点击标签不会互相吞更新。
  5. 只涉及插件包,不碰会话、提示词或凭据;换机器不随账号同步,要手工拷贝。

它改的是哪一层

「启用/停用」调用内核的 pluginManager.setBundleEnabled,把包加入或移出 profile 的 bundle 选择层,改的是真实插件状态,不是页面显示:依赖仍留在 node_modules,随时可以移回,不是卸载;由上层配置接管(只读)的包会明确标出,不会假装可切。

包内单个 loader 行的开关不在本插件职责内,本页包内行列表是只读展示;需要行级管理要配专门的行级工具。

范围上有保护:勾「显示系统核心」才露出 dsh-base / dsh-web-app 以及 acp、headless、sdk-app、sdk-minimal 这几种别的运行模式的包,一律不可切,避免误触改坏桌面档。未安装(availability === "missing")的包不显示。

架构与接口

包分宿主 half 和浏览器 half,零运行时依赖、无构建步骤。浏览器端数据走宿主 half 的同源路由,可用 curl 单独验证:

方法 路径 说明
GET /plugin-packs/api/health 自检:build 标记、路由、数据文件路径
GET /plugin-packs/api/bundles 包清单与行状态
POST /plugin-packs/api/bundles/enabled 整包启停,body { name, enabled },需 x-plugin-packs: 1 头
GET/PUT /plugin-packs/api/state 读 / 整份替换写入标签文档,PUT 需 x-plugin-packs: 1 头

这样做是因为浏览器直接调 ctx.remote.pluginManager 要接客户端远程装配顺序,容易在启动竞态里静默失败;走宿主路由不受影响。写操作带自定义请求头且路由不答预检,别的本地页面无法借道改插件状态。

排错先看自检接口:

curl 127.0.0.1:<端口>/plugin-packs/api/health

build 字段存在即路由正常;页面报 HTTP 404 / 响应不是 JSON 时,通常是改了宿主代码未重新应用 bundle 行,重新开关一次即可,不必重启 DSH。

适用场景与注意

适合插件数量在几十个量级、习惯按用途分类管理包、愿意把分类放进可手改文件的用户。标签跟着 DSH_HOME 走,换浏览器或清站点数据都不会丢。

留意几点:

  1. 插件以当前 dsh 进程权限运行,能读写该 profile 能访问的所有插件包,安装前建议先读源码与许可证(MIT)。
  2. 它只管到包这一层,包内行级开关需另找行级工具。
  3. 官方「已安装」标签本身无法替换,本插件以并列标签提供另一种视角,两者共存。
  4. 个别包(尤其宿主侧插件)切换后需重启 dsh web 才完全生效,页面会明确提示。

结尾

dsh-plugin-packs 做的事情很小:把已有的插件清单重排成日常语言——两栏、标签、搜索、批量。没引入新的安装方式,也没改内核语义,只是把「我现在在跑什么」从记忆问题变成可见事实。如果这正是痛点,可以从社区目录页开始试用:

  • 目录页:https://www.skillhub.cn/plugins/mmmmlp-cloud/dsh-plugin-packs
  • GitHub:https://github.com/mmmmlp-cloud/dsh-plugin-packs
羽毛球分组比赛记分
小程序二维码

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

小夜