# dsh-plugin-updater [English](README.md) | 简体中文 **面向 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的包级插件管理器,带更新检测。** 它在 DSH Web UI 中新增 **设置 → 插件包** 页面:列出当前 profile 已安装的全部插件包, 显示**已装版本与最新版本**,并支持一键**安装 / 更新 / 卸载** —— 相当于给 `dsh plugin`(一个 pnpm 前转器)配上了浏览器管理界面。 这是社区插件,不是 DeepSeek 官方包。它管理的是 profile 的**安装态**(npm 包与 `dsh.profile.bundles` 层列表);运行时的 Loader 条目启停请使用 [`dsh-plugin-manager`](https://github.com/hrhgit/deepseek-harness-plugin-manager), 两者互补。 ## 功能 - 列出当前 profile 的每个依赖:已装版本、来源(npm / Git / 本地 / 内置)、 是否为已激活的 bundle 层(`dsh.profile.bundles`)。 - 按来源**检测更新**: - **npm** —— 已装版本对比 `pnpm view dist-tags`(在 profile 目录内执行, 因此沿用所配置的 registry 与凭据)。 - **Git**(`github:owner/repo`、`git+…`、`…#ref`)—— 从 profile lockfile 读取 已装 commit,对比 `git ls-remote `;仓库有 tag 时显示最新语义化 版本号。 - **本地**(`link:` / `file:`)—— 对 origin 的方向感知检测:先对比检出目录 本地 `HEAD` 与 `git ls-remote origin HEAD`,不一致时再 fetch 并用 `rev-list --count` 判断方向 —— origin 领先才算「可更新」;本地领先(有 未推送提交)不报更新;分叉则提示手动处理。 - **内置** `@deepseek-ai/*` bundle —— 显示版本,随 dsh 安装一起更新。 - 一键**安装**(任意 pnpm 规格)、**更新**(npm 用 `@latest`,Git 重新拉取 记录的规格)、**卸载**:均在 profile 目录内执行 `pnpm add/remove`,随后执行与 `dsh plugin` 相同的 bundle 对账(解析到声明 `dsh.bundle.patch` 的包加入层列表, 被移除的离开)。 - 页面分为两个页签:**商店**(即下方插件市场)与**已安装**(已装插件列表、 手动安装输入框和操作日志);两个页签都保持挂载,切换不丢失搜索结果。页面 默认停在「已安装」,插件市场只在首次切到「商店」时才请求 GitHub(匿名搜索 配额仅 10 次/分)。 - **插件市场** —— 搜索 GitHub 上带 [`dsh-plugin` 话题](https://github.com/topics/dsh-plugin) 的仓库(排除 fork), 可按相关度 / Star 数 / 最近更新排序并翻页,任何结果都能直接以 `github:owner/repo` 依赖安装;已存在于 profile 中的仓库会标注“已安装”。 搜索结果缓存约 5 分钟;配置 `DSH_GITHUB_TOKEN`(或 `GITHUB_TOKEN` / `GH_TOKEN`) 可提高 GitHub 匿名搜索配额。 - **构建脚本闸门** —— pnpm ≥ 10 默认拒绝运行未加白的包安装脚本(profile 里 存在「已忽略构建」的包时,任何安装/更新都会硬失败)。安装/更新被这样拦截时, 页面会给出显式的**「允许构建脚本并重试」**按钮:把 pnpm 建议的 `allowBuilds` 条目写入 profile 的 `pnpm-workspace.yaml` 并重跑安装。允许即同意运行该包的 安装脚本——请只对信任的仓库开启。 - 实时操作日志,以及明确的“重启 dsh 后生效”提示 —— profile 层在启动时组合, 修改需要重启生效。 - 检测结果缓存(约 10 分钟)于 `~/.dsh/plugin-updater.json`;不在后台轮询 registry。 ## 安装 ```sh dsh plugin --profile web add github:hyqhyq3/dsh-plugin-updater dsh --profile web # 重启后打开 设置 → 插件包 ``` 或从本地检出安装: ```sh dsh plugin --profile web add link:/path/to/dsh-plugin-updater ``` ## 工作原理 - **Host 半 `lib/index.js`** —— 自动定位自身所在的 profile(其 `node_modules/dsh-plugin-updater` 实路径等于本包目录;可用 `DSH_PLUGIN_UPDATER_PROFILE` 覆盖),读取安装态(`package.json`、 `node_modules/*/package.json`、`pnpm-lock.yaml`),执行更新检测 (`pnpm view`、`git ls-remote`),并在 GUI webserver 上提供同源 JSON API `/plugin-updater/api/*`。变更操作在 profile 目录内 spawn `pnpm`,随后重新执行 bundle 对账。 - **Client 半 `lib/client.js`** —— 手写的模块工厂,注册设置页分区,每 3 秒轮询 `/api/state`。界面通过 `updater` locale 命名空间(`zh` / `en`)跟随 DSH 的**设置 → 通用 → 语言**;插件没有独立的语言设置。服务端生成的消息 使用相同语言,外部工具输出保持原样。API 请求携带 `?lang=zh` 或 `?lang=en` (缺失或无效时默认 `zh`)。升级时会一次性丢弃旧版检测缓存。 HTTP API: | 方法 | 路径 | 用途 | |---|---|---| | GET | `/plugin-updater/api/ping` | 存活探测 + 已定位的 profile | | GET | `/plugin-updater/api/state` | 插件列表、版本、检测结果、操作状态 | | GET | `/plugin-updater/api/search` | 插件市场搜索(`?q=&sort=best\|stars\|updated&page=&per_page=`) | | POST | `/plugin-updater/api/check` | 重新检测更新(`{name?}`) | | POST | `/plugin-updater/api/install` | `pnpm add ` + 对账 | | POST | `/plugin-updater/api/update` | `pnpm add @latest` / 重拉规格 | | POST | `/plugin-updater/api/remove` | `pnpm remove ` + 对账 | 纯 ESM JavaScript,零依赖(仅 Node 内置模块;要求 Node `^22.19 || >=24`、 PATH 上有 pnpm,Git 检测需要 git)。无构建步骤 —— `lib/*.js` 即所见即所得。 ## 限制 - 任何修改都需要重启 dsh 才生效(页面会给出提示);不会隐式重载运行中的进程。 - 管理器拒绝在页面里卸载自身 —— 请使用 `dsh plugin --profile remove dsh-plugin-updater`。 - Git 包的更新检测固定在规格的 ref 上(`#ref` 或默认分支 `HEAD`);tag 移动不视为 更新。 - `link:` 安装的目标目录没有 `.git` 时只列出、不检测。 - 插件市场使用 GitHub 公共搜索 API:无 token 时限额 10 次/分钟(结果缓存约 5 分钟以延长可用性);配置 `DSH_GITHUB_TOKEN` 可提高配额。 - 只管理 profile 清单的 `dependencies`;运行时 Loader 条目启停不在范围内。 ## 模型体验 无。本插件不增加任何面向模型的能力:不注册工具、不注入提示词上下文,只服务于 设置页面与其 JSON API。 ## 许可证 MIT