packages/dsh-plugin-manager
zhu1090093659/dsh-web设置 → 插件 分区里的插件管理 Tab:从 npm/git 安装带进度、下次启动生效的启停开关、安装冲突对账可撤销、失败一键转交修复会话。
从 npm 与 GitHub 每日采集的 DSH 插件目录:一键安装、启停、更新与卸载;装前就给出 dsh 会拒绝的原因与豁免命令;安装前的事实(engines.dsh、依赖数、bin 名、安装脚本)、回滚与收藏。
下面两条路做的是同一件事,按读者是谁挑一条。
前置条件: Node.js。运行 harness 本身无需安装——上游文档的形式是
npx -y @deepseek-ai/dsh web。插件管理经由 dsh plugin,它会分别 spawn
dsh 命令和 pnpm——用一条命令装好两者:npm install -g @deepseek-ai/dsh pnpm,并用 dsh --version 和 pnpm --version 验证。
# dsh 在 PATH 上(全局安装)。必须钉版本号:pnpm 11 会拦下刚发布的新版本,
# 不写版本号的裸安装可能给你旧版。下面是当前版本——用
# `npm view dsh-plugin-shop version` 查最新值。
dsh plugin --profile web add dsh-plugin-shop@0.9.4
# 或全程走 npx,什么都不装:
npx -y @deepseek-ai/dsh plugin --profile web add dsh-plugin-shop@0.9.4
如果你用的不是 web profile,把它换成你自己的。然后重启一次 dsh——新加的 bundle 不会作用于
已在运行的进程——再打开
左侧栏里的 插件商店
进去是一片插件卡片货架,带搜索框。首次加载要联网读目录,可能要等几秒,期间由一层扫光骨架占位。
全程非交互,无提示、无需确认。--profile 是必填的——不给它,dsh plugin 会以
error: required option '--profile <name>' not specified 退出。
1. 确定 profile 名。 profile 是 $DSH_HOME/profiles 下的目录($DSH_HOME 默认
~/.dsh)。那里还会出现 node_modules,它不是 profile。
ls -1 "${DSH_HOME:-$HOME/.dsh}/profiles" | grep -v '^node_modules$'
2. 安装。 钉版本号——显式钉版本能绕过 pnpm 的发布冷却期,确定性安装本来也是 agent 路径的要点。
dsh plugin --profile <profile> add dsh-plugin-shop@0.9.4
3. 验证——这步别省。 第 2 步返回 0 只说明 pnpm 解析到了这个包,不代表 profile 会加载它。 要断言的是 bundle 列表:
dsh plugin --profile <profile> list --depth 0
dsh-plugin-shop 必须出现并带有已解析的版本号。想直接读清单也行,同一事实位于
$DSH_HOME/profiles/<profile>/package.json 的 dsh.profile.bundles。
4. 重启该 profile——dsh --profile <profile>,web profile 用 dsh web。启停已安装的
插件是热生效的;新增 bundle 不是。
| 你看到什么 | 含义 | 怎么办 |
|---|---|---|
error: required option '--profile <name>' not specified | 漏了 --profile | 补上,它没有默认值 |
装到的版本比 npm 的 latest 旧 | pnpm 11 会压住刚发布不久的版本 | 显式钉版本:dsh plugin --profile <p> add dsh-plugin-shop@<版本号> |
client bundles not found ... lib/client.js | 磁盘上那份没有构建浏览器半边 | 从 npm 安装而不是从源码 checkout,或在该 checkout 里跑 pnpm build |
dsh: pnpm not found on PATH — install pnpm to manage profile plugins | dsh plugin 转发给 pnpm,而 pnpm 缺失 | npm install -g pnpm |
no profile directory found above <path> | 插件定位不到自己的 profile | 请报告——这是由 ctx.baseUrl 解析的,不该失败 |
| 重启后标签没出现 | bundle 不在 profile 的 bundles 里 | 重跑第 3 步;若确实不在,说明第 2 步没走完 |
| dsh 会拒绝安装的插件,卡片上会说明原因 | 深色主题下的同一片货架 |
| 浏览与搜索 | 数千个插件,按 dsh-plugin 与 deepseek-harness 关键字从整个公共 npm registry 采集(外加把这些关键字用作 topic 的 GitHub 仓库);作者若自己声明了简介就用作者原话,并归入七个分类。货架可以按星标、最新上架或最近更新排序,后两种在卡片上标出日期;版本号会写明自己是什么:npm 版本、GitHub 发布还是 GitHub 提交。切回标签页会重新读取目录,最多每五分钟一次 |
| 安装 | 一次点击,没有对话框。本机 dsh 会拒绝的安装——harness peer 不被当前版本接受,或名字已被另一个已装插件占用——卡片会在按钮的位置显示红色标签并写明原因,peer 被拒时附上 dsh 自己的豁免命令。较长的红字折叠成两行,点「展开」看全文。安装失败时,会给出指向插件自己仓库的预填 GitHub issue |
| 启停 | 对已安装插件生效,无需重启。带浏览器半边的插件还需要刷新当前页面,商店会在需要时给出按钮 |
| 已安装状态 | 已安装的插件在卡片上显示「已安装」,目录有新版本时改为「更新」按钮,另有「卸载」按钮;顶部「已安装」筛选只看已装插件 |
| 体积与作者 | 每张卡片显示装上它会占多少磁盘,紧挨着发布账号——用的是 npm 自己的解包体积,所以和该包的 npm 页面对得上 |
| 滤掉跑不起来的 | 必需的组件你这套安装没有提供,或者作者声明支持的 dsh 版本、profile 跟你正在用的不符,这样的插件会被标为不兼容,类别栏末尾的筛选可以把它们从货架上拿掉。它不会隐藏名字已被别的安装占用的插件,也不会从「已安装」视图里减东西——那些卡片是唯一能说明问题、也是唯一能撤销它的地方 |
| 刷新 | 当卸载或启停已经在服务端生效、只是当前页面还停在旧状态时,商店提议刷新这个页面——不会自动刷新,因为刷新会丢掉进行中的工作 |
| 重启 | 插件的宿主半边没能热挂载时;以及它挂载成功、但插件带浏览器半边时——会话中途装上的插件,它的界面要重启 dsh 才进得了页面,所以商店直说,而不是给一个按了也不会变的刷新。提议前先讲清代价:页面会断开,进行中的工作会中断 |
| 自更新 | 搜索框旁显示商店自己的版本号,自动查 npm 有没有新版本,有则一键用钉死版本更新,随后照常重启 |
目录不是谁手工维护的名单。每天跑六步,其中两步是这个货架值得一读的原因:
dsh-plugin 或 deepseek-harness 的包全部过一遍,外加把这些关键字
用作 topic 的 GitHub 仓库。不需要提交,也没有排队。dsh.bundle
的是库,不是插件;没有许可证或仓库的无从审查;npm 上已废弃的直接出局;仓库来源还额外要求无构建
脚本、无 workspace: 依赖——这两样任一都会让安装在你机器上失败;名字跟热门包只差一两个字符
的会被扣住,等人核过才放。十七种记录在案的拒收理由,全是
机械判定,每条拒收都附一句作者能读懂的话。dsh.compatibility(如果有)。完整流程图在 仓库 README。
有一件事它没有做:没有任何一条收录被人读过。今天 verified.yml 是空的,全部条目都是社区
层。机械筛查不等于评审。
一个包里装了两半,两者之间的分界就是安全边界:
| 半边 | 入口 | 能触及 | 不能触及 |
|---|---|---|---|
| Host | dsh-plugin-shop | 网络(取目录并校验 sha256)、文件系统(缓存)、per-profile 互斥锁下的 dsh plugin add | —— |
| Client | dsh-plugin-shop/client | 仅九个 shop/* Remote 方法 | 网络、文件系统 |
攻破浏览器那一半,攻击者拿到的就是那九个调用,别无其他。
插件目录会从几个来源里挑最先响应的那个读:npm 包 dsh-plugin-shop-catalog(走你配置的 registry、npmmirror 或 npmjs),或者 https://LivXue.github.io/dsh-plugin-shop/v1/。几个来源的内容完全一致,之所以要赛跑,是因为不同网络到它们的快慢可以差出几百倍。设了 DSH_SHOP_CATALOG_URL 就不再赛跑,只读你指定的那个。
| 变量 | 作用 |
|---|---|
DSH_SHOP_CATALOG_URL | 只从这个地址读目录,不再在默认来源之间赛跑 |
每日从公共 npm registry 构建,以静态 JSON 发布:
/v1/index.json —— 指针,携带 schemaVersion、builtAt、收录数 count 与过滤数 rejected(上面的徽章实时读它们)和内容哈希/v1/plugins.<sha256>.json —— 数据,内容寻址,可无限期缓存指针足够小,适合轮询。在信任数据文件的任何一个字节之前,商店会先用指针里的 sha256 校验它。
出现在货架上不等于背书。
capabilities 只是作者对自己包的自述。v0 没有沙箱,界面也从不把这个字段渲染成一份被强制
执行的权限清单。verified 层的含义是有人读过那个确切版本;一旦发布新版本就降级为
verified-stale,评审记录仍钉在它当初对应的版本上——所以过一次评审,买不到后续每个版本的信任。
在 package.json 里加上采集关键字——"keywords": ["dsh-plugin"] 或
"keywords": ["deepseek-harness"]——然后发布;或者不走 npm:把关键字作为 GitHub 仓库的 topic,
并在仓库根放一个带 name 和 dsh.bundle 的 package.json——目录会收录该仓库并把默认分支的
commit 钉为版本。每日构建就会找到你,不需要向本项目提交任何东西。声明 dsh.catalog 段可以自己掌控分类、简介和 capabilities;不声明,目录会从
你的 npm description 推导一条 listing。
完整参考:docs/schema.zh.md。
Apache-2.0 © LivXue