Files
ttstd-infinite-canvas/docs/design/plugin-platform-and-marketplace-research.md
2026-09-14 01:11:56 +08:00

315 lines
28 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 插件机制现状、对外回应与插件市场演进调研
> 状态:调研与建议,未实施;不是现有能力承诺。
> 基线:2026-09-06,本地工作区 HEAD `df94c3bd`。未修改运行时代码、部署、数据库或现有用户文件。
> 范围:影策内部的 Provider、应用/UI、编辑器与支付插件。旧版 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 正常运行的外部应用插件。用这个事实回应用户,再建设市场。**