Alyosha28
dsh-plugin-updater
No description
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
@dsh-external/dsh-plugin-updater
English: README.en.md · 中文: 本文档
DSH 插件更新中心:自动追踪 DSH 环境中所有插件的版本,与 npm registry / GitHub releases 的最新版比对,把待更新插件以卡片形式展示(界面参考 CC Switch 版本更新 组件样式),一键执行「下载 → 完整性校验 → 替换 → 热重启」,失败自动回滚; 支持定期自动检查(可配置频率)并在发现新更新时站内通知(右上角铃铛)。
开源仓库:github.com/Alyosha28/dsh-plugin-updater · Topic:
dsh-plugin
能力总览
| 能力 | 说明 |
|---|---|
| 全量版本追踪 | 扫描 Cordis loader 的全部条目(178+),解析每个插件 package.json 的安装版本 |
| 最新版比对 | npm registry 优先;GitHub-only 包走 releases/tags/默认分支(API 限流时自动降级 git ls-remote,不耗配额) |
| 一键更新 | 下载(带进度)→ 完整性校验(npm sha512/sha1,GitHub gzip CRC + 包名/版本复核)→ 备份 → 替换 → 热重启 |
| 失败回滚 | 替换前完整备份;任何一步失败自动恢复旧文件并重建旧代 fiber |
| 热重启 | 清模块缓存 → 重新 import → registry 重建 fiber(生产验证的重载配方),含 client 模块 rev 补扫 |
| 定期自动检查 | 默认 6 小时(可配 1h/6h/12h/24h/7d),发现新更新写入站内通知(铃铛徽标) |
| 主动通知 | 右上角悬浮铃铛:未读通知数 + 待更新插件数徽标,弹窗列表 + 全部已读 |
| AI 工具 | dsh_plugin_update(check/status/update):AI 可代用户检查与更新插件 |
| 安全护栏 | 默认不更新 DSH 托管核心包(allowCoreUpdates 可放开);源码链接(link/junction)安装不原地更新;拒绝自更新;变更 API 带同源校验 |
界面(参考 CC Switch)
- 设置 → 插件更新 页面:卡片网格,每卡 = 插件图标 + 名称 + 状态徽标 (黄「可更新」/ 绿「已是最新」/ 红「检查失败」)+ 当前/最新版本行 + 来源标签(npm/GitHub/DSH 托管/源码链接)。
- 发现更新时顶部出现品牌色横幅「发现 N 个可更新的插件」,工具条出现 全部更新(N) 按钮;每张卡右下角有醒目的 更新 按钮。
- 更新中:按钮切换为进度条(阶段 + 百分比 + 明细),完成后卡片变绿、 顶部浮出成功/失败 toast。
- 页面底部为自动检查设置:频率、通知开关、核心包开关。
更新管线(每插件)
resolveInstalled(profile package.json)
→ 最新版解析(npm → GitHub releases/tags → 默认分支 package.json)
→ 下载 tarball(全阶段超时 + 进度回调)
→ 校验:npm=sha512/sha1 integrity;GitHub=gzip CRC + 解包后包名/版本复核
→ 系统 tar 解包(500MB 上限)
→ 备份旧目录(保留嵌套 node_modules)
→ 替换文件(依赖变化时 npm install,含 lifecycle 脚本时 npm rebuild)
→ 复核落盘版本
→ 热重启(purge loadCache → import → registry 重建 fiber,失败自动恢复旧代)
→ 失败任意一步:恢复备份 + 重建旧代,明细写入任务步骤
架构
src/
├── index.ts host 入口:Config schema + HTTP API 路由 + dsh_plugin_update 工具
├── service.ts PluginUpdaterService:检查/更新/配置/通知/定时器/热重载
├── registry.ts npm/GitHub 最新版解析 + 安装位置解析 + repo 推导
├── updater.ts 下载/校验/解包/备份/替换/npm 子进程
├── notify.ts 站内通知存储(~/.dsh/storages/dsh-plugin-updater/)
├── semver.ts semver-lite 比较(v 前缀/预发布/build 元数据)
├── types.ts 共享数据契约
└── client/ Web UI(tsdown → lib/client.js,window.__ModuleLoader__ 包装)
├── index.ts settings.section 注册 + locale + 铃铛挂载
├── section.tsx CC Switch 风格更新面板
├── badge.tsx 右上角通知铃铛(与 memory-evolve 铃铛自动错位)
├── api.ts /dsh-plugin-updater/api/* 客户端
└── styles.ts DSW 设计 token(--dsw-alias-*)样式,深浅色自适应
HTTP API(同源):
GET /dsh-plugin-updater/api/state 全量状态(检查结果/任务/通知/配置)
POST /dsh-plugin-updater/api/check 触发一次检查
POST /dsh-plugin-updater/api/update 启动更新任务 {names:[...]} → {taskId}
POST /dsh-plugin-updater/api/config 更新配置 {patch:{...}}
GET /dsh-plugin-updater/api/notifications 通知列表
POST /dsh-plugin-updater/api/notifications/read 全部已读
配置
| 字段 | 默认 | 说明 |
|---|---|---|
| checkIntervalMs | 21600000(6h) | 自动检查间隔(≥60s) |
| notifyNewUpdates | true | 发现新更新时写站内通知 |
| allowCoreUpdates | false | 允许更新 DSH 托管核心包(危险) |
| profileDir | 自动探测 | 可更新范围 = 该 profile 的 node_modules |
| githubToken | 空 | GitHub token(env GITHUB_TOKEN 亦可用,且不落盘) |
| fetchTimeoutMs | 30000 | 单个请求超时 |
配置持久化于 <DSH_HOME>/storages/dsh-plugin-updater/config.json;通知与
已通知版本记录同目录。
构建与安装
# 构建(Windows 原生):junction 依赖 → tsc(host)→ tsdown(client)
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\build.ps1
# 或 bash scripts/build.sh(WSL 下自动委托 build.ps1)
# 安装进 profile(本机 DSH)
# 通过 DSH 的 dev_install_package 热装配(改 profile package.json + bundles + junction + loader.create)
已验证(实测记录)
- ✅ 全量扫描 178 个 loader 条目,npm/GitHub 解析无假阳性(含 tag 与 package.json 版本方案不一致的仓库)
- ✅ 端到端更新:0.0.0-beta.1 → 0.0.1(GitHub codeload 源,下载/校验/解包/替换/复核全链路)
- ✅ 带活跃 fiber 的插件热重启(dsh-vision 更新后 fiber [active]、工具完好)
- ✅ 自动检查 → 站内通知(铃铛徽标计数/弹窗/全部已读)
- ✅ UI 按钮更新流(可更新 → 进度 → 已是最新 + toast)
- ✅ GitHub API 限流下自动降级 git ls-remote;跨站请求 403;并发更新 409
已知限制
- GitHub 仓库无 tags/releases 时以默认分支 package.json 版本为准(分支即发布通道)。
- 依赖发生变化的更新会触发 profile 目录
npm install --no-save(尽力而为, 网络失败时该步骤报错并回滚文件)。 - 更新器自身拒绝自更新(防自毁);请用 DSH dev 工具或手动更新它。