# 万能导在线插件开发与发布 万能导从 Plugin v1 开始采用“轻量主程序 + 平台插件”的结构。官方平台插件会随正式桌面端一起打包,离线也可以使用;签名在线更新可覆盖内置版本,用户刷新插件中心即可安装、回滚或卸载覆盖版本,不需要等待桌面端发新版本。 ## 两层契约 - **Plugin v1**:负责安装、签名、版本、权限、更新、回滚和卸载。 - **Provider v1**:负责描述平台页面、字段、动作、目录和能力。 一个插件可以包含多个 Provider。飞书插件同时包含 `feishu-export` 和 `feishu-import`,平台中心会把它们组合在同一张飞书卡片中。 旧的 `providers/` 文件型 Provider 仍然兼容,但不会自动联网更新。新平台优先提交到 `plugins/`。 ## 后端与任务契约 插件后端只能依赖 `wandao_core` 中的跨平台能力(浏览器、checkpoint、凭证、日志、报告),不能 import 另一平台插件的实现。顶层 `wandao_*` 模块仅用于兼容旧脚本。 会执行迁移的 action 最终必须通过 `wandao_core.report.finalize_report` 输出一行 TaskResult v1: ```json { "kind": "wandao.result", "schemaVersion": 1, "provider": "example", "mode": "export", "totalDocs": 1, "successCount": 1, "failureCount": 0, "failures": [], "resourceFailures": [] } ``` 桌面端会拒绝“进程成功退出但没有合法 JSON 结果”的任务。运行时会提供 `WANDAO_RUN_ID`、`WANDAO_JOB_ID` 和可选的 `WANDAO_PARENT_RUN_ID`;结构化日志、报告与 checkpoint 必须保留这些关联信息,便于恢复和重试追溯。 ## 最小目录 ```text plugins/example/ ├── plugin.json ├── backend/ │ └── export_example.py └── providers/ └── example/ ├── provider.json └── README.md ``` 复杂平台可以在一个插件中增加多个 Provider: ```text plugins/example/ ├── plugin.json ├── backend/ │ ├── export_example.py │ └── import_example.py └── providers/ ├── example-export/provider.json └── example-import/provider.json ``` ## plugin.json ```json { "$schema": "../plugin.schema.json", "schemaVersion": 1, "id": "example", "name": "示例平台", "description": "导出和导入示例平台内容。", "version": "1.0.0", "publisher": "你的 GitHub 名称", "core": { "minVersion": "1.2.9" }, "platforms": ["win32", "darwin", "linux"], "entrypoints": { "providers": ["providers/example/provider.json"] }, "permissions": ["network", "filesystem:write", "process"] } ``` 可声明的权限: - `network`:访问平台接口或下载资源。 - `browser-automation`:启动或控制 Chrome、Edge、Chromium。 - `credentials`:保存登录 Cookie 或平台配置。 - `filesystem:read`:读取用户选择的本地文件。 - `filesystem:write`:写入导出目录或报告。 - `process`:运行插件后端脚本。 权限会在安装前展示。没有声明 `process` 的插件不能执行 Python 后端。 ## 发布等级与稳定审核 插件是否进入官方默认库由 `plugins/release-policy.json` 决定,而不是由贡献者在 `plugin.json` 自行声明。未列出的新插件默认进入 `experimental`:它们仍可在 PR 中构建预览、合并后发布到实验库,并会在插件中心正常显示和搜索,但带有明确实验性标记。 `stable` 是维护者的质量背书。申请升级时需提供脱敏样例、真实人工验证、资源与失败场景证据、checkpoint/TaskResult 验收结果和明确维护责任。合并普通实验 PR 不需要这些材料,也不会因为尚未稳定而阻塞共创。 ## 两种 UI ### 标准 UI 推荐优先使用 Provider v1 的 `fields`、`actions`、`toc` 和 `capabilities`。主程序自动生成表单、目录选择器、进度、停止按钮和任务记录。 为知插件是标准 UI 示例: ```text plugins/wiz/providers/wiz/provider.json ``` ### 自定义 UI 确实无法用标准字段表达时,可以在 `plugin.json` 声明单文件 UI: ```json { "entrypoints": { "providers": ["providers/example/provider.json"], "ui": "ui/index.html" } } ``` 对应 Provider 声明: ```json { "ui": { "mode": "custom", "entry": "../../ui/index.html" } } ``` 自定义 UI 在 sandbox iframe 中运行:没有 Node、没有同源权限、默认不能联网,也不能直接读写本地文件。它只能通过 `postMessage` 请求以下宿主能力: - `selectDirectory` - `selectFile` - `openExternal`(仅 HTTPS) - `runAction`(只能执行 Provider 已声明的动作) 请求格式: ```js parent.postMessage({ source: 'wandao-plugin', requestId: crypto.randomUUID(), method: 'runAction', payload: { actionId: 'export', args: ['--output', '...'] } }, '*'); ``` 宿主使用 `source: "wandao-host"` 和相同 `requestId` 返回结果。 ## 后端边界 - 每次插件动作都在独立 Python 子进程中运行,崩溃不会直接带崩 Tauri 2 宿主进程。 - 插件拥有独立安装目录、版本目录和数据目录。 - 登录摘要默认写入 `%APPDATA%/wandao/plugin-data/`。 - 插件可以使用主程序提供的稳定 SDK:`wandao_logging`、`wandao_report`、`wandao_checkpoint`、`wandao_cli`、`wandao_credentials`、`wandao_browser`。 - 不要从其他平台插件导入业务代码。公共能力应先提取为稳定 SDK。 - 不在安装时执行 `pip install`。纯 Python 依赖应随插件打包;含原生库的依赖需要按系统分别构建插件包。 独立进程不是完整的操作系统沙箱。安全边界还依赖代码审查、权限最小化、官方签名和用户确认。 ## 本地检查 ```bash node scripts/validate_plugins.js node --test tests_js/plugin_manager.test.js python scripts/quality_check.py ``` 本地签名构建由维护者执行,贡献者不需要私钥: ```bash node scripts/build_plugin.js \ --source plugins/example \ --output dist-plugins/example-1.0.0.wandao-plugin \ --private-key /secure/path/plugin-ed25519-private.pem ``` ## PR 与发布 1. 先在“新平台接入建议 / 共创认领”Issue 中确认没有重复开发并完成认领;仅提出平台建议不需要认领。 2. 一个 PR 只修改一个插件;不要顺手改其他平台或主程序。只有维护者协调的协议迁移可以添加 `plugin-batch` 标签批量修改。 3. 修改插件内容时必须提升 `plugin.json.version`。 4. PR 流水线校验目录、权限、脚本路径、语法和生命周期,并生成 `plugin-pr-preview` 预览包。预览包使用临时 `pr-preview` 密钥,只用于 CI 产物检查,不作为普通用户正式安装包。 5. PR 合并到 `main` 后,仓库流水线从 GitHub Actions Secret `WANDAO_PLUGIN_PRIVATE_KEY` 读取维护者私钥,生成正式签名包。 6. 流水线更新 `plugins-latest` Release 中的插件包和签名注册表。 7. 用户在插件中心刷新后即可安装或更新,桌面端版本号不变。 签名私钥只保存在 GitHub Actions Secret `WANDAO_PLUGIN_PRIVATE_KEY`,不会提交到仓库。主程序只内置公钥,下载文件和已安装文件都会校验。 ## 版本规则 - 修复插件自身 Bug:补丁版本,例如 `1.0.0 -> 1.0.1`。 - 新增兼容能力:次版本,例如 `1.0.1 -> 1.1.0`。 - 破坏插件数据或交互契约:主版本,例如 `1.x -> 2.0.0`。 - 如果插件需要新的主程序 SDK,同时提高 `core.minVersion`。 首批真实样例: - `plugins/wiz`:标准 UI、目录、图片和 checkpoint。 - `plugins/feishu`:同一插件包含导出与导入,覆盖登录、权限、Wiki 目录、图片修复和复杂参数。