docs(platform): 插件平台 - 补充机制审计与市场演进调研
This commit is contained in:
314
docs/design/plugin-platform-and-marketplace-research.md
Normal file
314
docs/design/plugin-platform-and-marketplace-research.md
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
# 插件机制现状、对外回应与插件市场演进调研
|
||||||
|
|
||||||
|
> 状态:调研与建议,未实施;不是现有能力承诺。
|
||||||
|
> 基线:2026-09-06,本地工作区 HEAD `df94c3bd`。未修改运行时代码、部署、数据库或现有用户文件。
|
||||||
|
> 范围:影策内部的 Provider、应用/UI、编辑器与支付插件;不将 `plugins/yingce/` 的 Codex App 连接插件与影策自身扩展系统混为一谈。
|
||||||
|
|
||||||
|
## 1. 决策摘要
|
||||||
|
|
||||||
|
用户反馈**对应用/UI 插件大体成立,但不能泛化为所有插件都只是开关**。现在是三种成熟度并存:
|
||||||
|
|
||||||
|
1. **声明式 Provider 扩展已经成立**:在现有请求、响应与表达式能力内,新协议可以通过包安装,不必修改宿主源码。
|
||||||
|
2. **应用/UI 扩展主要仍是内置模块化**:清单、注册表与开关存在,但大量实现、路由、设置和节点渲染仍随主应用编译。外部 Web 包的校验合同不等于执行运行时。
|
||||||
|
3. **支付存在真正的包内程序执行**:RPC 加载链路已存在;但它是专用能力,不是通用后端扩展平台,其现有隔离方式也不足以直接承接开放市场的不可信程序。
|
||||||
|
|
||||||
|
因此,当前准确定位是:**“已有声明式插件能力和部分独立运行时,应用插件正在从内置模块化演进为外部可安装扩展。”**
|
||||||
|
|
||||||
|
建议优先投入:**外部应用插件最小闭环 → 外部作者试用 → 受控分发目录 → 开放市场 → 商业化**。不是先建设市场 UI,也不是把所有内置组件搬进名为 plugins 的目录。
|
||||||
|
|
||||||
|
### 真正插件化的判断标准
|
||||||
|
|
||||||
|
关键不是“不写代码”,而是**扩展代码由谁编写、在哪发布、是否必须改宿主**。
|
||||||
|
|
||||||
|
- 插件作者可以写代码;声明式配置也可以是真插件,不必刻意引入可执行代码。
|
||||||
|
- 针对宿主已经开放的能力,作者不应修改宿主源码、不应依赖私有 store/service、不应等待宿主重新编译发布。
|
||||||
|
- 宿主仍然需要维护稳定的扩展点与公共 API。全新系统能力、权限类型和核心数据语义可能需要宿主升级,不承诺“任意未来功能永远不改宿主”。
|
||||||
|
- “内部模块化”“独立发布安装”“安全隔离”“市场运营”是不同维度;安全隔离不足不等于没有扩展能力,但不能因此宣称可安全开放市场。
|
||||||
|
|
||||||
|
## 2. 仓库审计:哪些已经有,哪些没有
|
||||||
|
|
||||||
|
以下是本次读取或执行得到的事实;“未找到”只限定为本次检查的工作区与路径,不代表对其他分支、线上版本作结论。
|
||||||
|
|
||||||
|
| 面向用户的能力 | 当前证据 | 判断 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 安装新模型协议 | `.yingce-plugin` 经校验、存储、加载为 `manifestAdapter`,进入运行时 registry | 现有 DSL 范围内是真扩展,不只是开关 |
|
||||||
|
| 工作流声明 | 统一 `contributes.workflows` 与 Provider 引用合同;另有 RunningHub/ComfyUI 专用状态及配置流程 | 有可扩展基础,但不能从清单推导所有工作流集成都已通用化 |
|
||||||
|
| 新应用/UI | builtin 静态导入;上传记录转为 `{ manifest, source }`,未构造外部代码实例 | 主要仍是宿主内置能力管理 |
|
||||||
|
| 新画布节点 | 节点注册表可接声明;通用 declarative 分支按 schema 展示数据 | 有基础声明式显示,不是任意交互组件运行时 |
|
||||||
|
| sandbox 节点 | 直接渲染“插件节点等待隔离运行时” | 已声明、未打通执行 |
|
||||||
|
| 编辑器插件 | UI 插槽注册存在;`editor-shell` 静态导入八个组件,以同一插件 ID 注册 | 是内部插槽化,不能据此声称八个独立外部插件已落地 |
|
||||||
|
| 应用启停与配置 | 后端按官方应用 ID 策略表分类;前端仍有 Eagle 等专用配置分支 | 用户“新增插件仍要改代码”的直接来源 |
|
||||||
|
| 支付 RPC | 从包提取 `backendEntry`,创建 `payment.NewRPCProvider` 并执行包内程序 | 已实现专用动态后端执行 |
|
||||||
|
| WASM | 清单允许声明;支付加载时明确返回“wasm 支付运行时尚未启用” | 合同预留,不是已支持运行时 |
|
||||||
|
| 完整市场 | 检查到本地包、安装接口、已安装 Provider catalog;未找到完整发布者提交/审核/发现/签名分发链路 | 插件中心不等于插件市场 |
|
||||||
|
|
||||||
|
### 2.1 包产物清点
|
||||||
|
|
||||||
|
只读取 ZIP 中的清单,未运行包内程序:
|
||||||
|
|
||||||
|
- `plugin-packages/*.yingce-plugin` 共 **80** 个文件,均可读取 `manifest.json`。
|
||||||
|
- **78** 个包含 Provider 贡献,未显式声明 backend/web runtime;现有加载路径按声明式处理。
|
||||||
|
- **2** 个包含支付贡献,声明 `runtime.backend=rpc`。
|
||||||
|
- **0** 个声明 Web `entry`。
|
||||||
|
- **1** 个包同时包含 workflow 贡献;贡献数量可重叠,不能与包数量相加。
|
||||||
|
|
||||||
|
这说明当前随仓库分发的样本集主要验证协议包与支付包,不能作为外部应用插件已可用的证据。数量仅是本地快照,不是线上安装量、用户数或市场规模。
|
||||||
|
|
||||||
|
### 2.2 关键证据定位
|
||||||
|
|
||||||
|
| 编号 | 文件 / 符号 | 支持的结论 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| E1 | `web/src/lib/plugins/builtin/index.ts:1–6` | Eagle、提示词优化、工作流、肖像排查、审美批改与 editor-shell 均静态导入 |
|
||||||
|
| E2 | `web/src/components/canvas/canvas-node-content.tsx:63–97`,`CanvasNodeContent` / `PluginCanvasNodeContent` | 肖像排查与审美批改专用渲染分支;sandbox 是占位提示;declarative 是基础数据展示 |
|
||||||
|
| E3 | `web/src/lib/plugins/builtin/editor/editor-shell.tsx:1–100` | 八个组件通过静态 import,在模块顶层注册到同一插件的插槽 |
|
||||||
|
| E4 | `web/src/pages/plugins/index.tsx:515` 附近及 `toRegisteredPlugin` | Eagle 专用设置;后端记录只转换为 manifest/source |
|
||||||
|
| E5 | `web/src/router.tsx:45,121` | Eagle 页面仍是宿主专用 import 和路由 |
|
||||||
|
| E6 | `backend/internal/service/plugin_management.go`,`officialApplicationPolicies` / `pluginManagement` | 应用类别与管理 scope 依赖宿主 ID 表;上传来源固定按系统级协议管理,未形成通用第三方应用分类 |
|
||||||
|
| E7 | `backend/internal/service/protocol_plugins.go`,`install` / `reload`;`backend/internal/protocol/manifest.go`,`LoadInstalledProviders` | 包安装与声明式 Provider 动态加载已存在 |
|
||||||
|
| E8 | `backend/internal/protocol/package.go`,`validatePluginPackageRuntime`;相邻 `package_test.go` | Web 入口存在性与路径校验已实现;相关测试只验证包合同 |
|
||||||
|
| E9 | `backend/internal/service/protocol_plugins.go:380–445`;`backend/internal/payment/rpc.go:75–145` | 支付专用程序加载;WASM 未启用;RPC 通过宿主子进程执行 |
|
||||||
|
| E10 | `web/src/lib/plugins/plugin-types.ts`,`RegisteredPlugin`;`web/src/services/plugin-host.ts`,`createPluginHostContext` | 声明了 activate/deactivate;当前 host context 主要封装 ai.text;未检索到通用生命周期调用调度器 |
|
||||||
|
| E11 | `backend/internal/service/protocol_registry.go`,`InstallPluginForAdmin` | 上传入口要求管理员、保护保留 ID 并写审计;不是任意用户当前均可上传程序 |
|
||||||
|
| E12 | `backend/internal/service/payment_plugin_lifecycle_test.go` | 已有未完成订单阻止升级等守卫,后续平台化不能丢掉这些业务约束 |
|
||||||
|
| E13 | `docs/adr/0005-editor-preset-plugin-architecture.md` | 既有 ADR 明确把外部安装/市场/沙箱放在后续,预设插件本身是原阶段边界 |
|
||||||
|
|
||||||
|
### 2.3 不应误判的地方
|
||||||
|
|
||||||
|
- `backend/internal/protocol/builtin.go` 确实还包含静态适配器,但**不能仅因文件存在,就断言已安装包在生产执行时全部委托给它**。本次看到 `reload` 使用 `LoadInstalledProviders(raw, nil)`;无 resolver 的 `host:` 会被拒绝,上传也禁止 `host:`。现有安装链路本身有真实声明式执行。
|
||||||
|
- 支付 RPC 已设超时、输出大小限制、精简环境变量、入口/平台校验和包摘要校验。这些是有效措施,但不是文件系统、网络、进程与租户资源隔离。
|
||||||
|
- 未运行真实第三方支付网关或模型上游;测试通过不代表所有随包协议都已做供应商联调。
|
||||||
|
|
||||||
|
## 3. 如何对用户回应
|
||||||
|
|
||||||
|
建议直接回应,不争论“插件”一词,也不把责任推给用户不会开发:
|
||||||
|
|
||||||
|
> 这条反馈我们认可,尤其是应用和界面类插件。目前部分插件仍是主程序内置能力的模块化管理,启停独立了,但新增能力仍需要修改主程序;我们之前没有把这个边界说明得足够清楚。
|
||||||
|
>
|
||||||
|
> 同时,模型协议类插件已经可以在现有声明式能力范围内通过安装包扩展,支付也有独立运行时,所以并不是所有插件都只是开关。
|
||||||
|
>
|
||||||
|
> 下一步我们会先补齐外部应用插件的 SDK、隔离运行环境和通用扩展入口。验收标准不是多几个插件卡片,而是第三方开发者不修改影策源码,也能开发、安装、运行和升级插件。这个闭环经过外部开发者验证后,再开放插件市场。
|
||||||
|
>
|
||||||
|
> 在这之前,我们会明确标注哪些是内置扩展、哪些支持外部安装、哪些运行时尚未支持,不把规划能力写成已实现能力。
|
||||||
|
|
||||||
|
不要承诺未经验证的交付日期、任意插件零成本运行,或“以后完全不用改宿主”。对外更有说服力的证据是**第三方独立开发与安装演示、可下载样例包、SDK 文档和兼容性测试**。
|
||||||
|
|
||||||
|
## 4. 外部体系对照:借鉴机制,不照搬技术名词
|
||||||
|
|
||||||
|
来源均为官方开发文档/官方仓库,见 §10。下表的“借鉴”是本报告建议,不是这些产品对影策的推荐。
|
||||||
|
|
||||||
|
| 体系 | 官方资料确认的机制 | 对影策的借鉴 / 限制 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| VS Code | Manifest contribution points 与扩展宿主分离;Node 和浏览器 Worker 有不同入口。[S1–S3] | 定义贡献点、版本化 API、按环境声明入口;不要让插件直接绑定主应用内部结构 |
|
||||||
|
| VS Code 安全与市场 | 桌面扩展宿主拥有与 VS Code 相同权限;市场另做扫描、签名验证和封禁。[S4] | **独立进程不自动等于安全沙箱**;市场信任与运行时隔离都要单独设计 |
|
||||||
|
| Figma | 插件逻辑运行于有限 JS 环境,UI 在 iframe;文档访问与浏览器 UI 通过消息连接。[S5] | 适合画布产品的“受控文档 API + 隔离 UI + 消息调用”模式,而非注入主 React 树 |
|
||||||
|
| Dify | 插件按能力扩展;daemon 管生命周期和不同运行环境;有 CLI 与包发布流程。[S6–S7] | 将模型、工具、工作流的插件执行与业务 API 进程解耦;复用影策已有任务/配额体系,不复制整套 Dify |
|
||||||
|
| Dify Marketplace | 发布流程含安装/打包验证、元数据与隐私材料检查、自动检查和人工审核。[S8] | 先建立发布和安装质量门槛,再谈搜索、推荐与规模增长 |
|
||||||
|
|
||||||
|
特别排除两个误区:
|
||||||
|
|
||||||
|
1. **Module Federation 或远程 import 是代码装载方式,不是安全边界。** 本报告不建议将未经审查的市场代码直接加载进主应用 React 上下文;可信内置模块可以保留高性能直连,但必须通过同样的公开业务合同,而不是继续增加私有捷径。
|
||||||
|
2. **Web Worker 不是“自动禁网的沙箱”。** Worker 可以发网络请求,且脚本响应的 CSP 有自己的边界;iframe 也不能简单加一个 sandbox 属性就视为完成隔离。[S9–S10]
|
||||||
|
|
||||||
|
## 5. 目标结构:一个包合同,多类贡献,分级运行
|
||||||
|
|
||||||
|
```text
|
||||||
|
本地包 / 官方预置包 / 受控目录 / 未来市场
|
||||||
|
│
|
||||||
|
安装校验与不可变版本仓库
|
||||||
|
│
|
||||||
|
Contribution Registry + 生命周期管理
|
||||||
|
│
|
||||||
|
权限代理(用户/项目/插件/版本/操作)
|
||||||
|
┌─────────┼───────────┐
|
||||||
|
声明式执行器 隔离 Web UI 专用后端插件运行服务
|
||||||
|
Provider/表单 iframe/RPC 受限任务执行,后续完善
|
||||||
|
└─────────┼───────────┘
|
||||||
|
稳定 Host API / 命令协议
|
||||||
|
│
|
||||||
|
画布、任务、资源、模型、权限、账务
|
||||||
|
```
|
||||||
|
|
||||||
|
统一的是**包身份、版本、贡献声明、权限授予与安装记录**,不是强迫所有插件使用一种语言或运行环境。一个包可以同时提供 Provider、面板和命令,不能重新拆成互不相通的多套市场。
|
||||||
|
|
||||||
|
### 5.1 宿主必须保留的责任
|
||||||
|
|
||||||
|
保留登录和归属校验、项目与画布存储、任务队列、资源访问、模型中转、配额和账务、撤销重做、基础 UI 插槽、权限代理、生命周期与审计。插件不得直连数据库、写内部 Zustand 状态、直接修改订单状态,或绕过任务/计费协议请求模型。
|
||||||
|
|
||||||
|
插件负责其业务算法、供应商适配、自己的 UI、配置 schema 与版本迁移。新增同类型插件不应再改路由表、供应商 switch、平台插件 ID 白名单或专用设置页。
|
||||||
|
|
||||||
|
### 5.2 首批公共 API:小而可用
|
||||||
|
|
||||||
|
以下是建议接口,不是现有可调用 API:
|
||||||
|
|
||||||
|
| 能力 | 第一批 API 方向 | 约束 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 命令与界面 | 注册命令、打开插件面板、通用 `/plugins/:pluginId/*` 宿主页 | 仅支持已声明的贡献;快捷键冲突可见,路由不由任意字符串注入 |
|
||||||
|
| 画布 | 读选区/选中节点、提交受校验的命令批次 | 写入走撤销栈与 revision 校验;没有整份内部 store 暴露 |
|
||||||
|
| 模型与任务 | 调用宿主已配置的文本/生成能力、订阅进度、取消 | 按请求实时校验权限、归属、配额;插件不接收原始模型密钥 |
|
||||||
|
| 资源 | 读取获授权的资源引用、上传/导入结果 | 默认不是全素材库权限;大文件走受控资源通道,不反复拷贝 base64 |
|
||||||
|
| 配置与存储 | schema 设置表单、插件私有 KV、宿主保管的秘密引用 | 用户/工作区/插件作用域隔离;配置声明不是权限授予 |
|
||||||
|
|
||||||
|
先支持命令、面板和基础设置;素材源、复杂节点渲染、时间线细粒度工具在首个闭环后扩展。高频拖拽/播放不逐帧跨 iframe RPC:由宿主渲染基本节点/时间线,通过批量命令和事件快照交换数据。
|
||||||
|
|
||||||
|
### 5.3 Manifest 与 SDK
|
||||||
|
|
||||||
|
- 在现有 v1/v2 基础上梳理合同,不为宣传而先发 v3;仅在真实破坏性变更时升级主版本。
|
||||||
|
- 区分包版本、Manifest 格式版本、Host API 版本、插件数据 schema 版本。
|
||||||
|
- 增加宿主 API 兼容范围、目标运行环境、按需激活事件、网络域名及权限需求等合同;无法支持的必要 runtime 必须明确拒绝激活。
|
||||||
|
- 插件来源与信任由安装渠道和管理员策略确定;不能信任清单里作者自填的 `trusted`、`official` 或“自动授予权限”。
|
||||||
|
- 用共享 JSON Schema/协议定义生成或对照校验 TS 与 Go 合同,避免前端枚举不含 rpc、后端已经执行 rpc 这类漂移。
|
||||||
|
- SDK、打包工具与开发宿主必须能脱离主仓库使用;首期可放同一 monorepo,验收必须从独立目录完成,不能用目录位置冒充独立性。
|
||||||
|
|
||||||
|
建议工具目标:初始化模板、校验包、开发连接、合同测试、打包、发布。**本报告没有创建这些 CLI 或命令。**
|
||||||
|
|
||||||
|
### 5.4 生命周期必须是真的,而不是 toggle 字段
|
||||||
|
|
||||||
|
建议状态:`installed → validated → awaiting-grant → disabled/activating → active → stopping → disabled`,另有 `failed / quarantined / incompatible`。
|
||||||
|
|
||||||
|
- `activate(context)` 注册贡献并返回可释放句柄;失败时回滚本次所有注册,不能半激活。
|
||||||
|
- `deactivate()` 释放事件、定时器、面板、Worker、任务订阅;宿主在超时后强制终止实例。
|
||||||
|
- “安装成功”“用户已启用”“runtime 就绪”“某贡献可用”分开呈现,不能用统一 enabled 掩盖未支持 runtime。
|
||||||
|
- 升级先验证目标版本和新增权限,再切换;失败恢复旧版本引用。
|
||||||
|
- 运行中任务绑定插件版本与包摘要,升级不让旧任务半途换适配器。支付可先继续采用已有未完成订单阻止升级的保守策略。
|
||||||
|
- 卸载要做引用检查。画布中已有插件节点保留数据与不可用占位,不静默删除;代码回滚不意味着数据迁移自动可逆。
|
||||||
|
- 卸载与清除用户数据分开操作,后者明确授权。
|
||||||
|
- 多副本部署时,安装/升级要有共享的版本与授权真相源、并发互斥及实例间失效通知;不能只依赖当前进程锁和本地 JSON registry。小规模自部署可保留文件存储实现,但共享部署必须显式选择持久化与一致性方案;实施数据库变更时同步数据库专题与迁移方案。
|
||||||
|
|
||||||
|
### 5.5 安全边界:公开市场的发布前置条件
|
||||||
|
|
||||||
|
**Web 插件建议采用单独源的受限 iframe 与宿主消息桥。** 优先避免共享主站 Cookie 的部署方式;不向插件注入主站 token、内部 API 客户端或 store。[S5、S9]
|
||||||
|
|
||||||
|
- sandbox/CSP 组合限制脚本、外连、图片/媒体外传、嵌套框架、表单、导航、弹窗与动态代码装载。具体策略必须通过 PoC 验证,不能只设置 `connect-src` 就声称禁止外传。
|
||||||
|
- 对不透明 origin 的 frame,不能只按 origin 字符串辨识调用者;由宿主绑定 `event.source`、一次性握手及 MessagePort,再关联安装记录、用户、项目和版本。
|
||||||
|
- RPC 校验消息 schema、方法白名单、实例状态、实际授予权限、归属、revision、频率和大小;不能相信插件消息自填的 pluginId/userId。
|
||||||
|
- Worker 若用于计算,要独立约束网络、存储与 CPU/内存风险;不能将主站同源 Worker 直接等同于隔离。[S10]
|
||||||
|
|
||||||
|
**后端代码插件不能直接复制当前支付子进程模式后全面开放。** 建议首期仅批准受控作者和能力;后续建设独立低权限 runner,配置只读包、独立临时目录、资源/进程限制、按插件区分网络出口、超时杀进程组、无数据库与主服务秘密挂载。具体容器/WASM 隔离方案应以威胁建模和压测决定,不因更换语言就宣称安全。
|
||||||
|
|
||||||
|
API Key 由宿主保管。凡需代签名或供应商请求的能力,应通过受控凭据代理处理;无法避免向代码提供凭据的插件必须单独提高信任等级并明示风险。支付插件先维持严格审核,不作为开放市场试点。
|
||||||
|
|
||||||
|
## 6. 下一步迁移顺序与验收
|
||||||
|
|
||||||
|
下面是按依赖安排的阶段,**不是已确认排期**。前期由前端宿主与后端协议能力各一名工程师推进,配合测试/安全评审;先通过垂直验证再估全量工期。
|
||||||
|
|
||||||
|
| 阶段 | 交付内容 | 退出标准 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| P0:纠正边界 | 能力支持矩阵、runtime 不可用原因、贡献点与权限合同草案、更新既有预设插件 ADR 的演进边界 | 产品说明不把已上传等同于可执行;目标结构获确认 |
|
||||||
|
| P1:外部应用闭环 | 隔离 UI + RPC、通用命令/面板/设置、SDK 模板、真正生命周期、一个独立示例插件 | 未包含该插件的宿主构建可安装运行;宿主源码不变;卸载无残留 |
|
||||||
|
| P2:以迁移验证抽象 | 将提示词优化器迁出专用入口,随后验证一个陌生作者应用与声明式 Provider;逐步去掉 ID 专用设置和节点分支 | 每新增一个同类插件,宿主无专用改动;现有业务语义与权限不退化 |
|
||||||
|
| P3:受控目录 | 不可变包版本、发布者身份、签名验证、审核、兼容矩阵、升级回滚、封禁、诊断日志 | 至少有外部作者独立发布/维护的包,完整经历一次失败升级与恢复演练 |
|
||||||
|
| P4:公开市场 | 开发者提交与支持流程、搜索与分类、质量指标、分批自动更新、滥用举报与撤销 | 不可信插件隔离通过评审;安装、升级、卸载、事故处置形成闭环 |
|
||||||
|
| P5:商业化 | 再评估付费授权、订阅与用量定价、作者结算、退款/争议流程 | 先有真实使用和维护成本数据;模型调用费用与插件费用清晰分离 |
|
||||||
|
|
||||||
|
### P1 推荐样例:外部“选中文本优化”插件
|
||||||
|
|
||||||
|
使用新的测试插件 ID,在独立目录开发:
|
||||||
|
|
||||||
|
1. 安装包贡献一个命令和面板。
|
||||||
|
2. 用户主动打开,读取被授权的画布选区。
|
||||||
|
3. 通过宿主调用文本模型,接收流式结果并可取消。
|
||||||
|
4. 预览后提交画布命令,支持撤销。
|
||||||
|
5. 升级插件 UI/算法但不重新构建宿主。
|
||||||
|
6. 停用或卸载后,面板、命令和订阅全部释放,画布数据仍保留。
|
||||||
|
|
||||||
|
用测试宿主模型替身做 CI 合同测试;真实模型联调另外执行并记录,不能把模拟结果当作真实上游已通过。先不替换现有提示词优化器,待闭环通过再迁移,降低回归范围。
|
||||||
|
|
||||||
|
### 防止“再次做成配置开关”的验收门禁
|
||||||
|
|
||||||
|
- **宿主冻结**:记录一个不包含样例插件的前后端构建摘要;后续只安装新包,宿主摘要保持不变。
|
||||||
|
- **独立作者**:作者仅拿 SDK、文档和已构建宿主,不能引用 `web/src` 或后端内部 package。
|
||||||
|
- **无专用分支**:在宿主源码中搜索新插件 ID,无专用路由、配置 switch、节点分支;安装记录和通用测试数据不算硬编码。
|
||||||
|
- **陌生能力实现**:在已开放 API 范围内实现一项未预置的逻辑,而不是只换标题、图标或开关。
|
||||||
|
- **权限拒绝**:未授权、已撤权、跨用户、跨项目、伪造 pluginId、超额调用均失败,写路径不能静默降级。
|
||||||
|
- **失败隔离**:崩溃、死循环、超大消息和外连违规不破坏其他用户数据;资源耗尽测试纳入专门环境,不在生产试验。
|
||||||
|
- **完整生命周期**:安装、激活失败回滚、停用清理、升级失败恢复、卸载引用保留都有自动化测试。
|
||||||
|
|
||||||
|
## 7. 插件市场:先分发闭环,再市场规模
|
||||||
|
|
||||||
|
### 7.1 市场和宿主必须分工
|
||||||
|
|
||||||
|
市场负责发现、发布者身份、版本元数据、包分发、签名与撤销信息;影策实例负责信任策略、授权、安装、执行、业务数据和付费任务。用户的项目、素材、密钥不应为了浏览市场自动上传。
|
||||||
|
|
||||||
|
现有 `/plugins/catalog` 是可用 Provider 目录,不应原地承担所有市场责任。可以复用安装器和包格式,但发布/审核/版本仓库应有明确边界。
|
||||||
|
|
||||||
|
建议概念模型(不是本次数据库迁移):
|
||||||
|
|
||||||
|
- Publisher:身份、命名空间、维护者与账号保护状态。
|
||||||
|
- Plugin / Release:包身份、不可变版本、摘要、目标平台、Host API 范围、权限、变更说明。
|
||||||
|
- Review / Attestation / Revocation:检查结果、人工审批、签名证明、撤销原因。
|
||||||
|
- Installation / Grant / RuntimeInstance:部署范围、用户启用、实际授权、运行实例;与发布者元数据分开。
|
||||||
|
- Entitlement:未来付费权益,不与版本签名、用户权限或执行凭据混为一谈。
|
||||||
|
|
||||||
|
### 7.2 发布到安装的最小流程
|
||||||
|
|
||||||
|
```text
|
||||||
|
作者提交包和材料
|
||||||
|
→ 路径/大小/依赖/秘密/兼容性检查
|
||||||
|
→ 隔离环境安装与合同测试
|
||||||
|
→ 按风险人工审核
|
||||||
|
→ 固化版本并签名
|
||||||
|
→ 进入目录
|
||||||
|
→ 实例管理员选择版本和授权范围
|
||||||
|
→ 下载并验证摘要、签名与撤销状态
|
||||||
|
→ 激活与健康检查
|
||||||
|
```
|
||||||
|
|
||||||
|
- 摘要只证明字节一致,签名只证明来源/完整性,两者都不能证明代码无恶意。
|
||||||
|
- 新增权限、网络域名、维护者重大变更或高风险能力的更新应重新审批,不能随自动更新静默提权。
|
||||||
|
- 同一发布版本不可覆盖;依赖锁定并校验供应链,首期限制插件互相依赖的复杂度。
|
||||||
|
- 市场下架、阻止新安装、禁止激活、撤销运行实例、删除用户数据是不同动作;不能用一个“删除”按钮混在一起。
|
||||||
|
- 市场暂时不可用时,已安装、校验通过的普通插件原则上仍可运行;撤销缓存和高风险插件的离线策略应明确,不把市场服务变成所有创作任务的单点故障。
|
||||||
|
- 自部署用户保留手工安装受信包/私有目录能力;用安全策略约束,而不是强制连接公共市场。
|
||||||
|
|
||||||
|
### 7.3 冷启动与商业化
|
||||||
|
|
||||||
|
先邀请少量外部作者,优先已有用户需求的提示词/模板、批量处理、素材导入和模型适配。目录初期采用人工审核即可,不急着建设推荐算法与复杂分成。
|
||||||
|
|
||||||
|
衡量“是否形成生态”的指标应是:**独立作者成功发布率、无需宿主改动的插件比例、安装激活成功率、故障与回滚率、用户持续使用率、作者维护响应**,不是插件卡片数量。门槛目标在试点后设定,不拿本次 80 个包当生态成绩。
|
||||||
|
|
||||||
|
付费市场至少区分插件授权费、模型上游费用、宿主资源成本、第三方服务订阅。先以使用数据验证价值和成本,再设计定价与结算;具体税务、支付合规和法律条款另行专业评估,本报告不作结论。
|
||||||
|
|
||||||
|
## 8. 风险与明确不做的事
|
||||||
|
|
||||||
|
- 不推倒现有 Provider DSL;先收敛通用协议,复杂转换有证据后再引入代码运行时,避免 DSL 无限膨胀成难维护的语言。
|
||||||
|
- 不把“八个内部组件”作为“八个第三方可装插件”的交付。
|
||||||
|
- 不立即把支付、权限、数据库或账务写接口开放给公共市场插件。
|
||||||
|
- 不使用 `eval`、主页面远程脚本注入或仅改名为 sandbox 的执行器来补 Web runtime。
|
||||||
|
- 不将模型协议、UI 插件、市场各做一套互不兼容的身份和生命周期。
|
||||||
|
- 不一次迁移全部内置功能;先用一个真实外部插件证明边界,再逐个清除专用依赖。
|
||||||
|
- 不用更多 helper、更多 Manifest 字段和更多启停按钮替代运行时、SDK 与治理能力。
|
||||||
|
|
||||||
|
## 9. 本次验证记录与边界
|
||||||
|
|
||||||
|
环境:Go `1.25.6 darwin/arm64`;仓库要求 Go `1.25.0`。未启动开发服务器,未调用真实模型/支付上游,未安装外部依赖。
|
||||||
|
|
||||||
|
在 `backend/` 执行的最小测试均通过:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go test ./internal/protocol -run 'Test(ParsePluginPackage|DeclarativeManifest|ManifestAgentMapsRequestAndResponse|ManifestMapsSynchronousTextResponse)' -count=1
|
||||||
|
go test ./internal/payment -run 'TestRPCProvider' -count=1
|
||||||
|
go test ./internal/service -run 'Test(ApplicationPluginUsesUserStateUnderPlatformAvailability|UploadedManifestCannotClaimUserActivationScope|ArtCritiqueIsUserToggleableApplication|PaymentPluginUpgradeBlockedByActiveOrders|PaymentPluginRemovalAllowedAfterOrdersFinish)$' -count=1
|
||||||
|
```
|
||||||
|
|
||||||
|
分别验证已有包合同/声明式映射、支付 RPC 合同/错误处理、应用启用策略/支付生命周期守卫。服务测试使用测试内存数据库或临时目录,没有迁移用户数据库。
|
||||||
|
|
||||||
|
这些结果**不覆盖**:外部 Web 插件浏览器运行、公开市场安全、全部供应商联调、真实支付成功率、线上安装状态、多实例并发安装一致性。没有把静态检索写成浏览器验证,也没有执行与本次调研无关的全量构建。
|
||||||
|
|
||||||
|
## 10. 外部一手资料
|
||||||
|
|
||||||
|
本次联网搜索工具没有返回可用正文,随后直接获取以下官方页面/仓库内容(HTTP 200)并核对相关段落;不是基于搜索摘要或第三方转载。失效页面与只有空壳内容的页面未作为证据。以下来源的总结限于本报告引用的机制,不代表对产品整体安全性的评级。
|
||||||
|
|
||||||
|
| 来源 | 标题 | 官方地址 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| S1 | VS Code — Extension Host | `https://code.visualstudio.com/api/advanced-topics/extension-host` |
|
||||||
|
| S2 | VS Code — Contribution Points | `https://code.visualstudio.com/api/references/contribution-points` |
|
||||||
|
| S3 | VS Code — Web Extensions | `https://code.visualstudio.com/api/extension-guides/web-extensions` |
|
||||||
|
| S4 | VS Code — Extension Runtime Security | `https://code.visualstudio.com/docs/configure/extensions/extension-runtime-security` |
|
||||||
|
| S5 | Figma — How Plugins Run | `https://developers.figma.com/docs/plugins/how-plugins-run/` |
|
||||||
|
| S6 | Dify — Dify Plugin | `https://docs.dify.ai/en/develop-plugin/getting-started/getting-started-dify-plugin` |
|
||||||
|
| S7 | Dify Plugin Daemon — README | `https://raw.githubusercontent.com/langgenius/dify-plugin-daemon/main/README.md` |
|
||||||
|
| S8 | Dify — Publish to Dify Marketplace | `https://docs.dify.ai/en/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace` |
|
||||||
|
| S9 | MDN — iframe element | `https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/iframe` |
|
||||||
|
| S10 | MDN — Using Web Workers | `https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers` |
|
||||||
|
|
||||||
|
**最终建议:批准 P0/P1 的范围与验收标准,先交付一个主程序完全不认识、但能通过公共 SDK 正常运行的外部应用插件。用这个事实回应用户,再建设市场。**
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
## 设计沉淀
|
## 设计沉淀
|
||||||
|
|
||||||
|
- [插件平台与市场演进调研](design/plugin-platform-and-marketplace-research.md):插件机制代码审计、对外回应、外部 SDK 与隔离运行时、独立插件验收、受控目录到公开市场的分阶段方案(调研建议,未实施)。
|
||||||
|
|
||||||
- [站点及外观与皮肤主题设计合同](design/site-appearance-and-skins.mdx):品牌一致性、登录页与邮件、SEO/备案、三层皮肤令牌、无闪屏启动顺序和验收边界。
|
- [站点及外观与皮肤主题设计合同](design/site-appearance-and-skins.mdx):品牌一致性、登录页与邮件、SEO/备案、三层皮肤令牌、无闪屏启动顺序和验收边界。
|
||||||
|
|
||||||
- [工作区外壳设计沉淀](design/workspace-shell-design.mdx):侧栏(260px 可折叠导航 + 分组折叠)、主区卡片、顶部栏(账户/公告/主题)的设计决策与样式约束。
|
- [工作区外壳设计沉淀](design/workspace-shell-design.mdx):侧栏(260px 可折叠导航 + 分组折叠)、主区卡片、顶部栏(账户/公告/主题)的设计决策与样式约束。
|
||||||
|
|||||||
Reference in New Issue
Block a user