manifest 清单详解
manifest.json 是插件的身份文件,位于 .qplugin 包根目录。它描述插件的元信息、权限、入口和扩展点。
推荐用 qomicex create <id> 生成合法 manifest 骨架(自动配好 id / layers / permissions / entry),再用 qomicex verify 校验合法性。本页讲解全部字段,方便按需调整。
完整结构
字段总表
entry 对象
若省略
entry.frontend,插件不会被激活(activatePlugin 只在 entry.frontend 存在时渲染并标记 active),因此无法注册方法或提供 UI。即使纯功能插件也建议提供一个空页面入口。唯一例外是纯 L3(wasm)插件:layers 只含 l3(不含 l2/l4)时 CLI 允许省略 entry(网关按固定文件名 plugin.wasm 加载),但这类插件同样没有页面入口、不会被激活渲染。
contributes 对象
插件自持 i18n(l10n)
manifest 顶层声明"l10n": "l10n"(包内目录,相对 .qplugin 根),目录内存:
key → string 映射。manifest 的显示字符串用 %key% 引用词条(如 "name": "%plugin.name%"、installModes 的 label/description),宿主在加载清单时按启动器当前 locale 解析(locale 包缺失的 key 回退默认包,再缺失回退 %key% 原文)。插件运行时 UI 经桥取同一份包:
icon 字段规范(菜单 / 安装方式 / 顶层图标)
按优先级选择:- Font Awesome 类名(推荐):
"fa-solid fa-server"。零资产、跟随主题色(currentColor 渲染)、启动器内置解析(侧栏、安装对话框统一渲染)。- 可用类名不要硬编码:内置表随启动器演进。运行时取全量用
call('listIcons'),离线查表见@qomicex/plugin-ui导出的ICON_NAMES。 - 表外类名会渲染为空白(曾被静默忽略)。
qomicex verify/lint会静态校验并报 error,同时给出相近的内置图标建议。 - 插件页面内的图标不要调用
getIconSvg,用<Glyph>+ 单图标子路径(见 插件 API — 图标)。
- 可用类名不要硬编码:内置表随启动器演进。运行时取全量用
- 包内相对路径:
"dist/icon.svg"(多色/品牌图标用;自动解析为插件文件服务 URL)。 - 绝对 URL / emoji / 纯文本:如
"https://…/icon.png"、"🏆"、"A"。emoji 不跟随主题色、不随缩放优化,建议优先用 1 或 2。 - 私有图标(
contributes.iconTheme):指向包内icon-theme.json,结构为{ "schemaVersion": 1, "icons": { "<图标键>": { "type": "svg", "path": "M…" } } }。 声明的键会出现在listIcons()中,getIconSvg优先解析它们——内置表里没有的图标 可以靠它自带,不必等启动器版本更新。
installModes 数组元素
安装整合包等资源时,安装对话框的「安装方式」选项组会列出激活插件贡献的条目(默认项为启动器内置的「创建实例」)。用户选中并确认后,启动器经插件注册表调用
installMode:{id} 方法(插件需用 __PLUGIN_API__.registerMethod 注册),附资源上下文:
registerMethod(config:write)权限模型。实践示例见服务端管理插件(top.qomicex.server-manager,安装方式「安装为服务端」)。
hooks 数组元素
声明用于文档化与权限预检;实际处理函数在运行时用
__PLUGIN_API__.registerHook 注册。
menuItems 数组元素
settingsPages 数组
把插件的设置界面统一收进启动器,避免设置入口散落在各处。- 每个路径是
.qplugin包内 HTML 文件的相对路径;插件停用后对应 tab 自动消失 - 启动器在「设置 → 插件 → 插件设置」为每个路径渲染一个 tab(左侧纵向 tab 逐插件列出,右侧 iframe 沙箱,与插件页相同的
__PLUGIN_API__桥) - 完整开发指南(设置 HTML 写法、getSettings/setSettings 用法、openPluginSettings 跳转、生命周期规则)见 插件设置页
icon 写法示例
http://localhost:5000/api/plugins/{id}/files/dist/icon.png,无需插件侧额外处理。
顶层 icon(库插件图标)
icon 除了写在 menuItems[].icon,也支持写在 manifest 顶层,供没有 contributes.menuItems 的库插件在插件管理/列表里显示图标:
- 支持写法与
menuItems[].icon一致(emoji / 绝对 URL / 包内相对路径 / FontAwesome 类名) - 插件管理卡片读取顺序:
contributes.menuItems[0].icon ?? manifest.icon - 库插件建议用顶层
icon,不要声明contributes.menuItems(会创建侧边栏入口) - 图标尽量用 FontAwesome 类名(如
fa-solid fa-file-lines、fa-brands fa-markdown,需在启动器BuiltinIcons.tsx预置列表内):SVG 路径经<img>渲染固定黑色不随主题,FA 类名随明暗主题
overlay 对象
layers 图层定义
layers 按复杂度分层,从纯声明到可执行逻辑,决定插件的能力与运行方式:
声明方式:
layers 是一个数组,可同时声明多个层级:
-
iframe 沙箱为默认渲染:带
entry.frontend的插件默认走 iframe 沙箱(<iframe sandbox="allow-scripts">+ postMessage 桥),与主界面 DOM/CSS 隔离(opaque origin,防 CSS 泄漏与同源窃取)。仅 manifest 显式声明"render": "inline"才走内联渲染(与主界面同上下文,兼容旧插件)。 -
iframe 沙箱内同样支持全部
__PLUGIN_API__方法、.p-*组件样式、registerMethod/callPlugin(跨窗口中转) -
沙箱插件脚本随
srcdoc解析自动执行,无需进入页面 -
插件激活条件:插件安装后初始状态为
installed,实际激活取决于两点:①entry.frontend存在(activatePlugin仅在entry.frontend存在时才渲染并标记active);② 用户在插件列表中启用。与layers声明无关——纯["l3"]插件若有entry.frontend照样会激活(默认走 iframe 沙箱)。 -
iframe 沙箱与内联渲染的差异:
-
L0/L1 当前为声明性预留层级,暂无独立运行机制;L3 WASM 已实现:声明
l3且包内含plugin.wasm的插件,由启动器 Rust 层(wasmtime)加载并执行(见 WASM 插件) -
L4 远程 WebView 已实现:声明
render:"webview"或layers含"l4"的插件,激活时由主窗口createRemoteWebview打开独立 Tauri WebviewWindow(与主界面进程级隔离),插件 UI 渲染在该窗口内,API 调用经 Tauri 事件转发到主窗口执行(见 l4 远程 WebView) - 需要隔离环境或常驻脚本的插件(如 AI 助手、工具面板)→ 使用默认 iframe 沙箱
-
纯 UI/主题类或依赖主界面 DOM 的轻量插件 → 显式声明
"render": "inline" -
若插件后续要接入 WASM 后端逻辑,可再叠加
"l3" -
重 UI / 不受控 / 需进程级隔离的插件(如复杂编辑器、游戏 UI 增强)→ 声明
"render": "webview"或layers含"l4"(独立窗口,busy-loop 不影响主界面)
版本范围语法
dependencies[].version 支持以下写法:
比较规则:
- 按
.分段、逐段数值比较;忽略-(预发布)和+(构建号)后缀 - 缺段视为 0(如
1.0等于1.0.0) - 不支持
^、~、*、通配x、||、逗号
minLauncherVersion:启动器侧当前不校验,但商店侧会校验——POST /plugins/check-updates 用 semver 比较,把最低版本高于当前启动器的版本从更新列表剔除;GET /plugins?minLauncherVersion= 也会据此过滤。CLI(qomicex verify)则要求该字段必须存在。因此请务必填写,否则 CLI 校验不通过,且商店无法做兼容过滤。