Skip to content

清单

manifest.json 是插件的唯一事实来源。宿主在安装时解析它,以获知插件的身份、如何启动其 worker、挂载什么 UI、允许它做什么,以及它暴露哪些 AI 工具。它位于 .fyp 归档的根目录。

Schema 参考

字段类型必填默认值说明
schemaVersionnumber清单 schema 版本。当前为 2
idstring反向 DNS 的插件 id,例如 fan.summer.excel。在已安装插件中必须唯一。
namestring人类可读的显示名。
descriptionstring在市场与插件列表中展示的一行描述。
versionstringSemVer 风格的版本字符串,例如 4.0.0
authorstring作者或组织名。
iconstring图标标识符(一个 Vuetify/Material 设计图标名,例如 file-excel)。
categorystring合法 category 取值之一。
uiobjectUI 子记录。见 ui
backendobjectWorker 子记录。见 backend可选——纯 UI 插件可省略它。
rpcobjectRPC 方法表。见 rpc.methods。声明每个方法的 inputSchema/outputSchema(JSON-Schema 对象)。
permissionsstring[][]声明的权限。驱动文件 I/O 授权。
homepagestring指向插件主页或源码仓库的 URL。
officialbooleanfalseOfficialPluginSeeder 预置的插件设为 true;将描述符的 source 设为 OFFICIAL
aiToolsobject[][]声明的 AI 工具。空数组表示 supportsAi = false

ui

字段类型必填说明
entrystring相对于归档根的入口 HTML 路径,通常为 ui/index.html。通过 /plugin-runtime/{id}/<entry> 提供。

backend

字段类型必填说明
callTimeoutSecondsinteger插件级的默认每次调用超时(秒)。会被钳制到 [1, 600]。省略时宿主使用 60aiTools[].timeoutSeconds 会针对单个工具覆盖此值。

宿主按约定以 java -jar backend/worker.jar 启动 worker,并通过 stdio 上的 JSON-RPC 2.0 驱动它;线协议固定为 json-rpc-2.0,不再在清单中声明启动命令或协议。

rpc.methods

插件暴露的 JSON-RPC 方法表,以方法名为键。每个方法自带其参数与输出的 JSON Schema——是真正的 JSON-Schema 对象,而非转义字符串。Java Worker SDK 与 TypeScript UI 客户端均从该表生成类型化绑定。

字段类型必填说明
descriptionstring方法的简短描述。
inputSchemaobject描述方法参数的 JSON Schema 对象
outputSchemaobject描述 Worker 结果信封的 JSON Schema 对象。

aiTools[].method 必须在此表中存在;fengyu CLI 在 check/build 时会校验二者一致。

aiTools[]

每一项声明一个 AI 可调用的工具,宿主会把它们聚合成其 Spring AI 的 ToolCallback[]。参数与输出 Schema 不再内联——它们声明在 rpc.methods 中;aiTools[] 只携带工具的面向模型的元数据与副作用分类。

字段类型必填说明
namestring暴露给模型的工具名。
descriptionstring给模型的自然语言描述。
methodstring当模型调用此工具时要调用的 worker JSON-RPC 方法(必须在 rpc.methods 中存在)。
effectstring审批分类:readwriteexternal
timeoutSecondsinteger针对此工具的调用超时(秒),钳制到 [1, 600]。覆盖 backend.callTimeoutSeconds。默认 60可能超过其声明超时的工具必须拆分为 *_start / *_status / *_cancel 的 job 方法——参见 Worker → 长任务(job 模式)

端到端流程见 AI 工具

合法 category 取值

category 是一个自由格式的提示性字符串,UI 用它来对插件分组——宿主不会校验它是否属于某个固定集合(它只会把你写的值转为大写,为空时默认为 OTHER)。为保持一致,请使用以下约定取值之一:

