PI-Desktop插件清单全字段解析:.piplug包格式深度指南
【免费下载链接】PI-DesktopLocal-first AI coding agent desktop: Electron + Rust host core + pi Agent Harness + user-installable plugins项目地址: https://gitcode.com/GitHub_Trending/pid/PI-Desktop
如果你想在 PI-Desktop(一款 Local-first AI coding agent 桌面应用)中开发或安装插件,那么manifest.json是你必须读懂的第一份文件。本文带你完整解析 PI-Desktop 插件清单(Manifest)的全部字段,以及它的分发格式.piplug包——从必填项、UI 声明、能力贡献(contributes)、权限(permissions)到文件/网络沙箱策略,一篇讲透。
读完本文,你将能够:
- 看懂任意 PI-Desktop 插件的
manifest.json - 知道每个字段对应什么能力、需要什么权限
- 理解
.piplug包的内部结构与安装校验规则
核心参考文档:02-plugin-manifest-schema.md(字段权威定义)与 06-plugin-packaging.md(打包规范)。
一分钟认识 .piplug 包格式
.piplug是 PI-Desktop 的产品级插件分发扩展名,本质是一个zip 压缩包,根目录必须包含manifest.json(见 ADR 0007)。典型结构如下:
demo.hello-0.1.0.piplug └─ (zip) ├─ manifest.json ← 插件清单,根目录必须存在 ├─ main.js ← 插件运行时入口 ├─ renderer/ ← 面板 HTML/CSS ├─ skills/ ← Agent 技能文档 ├─ themes/ ← 主题 CSS └─ checksums.json ← 可选的包内校验清单选择 zip 的原因很务实:跨平台、实现简单、方便做校验和/签名、开发者可以解压后本地审查。
包内硬性约束 📦
| 约束 | 规则 |
|---|---|
| 根目录 | 必须包含manifest.json |
| 路径 | 禁止绝对路径软链接、禁止../路径穿越 |
| 压缩方式 | 必须是store(不压缩)模式,普通 zip 工具生成的包会被安装器拒绝 |
| 大小 | 解压后默认上限 50 MB(可配置) |
| 文件数 | 默认上限 2000 个(可配置) |
💡 开发阶段无需打包——直接选择包含
manifest.json的目录加载为"开发插件"即可。打包请用官方工具pi-plugin pack,它会输出<id>-<version>.piplug并打印 SHA-256。
必填字段:身份四件套 + 入口
manifest 的 Schema 版本当前为1。以下五个字段缺一不可(host-core 校验源码见 manifest.rs):
| 字段 | 要求 | 说明 |
|---|---|---|
schemaVersion | 必须是1 | 未来升到 2 需要迁移器,过高的主版本会被拒绝 |
id | 必填 | 反向域名风格,如com.example.todo;发布插件建议用稳定 id,设置、数据、授权、更新全部以它为键 |
name | 必填 | 展示名称(作者语言) |
version | 必填 | 语义化版本(semver),如0.1.0 |
main | 必填 | 运行时入口,相对路径,指向可直接加载的 js/html/css,宿主不会替你做npm install或编译 TypeScript |
可选字段:从描述到国际化
基本信息区
description:一句话描述author:字符串或{ name, url, email }对象homepage/repository:项目地址icon:图标相对路径engines.piDesktop:宿主版本范围,如">=0.1.0"enabledByDefault:内置插件首次注册默认开关;省略即默认启用
i18n:让插件说用户语言 🌏
name/description是展示文案,可通过顶层i18n块按语言声明。en和zh-CN是契约语言:所有中文 Shell 语言读zh-CN,其余语言读en;缺失时逐字段回退到作者原文。
{ "name": "小清新待办", "i18n": { "en": { "name": "Todo List", "description": "A calm todo list" }, "zh-CN": { "name": "小清新待办", "description": "轻盈的待办清单", "safetyNotes": "只写自己的数据" } } }解析发生在宿主侧(按settings.language或 OS 语言),注册表里始终保存作者原文,切语言不重写数据库。
ui 块:面板与浮动小组件
{ "ui": { "panel": "renderer/index.html", "width": 480, "height": 360, "resizable": true, "title": { "en": "My Panel", "zh-CN": "我的面板" } } }panel指向沙箱、上下文隔离的 Electron 窗口(无 Node 集成),只暴露window.pluginBridge- 宿主预留 46px 透明拖拽带,不要在内容区再补 46px 顶部内边距
- 想要"悬浮球"式透明无边框窗口?声明
"ui": { "shape": "widget" },最小支持 120×120,alwaysOnTop可置顶
contributes 块:插件能贡献什么 🧩
这是 manifest 的核心——声明插件向宿主注入的能力。每种能力都有对应的权限要求(缺失即校验失败,skills除外):
| 能力 | 用途 | 所需权限 |
|---|---|---|
commands | 全局搜索中的命令 | — |
agentTools | Agent 可调用的工具(含risk等级与 JSON Schema) | agent.tool.register |
skills | 按需注入的提示词文档(字符串路径或元数据覆盖对象) | agent.prompt.inject(缺失则跳过) |
views | 停靠在工作面板的界面(本地化 title,icon为宿主图标 token) | ui.view |
themes | 设计令牌覆盖 CSS(base为 light/dark,最多 8 个,单文件 256 KiB) | ui.theme |
settings | 设置项(string/number/boolean/select/json/shortcut) | — |
mcpServers | stdio 或 http 的 MCP 服务器 | mcp.server.local/mcp.server.remote |
services | 宿主监管的常驻服务 | background.service |
bus | 插件间消息总线(publish 具体主题 / subscribe 通配模式) | bus.publish/bus.subscribe |
providers | 声明模型供应商行(最多 8 个,每个 1..64 个模型) | provider.register |
globalShortcuts | 全局快捷键(最多 8 条,command 必须已声明) | keyboard.globalShortcut |
完整字段类型定义见 02-plugin-manifest-schema.md。两个值得注意的细节:
- MCP 的
env/headers支持{ "setting": "key" }语法读取插件自身设置,宿主环境变量永不透传 contributes.providers的oauth暂不支持,声明即校验失败
完整示例
仓库自带一个"全家桶"示例插件,覆盖命令、面板、工具、技能、主题、服务、总线、设置:examples/plugins/hello/manifest.json。更精简的 Agent 工具插件可看 examples/plugins/roundtable/manifest.json。
permissions 与沙箱策略
permissions:32 项封闭枚举
permissions是"能否碰"的总闸。未知权限值 = 校验失败。按风险分三档:
- 低:
ui.panel、ui.view、ui.theme、notify - 中:
clipboard.read/write、fs.read、background.service、bus.publish/subscribe、keyboard.globalShortcut等 - 高:
fs.write、fs.delete、agent.tool.register、agent.prompt.inject、net.fetch、mcp.server.local/remote、net.websocket、desktop.control等
完整矩阵见 13-plugin-permissions-matrix.md。
fs:能碰哪些文件 📁
权限回答"能否碰文件",fs回答"碰哪些":
{ "permissions": ["fs.read", "fs.write", "fs.delete"], "fs": { "read": { "root": "workspace", "scope": ["**/*"] }, "write": { "root": "workspace", "scope": ["docs/**", "*.md"] }, "delete": { "own": true, "scope": ["dist/**"] } } }- 不写
fs块 =零常驻可达,每次访问都弹运行时确认——"不声明,就不给" - 写/删除禁止整树模式(
**、**/*等),只有读可以声明全树 root: "userSelected"走用户选目录授权,句柄仅存内存,随进程销毁.env*、SSH 凭据、*.pem、.git/**无论怎么声明都拒绝
net:出站白名单 🌐
{ "net": { "domains": ["api.example.com", "*.githubusercontent.com"] } }这份白名单约束所有宿主管理的出站路径——pi.net.fetch、面板自身的fetch/<img>/<script>加载、远程 HTTP MCP、WebSocket。条目只能是裸主机名(无协议/端口/路径),裸*被拒,省略或写坏 =完全无出站。
校验规则速查 ✅
安装前宿主执行严格校验,常见雷区:
- 路径字段一律相对路径,禁止绝对路径和
.. main/ui.panel/ skills /views[].entry指向的文件必须存在- 贡献 id(themes、mcpServers、services、views)须匹配
[a-zA-Z][a-zA-Z0-9_-]{0,63}且列表内唯一 - 能力缺对应权限直接失败(如
agentTools必须配agent.tool.register) fs.<mode>必须配同名权限;net.domains必须是裸主机名activationEvents支持onStartup、onCommand:*(当前 MVP 实现)
校验器与打包器共用同一套规则——用pi-plugin check就能在本地预演安装结果。
开发 → 打包 → 安装全流程 🔧
选择目录/包 → 校验包安全性 → 解压到临时区 → 校验 manifest + 文件 → 权限审查 UI → 移入 installed/<id> → 写注册表 → 可选自动启用- 同 id 新版本 = 升级,旧版自动备份到
cache/backup/<id>/<version> - 失败则清理临时区,不留半成品目录
- 发布前清单:稳定反向域名 id → 升 semver → 声明
engines.piDesktop→pi-plugin check清零错误 →pi-plugin pack→ 干净状态安装测试 → 记录 SHA-256
更多开发细节(热重载、日志、排错表)见 plugin-development.md;安全模型背景见 04-plugin-security.md。
总结
| 概念 | 一句话 |
|---|---|
manifest.json | 插件的身份证 + 能力声明书,根目录必须有 |
.piplug | store 模式 zip,50MB / 2000 文件上限,禁止穿越与软链 |
contributes | 插件给宿主"注入"什么,几乎每项都绑权限 |
permissions+fs+net | 三道沙箱:能不能碰 → 碰哪些文件 → 出站到哪 |
| 校验 | 能力缺权限即失败;不声明沙箱范围即零权限 |
读懂这五个字段簇,你就掌握了 PI-Desktop 插件生态的"语言"。动手试试:用应用内New plugin from template生成panel-basic模板,对照本文逐字段检查生成的 manifest.json——这比看十篇文档都快。
【免费下载链接】PI-DesktopLocal-first AI coding agent desktop: Electron + Rust host core + pi Agent Harness + user-installable plugins项目地址: https://gitcode.com/GitHub_Trending/pid/PI-Desktop
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考