Appearance
发布规范
本文档说明插件打包格式、签名、分发渠道、更新与发布检查清单。
TIP
推荐用 qomicex CLI 完成打包 → 签名 → 发布全流程:qomicex pack 打包、qomicex verify --package 验签、qomicex publish 一键发布。完整命令见 CLI 工具参考。
一、打包格式
.qplugin 本质是 ZIP 压缩包,其中 manifest.json 必须位于根目录。
my-plugin.qplugin(即 zip)
├── manifest.json # 必须在根目录
├── signature.json # 签名(上传商店必须,见 §四)
├── signature.cert.json # 开发者证书(商店发布时附带)
└── dist/
├── index.html
├── app.js
└── theme.cssWARNING
manifest.json不在根目录 → 安装失败(Invalid plugin package)- 后端不校验扩展名,任何合法 zip 都能通过上传接口;但请统一使用
.qplugin以便识别 - 包内路径避免
../相对路径(zip-slip 风险,且可能导致文件写入异常位置) - 包内条目路径必须使用正斜杠
/(Windows 老工具生成的\会被安全校验拒绝)
WASM 插件(L3)打包
含 L3 能力的插件需在包内提供 plugin.wasm(wasmtime 核心模块):
my-wasm-plugin.qplugin(即 zip)
├── manifest.json # 必须在根目录,layers 含 "l3"
└── plugin.wasm # wasm 编译产物(wasm32-unknown-unknown)- 编译:
rustup target add wasm32-unknown-unknown && cargo build --release --target wasm32-unknown-unknown - 产物重命名为
plugin.wasm放入包根目录(网关按固定文件名plugin.wasm加载,无需在 manifest 声明路径) - manifest
layers需含"l3",permissions含"wasm:execute" - 详见 WASM 插件(L3)
主题内容(可选发布物)
主题、图标、字体是可选发布内容,通过 contributes 声明,不要求独立发布格式:
| 内容 | 声明位置 | 说明 |
|---|---|---|
| 主题 CSS | entry.theme | 激活时注入 <style data-plugin-theme> |
| 图标主题 | contributes.iconTheme | .qtheme 包内 icon-theme.json 路径 |
| 字体/连字 | contributes.fontLinks | 字体 CSS/CDN URL,激活时注入 <link> |
三者都作为 .qplugin 包内资源随包分发,无需单独打包。详见 主题系统。
二、命名规范
| 项目 | 规范 |
|---|---|
| 插件 id | 反向域名风格(如 top.qomicex.assistant、dev.example.helloworld),小写、点分、id 一经发布不要更改(它是安装目录名与依赖引用 key) |
| 插件名 | 简洁可读,如「AI 助手」 |
| 版本号 | 语义化版本 x.y.z,用于依赖匹配(见 版本语法) |
| 包文件名 | 建议 {插件id}.qplugin 或 {插件名}-{版本}.qplugin |
三、权限与安全规范
- 最小权限原则:只声明真正用到的权限。安装详情页会按风险分级展示(危险权限如
shell:execute、filesystem:write、plugin:install会醒目提示) - 不得在插件内硬编码密钥/凭据
- 访问外部网络建议走
proxyFetch(自带 SSRF 防护),而非直接内网请求 - 插件脚本默认运行在 iframe 沙箱(opaque origin),不要依赖全局变量跨插件共享
- 重计算请离开 UI 主线程(Web Worker / WASM / 后端代理),
qomicex verify会静态告警while(true)/setInterval无界循环
四、插件签名(Ed25519 三级信任链)
商店与启动器使用 Ed25519 三级信任链(ADR-050)防供应链投毒:
商店根钥 → 签发开发者公钥证书 → 开发者密钥签每个 release- 信任链:商店根钥签发开发者公钥(
signature.cert.json,内含开发者公钥 + 根钥签名)→ 开发者用私钥签包体(signature.json)。启动器内置商店根公钥,可完全离线验签。 - 签名格式:
signature.json(包内根目录):
json
{
"alg": "Ed25519",
"signedHash": "<sha256 hex>",
"signerKeyId": "<key id>",
"signature": "<base64 ed25519 sig>"
}signedHash= 规范化 manifest + 文件清单的 SHA-256:SHA-256(canonical JSON 的 { manifest: sha256(manifest.json 原始字节), files: [{path, sha256}] })。规范化 = 键序递归排序 + 无空白 JSON,保证可复现哈希。- 强制范围:商店新上传版本、启动器手动上传
.qplugin强制验签(缺签名或验签失败 → 422signature_invalid/ 拒绝安装);商店安装与本地开发目录安装不强制(老版本兼容,开发路径放行)。 - 降级兼容:老版本(无签名)已发布可继续安装,不强制重签。更换/泄露私钥后重新生成密钥对并上传新公钥即可,旧证书自动失效。
- 换根钥注意:商店更换签名根钥后,内置根公钥(CLI
signature.ts的STORE_ROOT_PUBLIC_KEY_B64、启动器plugin_signature.rs的ROOT_PUBLIC_KEY_B64、CLI 文档signing.md)必须同步更新,且所有旧证书签发的包验签失败、需重新qomicex publish换新证书。
签名工具
- 生成密钥对:
openssl genpkey -algorithm Ed25519 -out dev-key.pem,或node scripts/plugin-keygen.mjs generate(仓库内脚本) - 签名:
qomicex pack --key ./dev-key.pem(打签名的.qplugin),或qomicex publish一键走完设备流登录 → 上传公钥获证书 → 签名 → 上传 - 验签:
qomicex verify --package ./release/xxx.qplugin
五、安装方式
- 上传 .qplugin 文件:设置 → 插件 → 安装插件,选择
.qplugin/.zip文件(强制验签,无签名/验签失败被拒) - 商店在线安装:插件商店页面 → 安装(有签名则验签,无签名老版本放行)
- 目录安装(开发者调试):后端
POST /api/plugins/install,body{"sourceDir": "/path/to/dir"},直接指向含manifest.json的目录(不强制签名,plugins-dev/开发路径)
TIP
- 上传接口(upload)不做依赖检查;依赖检查仅在目录安装(install)与商店安装接口执行。发布前请确保依赖插件已随文档说明。
- 状态切换(启用/禁用)需要重启启动器后生效。
六、更新、升级与回滚
- 更新检查:启动器启动后静默轮询商店
POST /plugins/check-updates(按 launcher 版本 + 已装插件清单),有更新时在插件管理页显示升级按钮。 - 灰度放量:商店返回
rolloutPercent(0-100,缺省/100 = 全量)。<100时启动器按hash(slug@latestVersion) % 100 < rolloutPercent决定该用户是否看到升级提示,同一用户结果稳定。 - 遥测自动暂停:商店按 24h 错误上报计数对版本做灰度保护——某版本 24h 错误数超过阈值(默认 10)后,商店不再把该版本作为更新建议下发(已安装用户不受影响)。详见 灰度遥测。
- 升级流程:点击升级按钮 → 确认 → 走商店安装管线(下载 → SHA-256 校验 → 验签 → 覆盖安装)。
- 回滚快照:覆盖安装前旧目录会改名
plugins/{id}.bak-{version}快照;升级后插件异常可点「回滚」按钮恢复(POST /api/plugins/{id}/rollback)。PluginInfo.hasRollback标记是否有可用快照。 - 卸载:设置 → 插件 → 删除按钮(会删除
plugins/{id}/整个目录)。
七、发布渠道
早期「GitHub 仓库 + PR」分发模式已由线上商店取代,正式发布一律走线上商店 plugins.qomicex.top。
1. dev 本地安装(开发自测)
开发过程中直接把 .qplugin 上传启动器验证,或走 qomicex dev + 调试 harness(见 调试与热重载)。
2. 商店发布(正式渠道)
| 方式 | 流程 |
|---|---|
qomicex publish(推荐) | RFC 8628 设备流登录 → 上传开发者公钥获取证书 → 签名包体 → multipart 上传。一键完成,无需浏览器操作 |
| 网页手动上传 | 登录商店 → 升级为开发者 → 新建插件 → 上传新版本(须先用 qomicex pack --key <私钥> 签名,商店强制验签) |
- 自动发布:纯 L3 且无危险权限的包上传后自动发布,无需人工审核。
- 人工审核:其余(含 UI 层或有危险权限)进入审核队列,结果在版本列表查看。
- 更新版本时上传同名 slug 的新版本,商店做版本去重(409
version_exists)。
3. 自建镜像 / 私有注册表(开放注册表协议)
如果你需要为自己或团队搭建私有的插件分发源,开放注册表协议(详见商店侧边栏「开放注册表协议」)允许第三方实现兼容的镜像:
- 核心端点:只需实现
GET /registry、GET /plugins、GET /plugins/:slug、GET /plugins/:slug/versions/:version/download四个端点即可被启动器识别为可用源 - 下载双通道:镜像重传包体时必须原样保留
signature.json和signature.cert.json,不可重打包 - 发现机制:启动器设置
registryUrl可配置多源列表,主源不可达时自动回退 - 部署方式:Cloudflare Worker 复制(共享负载)、纯静态托管(只读)、或自建完整注册表(独立源)
详细实现指南见开放注册表协议。
八、数据与目录
插件可读写自己的数据(按插件 id 隔离):
{数据目录}/plugins/{插件id}/
├── manifest.json # 你的插件文件(安装时解包)
├── settings.json # getSettings/setSettings 读写
└── cache.json # setCache/getCache 读写数据目录位置:
- Windows:
%LOCALAPPDATA%\qomicex-launcher - Linux:
$XDG_DATA_HOME或~/.local/share - macOS:
~/Library/Application Support - 环境变量
QOMICEX_HOME可覆盖(便携模式)
九、发布检查清单
- [ ]
manifest.json在包根目录,JSON 合法 - [ ]
id唯一且不再更改,version语义化递增(可用qomicex bump patch|minor|major) - [ ]
permissions只含必要权限(可用qomicex verify校验最小化) - [ ] 依赖插件的
dependencies声明正确(必装/可选、版本范围) - [ ]
entry.frontend已声明(否则插件不被激活) - [ ] 页面/悬浮窗脚本未使用全局变量跨插件通信
- [ ] 主线程无
while(true)/ 无界setInterval(qomicex verify告警项) - [ ] 已用
qomicex pack --key签名,signature.json在包根目录 - [ ] 本地安装测试通过(上传 → 启用 → 重启 → 功能验证)
- [ ]
qomicex verify --package验签通过 - [ ] 若调用其他插件,已在文档说明前置插件名称与版本
- [ ] 若贡献了图标/字体主题,已在
contributes.iconTheme/contributes.fontLinks声明(见主题系统) - [ ] 发布后关注错误率(灰度遥测阈值默认 10/24h,见灰度遥测)
十、版本兼容建议
minLauncherVersion建议填写,虽然当前版本未强制校验- 插件 API 可能演进,发布时说明兼容的启动器版本范围
- 重大变更(方法签名、权限变化)建议递增主版本