插件分发、Release 命名与更新策略
状态:产品规范(2026-08-01)
安装通道:GitHub · 本地 ZIP · 本地文件夹
实现跟踪:Serpent-u3nx(Release asset + 平台 匹配)、Serpent-8r91(更新提示与自动更新)
1. 安装通道(产品面)
| 通道 | 用户操作 | Serpent 行为 |
|---|---|---|
| 本地文件夹 | 选择已构建的插件目录 | 校验清单与 runtime.entry 后拷贝进安装根 |
| 本地 ZIP | 选择符合规范的 .zip | 解压后同上校验 |
| GitHub | 粘贴 https://github.com/owner/repo 或 Release 页 URL | 优先取匹配当前平台的 Release asset ZIP;不得默认对源码 zipball 跑 npm install/build |
三条通道装入后的包形态必须相同:成品包(见 §3),不是未构建源码树。
本地「源码目录 + 现场 npm」不做:用户路径仅为成品包三通道。
1.1 设置页安装流程
设置 → 插件 → 安装插件 只保留两个入口:
- 本地安装:打开系统选择器,选择已构建的插件文件夹或
.zip压缩包。 - 从 GitHub 安装:进入独立页面,输入完整 GitHub 地址或
owner/repository。页面会显示解析、下载和安装阶段;下载阶段支持暂停、继续和停止。关闭按钮会停止当前下载并关闭面板。
GitHub 下载失败、仓库不存在、没有当前平台 Release 包或插件包校验失败时,安装页面会保留可读的失败原因;不会把本机绝对路径显示给 Renderer。
自动更新是「设置 → 插件」总览区的设备级开关。开启后,支持规范 GitHub Release asset 的插件统一参与兼容更新检查;新安装的 GitHub 插件也继承该策略。关闭后不再自动下载,仍可使用插件卡片上的手动更新按钮。
1.2 安装目录与版本替换
每个安装范围内,一个插件 ID 只有一个活动目录:
userData/plugins/<pluginId>/
{library}/.serpent/plugins/<pluginId>/
当前版本、来源和包哈希只记录在插件清单与对应 lock 文件中,不再使用
<pluginId>/<version>/ 作为活动包路径。安装新版本时先完成 staging 与完整校验,再原子替换该插件 ID 的活动目录和 lock;失败时保留旧目录。
这意味着同一安装范围不保留多个可切换的本地版本,插件管理器的本地
rollback 在覆盖安装后会明确返回“没有上一份已安装包”。需要回退时,重新安装旧版本 ZIP/目录即可;如果当前设备的 Resolution 仍指向旧包哈希,Host 会要求用户显式选择新包,不会静默启用替换包。
2. 平台标识(判定与命名共用)
与 Electron / Node process.platform + process.arch 对齐(清单 nativeModules 已用同一套):
| 规范 token | 含义 | Node 对应 |
|---|---|---|
darwin-arm64 | macOS Apple Silicon | darwin + arm64 |
darwin-x64 | macOS Intel | darwin + x64 |
win32-x64 | Windows 64 位(常见) | win32 + x64 |
win32-arm64 | Windows on ARM | win32 + arm64 |
win32-ia32 | Windows 32 位(可选维护) | win32 + ia32 |
linux-x64 | Linux x86_64 | linux + x64 |
linux-arm64 | Linux aarch64 | linux + arm64 |
any | 无原生二进制、全平台同一 ZIP | — |
口语文案映射(UI 可用,文件名必须用规范 token):
| 口语文案 | 规范 token |
|---|---|
| Mac Apple Silicon / M 系列 | darwin-arm64 |
| Mac Intel | darwin-x64 |
| Windows x64 | win32-x64 |
| Windows ARM | win32-arm64 |
| Windows x86(32 位) | win32-ia32 |
安装与更新时:先匹配 platform-arch 精确 asset;若无则尝试 any;再无则失败并提示缺少本平台包(不得静默下载错误架构)。
无限制插件若声明 runtime.nativeModules,还须与当前 nodeAbi 兼容(既有兼容性校验保留)。
3. 成品包内容(ZIP 内 / 文件夹内)
根目录(或 ZIP 解压后唯一顶层目录)须含:
serpent-plugin.json
README.md
LICENSE
<entry 指向的已编译 JS> # 如 entry/main.js 或 dist/main.js
[可选 ui/ 等清单声明文件]
[可选:已捆绑的 node_modules 或原生 .node,按平台 ZIP 分流]
禁止依赖用户机器现场执行 npm install / npm run build 才能通过校验。
3.1 ZIP 条目路径
Host 用 adm-zip 读取 ZIP,不在 Windows 上提供 zip 命令。条目名必须是相对 POSIX 路径:
- 使用
/分隔目录,例如entry/main.js。 - 不要使用
\、盘符、前导/、..。 - 不要把当前目录写成路径段:
./serpent-plugin.json会被旧版 Host 拒绝(PLUGIN_ARCHIVE_INVALID:absolute or traversing path)。当前 Host 会去掉./并把\换成/,但发布包仍应写出不含这些前缀的路径。 - 允许 ZIP 内有且仅有一层包裹目录(
my-plugin/serpent-plugin.json);解压后会剥掉该前缀。 - 禁止符号链接。
Windows 上 tar -a -c -f out.zip -C dist . 会稳定写出 ./ 前缀;Compress-Archive 可能写出反斜杠。不要依赖这两条命令直接作为 Release 产物。打包方式见 最佳实践 §8。参考实现:Serpent-Plugin-ImageUpscaler。
4. GitHub Release 结构与 asset 命名
4.1 Release
- 使用 GitHub Release(建议 tag = 清单
version,如1.2.0或v1.2.0,安装器应接受可选v前缀)。 - 每个需要原生/平台分流的版本,为每个支持的平台上传一个 ZIP asset。
- 纯 JS、无原生依赖:可只上传一个
…-any.zip。
4.2 Asset 文件名(强制)
{pluginId}-{version}-{platformToken}.zip
规则:
pluginId:与清单id完全一致(小写、点分,如com.example.image-upscaler)version:SemVer,不含前导v(如1.2.0);Release tag 可为v1.2.0platformToken:§2 规范 token(darwin-arm64、win32-x64、any等)- 仅允许字符:
[a-z0-9._-];整名大小写敏感,发布时用小写
示例:
com.example.image-upscaler-1.2.0-darwin-arm64.zip
com.example.image-upscaler-1.2.0-darwin-x64.zip
com.example.image-upscaler-1.2.0-win32-x64.zip
com.example.image-upscaler-1.2.0-win32-arm64.zip
com.example.palette-tools-2.0.1-any.zip
推荐另附 SHA256SUMS(或每个 zip 旁 .sha256);实现阶段可先做文件名匹配,哈希校验作为增强。
4.3 仓库 URL 解析优先级
用户粘贴 GitHub 相关 URL 时,建议顺序:
- Release / tag 页 → 解析 owner/repo + tag → 列 assets → 选平台 ZIP
- 仓库根 URL → 取 最新稳定 Release(非 draft/prerelease,除非用户显式选预发布)→ 同上
- 兼容回退(过渡期):若 Release 无规范 asset,但 tag/默认分支 zipball 内已有成品包,可继续旧行为并提示作者迁移到 Release asset(过渡结束后可移除)
不默认执行:对源码归档跑 package manager。
5. 更新显示与自动更新
仅对 来源为 GitHub 且能解析到规范 Release asset 的安装生效。本地文件夹 / 本地 ZIP 不自动检查远端(用户可重新选择文件覆盖安装)。
5.1 显示更新
设置 → 插件列表中,对 GitHub 安装的包:
- 定期或打开设置时检查:是否存在更高 SemVer 的 Release,且含当前平台(或
any)asset - 若有:显示「有可用更新:
{newVersion}」与「更新」按钮 - 更新前复用既有 来源/权限/运行时模式变更 确认;包哈希变化时资源库插件需按信任规则处理
5.2 自动更新(可选勾选)
-
默认:关闭
-
勾选前必须展示风险说明(阻塞确认),文案要点:
- 将从 GitHub 下载并替换本机插件代码,可能引入恶意或不兼容变更
- 新版本可能提升权限、改为无限制模式或附带原生模块
- 网络与 GitHub 可用性影响更新;失败时保持旧版本
- 自动更新不会跳过本机信任与高风险确认(若策略要求仍弹窗,则自动更新只负责下载,启用前仍确认)
-
策略建议(实现默认):
变更类型 自动更新行为 同权限、同 runtime.mode、SemVer 补丁/次要 可自动下载并在下次开库切换(或空闲时切换) 权限增加 / runtime.mode 变更 / 源变更 不得静默启用;改为「待确认更新」通知 主版本或破坏性 同上,强制确认 -
设备态保存:
updatePolicy: follow-latest | pinned可扩展为显式autoUpdate: boolean(pinned 时强制关闭自动更新)
5.3 与 Safe Mode
Safe Mode 只停用无限制插件;自动更新检查可继续,但不得在 Safe Mode 下激活新装的无限制包。
6. 作者发 布检查清单
npm ci && npm run build(或等价)产出成品目录- 按平台打 ZIP(原生依赖必须打进对应平台包,勿假设用户有编译链)
- 抽查 ZIP 条目为相对 POSIX 路径,无
./、\、.. - 按 §4.2 命名并上传到 GitHub Release
- 清单
version与 Release tag / 文件名 version 一致 - 无限制插件填写正确的
nativeModules(platform/arch/nodeAbi) - README 写明支持的平台 token 列表
- Unix 可执行文件不要假设解压后仍有执行位;运行时按需
chmod
7. 实现分期
| 阶段 | 工单 | 内容 |
|---|---|---|
| 1 | Serpent-u3nx | GitHub 安装改读 Release assets;平台 token 匹配;文档与校验错误码;过渡期 zipball 回退 |
| 2 | Serpent-8r91 | 设置页「有可用更新」;手动更新;自动更新勾选 + 风险文案 + 权限升级阻断静默 |
| 后续 | — | SHA256 校验、prerelease 开关(不做源码目录 npm) |
Serpent-upsn.9(打包/最终 QA)仍排在平台收口最后,不阻塞本规范文档落地。