Skip to content
dsh.fish
Bundle

dsh-plugin-doctor

DSH 插件管家:审计已安装插件的规范性与安全隐患(manifest 契约、patch 层、静态代码、供应链),设置面板提供插件列表(中文描述、安装时间、版本更新)、热启停与可靠的安装/卸载。

Source
Oo0520
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-plugin-doctor

DSH(DeepSeek Harness)插件管家:审计已安装插件的规范性与安全隐患,并在设置面板中提供插件管理(启停、安装、卸载、版本更新)。

## 功能

### Host 工具(对话中由 AI 调用)

| 工具 | 用途 | 副作用 |
|---|---|---|
| `plugin_audit` | 审计 profile 全部 bundle:manifest 契约、patch 层风险、静态代码扫描、供应链风险 | 只读 |
| `plugin_list` | 列出 loader 组合行与 fiber 运行状态(PENDING 缺失服务 / FAILED 错误) | 只读 |
| `plugin_toggle` | 热启用/禁用插件:loader 运行时即时生效 + 写 profile `cordis.patch.yml` 持久化(HMR 自动应用) | 改运行状态 + patch 文件 |
| `plugin_uninstall` | 卸载插件包(`dsh plugin remove` 转发 pnpm),带 dry-run 确认 | 删除依赖,需重启 |
| `plugin_install` | 安装插件包(`dsh plugin add` 转发 pnpm) | 需重启 |

### 设置面板(Web 客户端)

设置 → 插件体检,包含「插件管理」与「体检报告」两个视图:

- **插件列表**:运行状态、版本、中文功能描述(内置词典 + 包描述兜底,可自维护外部词典)、安装时间(面板操作精确记录,历史安装按目录时间估算并标「约」)、7 天内新装标「新」徽章
- **搜索**:同时匹配插件名、ID 与中文描述
- **启停**:运行时热切换 + 持久化;禁用会先探测是否把其他条目晾成 PENDING(如停掉服务提供方),有则自动回滚并拒绝,避免下次启动报 "entries did not activate"
- **装卸**:面板直接安装/卸载社区插件;纯客户端插件(无 `dsh.bundle`)也能从孤儿 patch 行启用,重启后由市场挂载
- **版本更新**:查询 npm registry 对比本地版本,「更新到最新」一键升级,并识别 pnpm 发布冷静期(`minimumReleaseAge`)导致的更新假象
- **双语**:界面描述跟随 DSH 语言切换(中文优先中文词典,英文显示精简英文摘要)

## 卸载可靠性

卸载的成败以**清单是否还引用该包**为准,而不是 pnpm 退出码:即使 pnpm 因文件被占用中途失败(如插件自带常驻进程锁住其目录),也会强制收敛到一致状态——

1. 从 `package.json` 的 `dependencies` 与 `dsh.profile.bundles` 移除引用
2. 清理 `cordis.patch.yml` 中的残留 patch 行
3. 运行时停用其 loader 条目(刷新页面不 404),下次启动不再组合
4. 被锁而删不掉的残留目录单独提示,可手动删除,不影响系统运行

改写清单前自动备份为 `*.bak.plugin-doctor`。

## 审计规则

- **错误(需处理)**:manifest 指向不存在的文件、patch 非顶层数组、insert 行缺 id/name、`!!js` 表达式、patch 覆盖/冲突官方内置行、`eval`/`new Function`、读取 `.credentials.yaml`、解码执行类命令、安装期脚本(preinstall/postinstall)、bundle 目录无法解析
- **警告(建议关注)**:exports 缺 `./cordis.patch.yml`/`./package.json` 入口、client 声明不完整、直接依赖共享运行时(应 peer)、直接使用 `child_process`、遍历 `process.env`、非白名单硬编码外联地址、`prepare` 脚本、github 依赖未固定 commit、跨包覆盖未知行
- **提示**:高权限依赖(puppeteer/ssh2 等)、缺 version/description、`process.exit`

体检范围 = profile bundles 列表 ∪ 非官方 dependencies,新装插件立即可扫描。`@deepseek-ai/*` 官方内置包仅做 manifest 轻检(trusted),不扫代码。

## 安装

```sh
dsh plugin --profile web add dsh-plugin-doctor          # npm
dsh plugin --profile web add github:Oo0520/dsh-plugin-doctor   # github
```

(或本地路径 / tarball。)仓库已包含构建产物 `lib/`,github 安装无需构建脚本。

注意事项:

1. **pnpm 供应链冷却期**:pnpm 11 默认 `minimumReleaseAge`(约 24h)会拒绝当天新发布的包。被拦时可在命令尾部追加 `--config.minimum-release-age=0` 一次性绕过(不修改持久配置)。
2. **link: 安装形态**:本地路径安装生成 `link:` 依赖,Node ESM 从源目录真实路径向上解析依赖,因此源目录需自带 `node_modules`(`npm install` 即可)。npm/tarball/github 安装则无此要求。
3. **安装后重启 profile**。

## 开发

```sh
npm run build   # build:host(tsc)+ build:client(tsdown + 类型)
```

修改 `src/` 后重新 build 并重启 profile。

## 配置

- `profile`:目标 profile 名,默认 `web`;运行时会优先从 `ctx.baseUrl` 自动推断当前 profile。

外部描述词典:`~/.dsh/.plugin-doctor/descriptions.json`(`{ "包名": "中文描述" }`),优先级高于内置词典。

## 安全边界

- `plugin_toggle` 拒绝禁用官方内置行(fs/tools/webserver/loader 等)与 `plugin-doctor` 自身
- `plugin_uninstall` 拒绝卸载 `@deepseek-ai/*` 官方包与自身;默认 dry-run,必须 `confirm=true` 才执行
- 首次改写 profile `cordis.patch.yml` 前自动备份为 `cordis.patch.yml.bak.plugin-doctor`

Install

dsh plugin --profile web add github:Oo0520/dsh-plugin-doctor

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source