取值用途
dev开发者工具
text文本编辑/渲染(例如 fan.summer.markdown
image图像处理
net网络相关
network网络相关(例如 fan.summer.email
file文件处理(例如 fan.summer.excel
ai以 AI 为中心的插件
other上述未涵盖的任何类型(脚手架的默认值)

合法权限

permissions 是一个数组,包含零个或多个以下规范集合中的值,由 CLI 与宿主共同强制执行:

取值授权
files.readPOST /api/plugin-runtime/{id}/files/uploadupload-directorynative(读访问)
files.writePOST .../files/native(写访问)、POST .../files/outputGET .../files/export/{ref}
network来自 worker 的通用出站网络访问。
network.emailworker 可以建立 SMTP/IMAP 连接(fan.summer.email 使用)。
clipboard.read读取宿主剪贴板。
clipboard.write写入宿主剪贴板。
notifications显示宿主通知/toast。
database宿主向 worker 环境注入数据库连接坐标(FENGYU_DB_* —— type/driver/url/username/password —— 以及一个私有数据目录),以隔离 DB 用户/schema 形式 provision;由 worker 自行建立连接。参见插件数据库规范

任何其他取值在 validate 与 install 时都会被当作未知权限拒绝。在缺少对应权限的情况下尝试文件操作会被以 403 拒绝。参见 文件 I/O

强制力度并不一致(P1-9)。 不要假设每个被接受的权限都被同等强制执行:

  • 由宿主/OS 沙箱强制: files.readfiles.write(FileRef 授权闸门)、network(OS 网络命名空间)。
  • 在网络层按全量出站放行(advisory): network.emaildatabase 目前授予宽泛的出站网络——宿主尚未代理 SMTP/IMAP,也未限制 DB 只连特定主机。真正的邮件/DB 代理是一项已立项的后续工作。
  • 宿主桥门控(插件 notify): notifications。宿主桥会在运行时读取它——声明了该 权限的插件,其 notify 调用会产生真正的统一宿主通知(应用内 toast + 原生桌面通知 + 持久化通知中心);未声明的调用回退到 @infinia/plugin-ui 的 iframe 内部通知中心。
  • 仅声明(尚无宿主强制): clipboard.readclipboard.write 只是为未来到桌面外壳的 capability 桥接声明意图,运行时当前不读取。

在任何汇总插件权限的 UI 中都要如实呈现——不要对 network.email/database 暗示比 OS 实际强制更细的网络隔离。

示例

Markdown 插件

fan.summer.markdown 的清单——一个无权限、无 AI 工具的文本插件:

json
{
  "schemaVersion": 2,
  "id": "fan.summer.markdown",
  "name": "Markdown Editor",
  "description": "Split-pane Markdown editor with isolated server-side rendering",
  "version": "4.0.0",
  "author": "FengYu",
  "icon": "language-markdown",
  "category": "text",
  "ui": { "entry": "ui/index.html" },
  "backend": { "callTimeoutSeconds": 30 },
  "permissions": [],
  "homepage": "https://github.com/MuskStark/FengYu",
  "official": true,
  "rpc": {
    "methods": {
      "render": {
        "description": "Render Markdown source to sanitized HTML via commonmark.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "markdown": { "type": "string", "description": "The Markdown source to render." }
          },
          "required": ["markdown"]
        },
        "outputSchema": {
          "type": "object",
          "properties": {
            "success": { "type": "boolean", "description": "true when the render completed." },
            "summary": { "type": "string", "description": "Short localized result summary." },
            "html": { "type": "string", "nullable": true, "description": "The rendered, sanitized HTML." }
          },
          "required": ["success", "summary"]
        }
      }
    }
  }
}

Excel 插件(含 aiTools)

fan.summer.excel 的清单——一个带读写权限和 AI 工具的文件插件。这里完整展示两个方法:excel_analyze(短时同步调用),以及 excel_execute_start(长时拆分 job 模式对的启动半边)。参数与输出 Schema 是 rpc.methods 里的 JSON-Schema 对象aiTools[] 只引用方法名并声明副作用:

json
{
  "schemaVersion": 2,
  "id": "fan.summer.excel",
  "name": "Excel Splitter",
  "description": "Split Excel workbooks by sheet, column value, or complex rules",
  "version": "4.0.0",
  "author": "FengYu",
  "icon": "file-excel",
  "category": "file",
  "ui": { "entry": "ui/index.html" },
  "backend": { "callTimeoutSeconds": 60 },
  "permissions": ["files.read", "files.write"],
  "homepage": "https://github.com/MuskStark/FengYu",
  "official": true,
  "rpc": {
    "methods": {
      "excel_analyze": {
        "description": "Analyze the granted Excel workbook; returns sheet names.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "filePath": { "type": "string", "description": "Resolved absolute path of a readable FengYu FileRef." }
          },
          "required": ["filePath"]
        },
        "outputSchema": {
          "type": "object",
          "properties": {
            "success": { "type": "boolean" },
            "summary": { "type": "string" },
            "sheets": { "type": "array", "items": { "type": "string" } }
          },
          "required": ["success", "summary"]
        }
      },
      "excel_execute_start": {
        "description": "Launch the configured split as a background job and return a jobId immediately. Poll excel_execute_status with a cursor to drain progress logs.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "outputDir": { "type": "string", "description": "Resolved absolute path of a writable FengYu DirectoryRef." },
            "filePrefix": { "type": "string" }
          },
          "required": ["outputDir"]
        },
        "outputSchema": {
          "type": "object",
          "properties": {
            "success": { "type": "boolean" },
            "summary": { "type": "string" },
            "jobId": { "type": "string" }
          },
          "required": ["success", "summary"]
        }
      }
    }
  },
  "aiTools": [
    { "name": "excel_analyze", "method": "excel_analyze", "effect": "read", "description": "Analyze the granted Excel workbook; returns sheet names.", "timeoutSeconds": 30 },
    { "name": "excel_execute_start", "method": "excel_execute_start", "effect": "write", "description": "Launch the configured split as a background job and return its job ID.", "timeoutSeconds": 30 }
  ]
}

inputSchema/outputSchema 是真正的 JSON-Schema 对象(不再是转义字符串)。aiTools[] 只携带 name/method/effect/description/timeoutSeconds——参数与输出 Schema 统一声明在 rpc.methods 中,宿主据此构建 Spring AI 的 ToolDefinition

下一步

Released under the GPL-3.0 License.