沙箱边界(宿主保证的)
| 你的代码 | 运行在 | 能碰到 | 碰不到 |
|---|---|---|---|
main.js(命令) |
隐藏的 <iframe sandbox="allow-scripts"> 里的 Web Worker;opaque origin;CSP default-src 'none'; connect-src 'none' |
宿主交进来的 ctx(按权限、按模式、按调用裁剪) |
网络、应用的 DOM / 存储 / 登录态、别的插件、Node / Electron API |
panel.html(面板) |
<iframe sandbox="allow-scripts">;opaque origin;CSP 禁网、禁外部资源、禁嵌套页面、禁表单 |
本插件的命令(run)与少数宿主动作 |
同上;另外不能导航(主进程拦截)、不能弹窗 |
ctx的每个能力调用都回到宿主执行:宿主再校验一遍(权限、模式、日历归属、存储规则、网络白名单与 SSRF 防护), 插件代码里「绕过」SDK 没有意义。- 能力随一次调用结束作废;超时(describe 20 秒、run 3 分钟、undo 90 秒)的沙箱会被拆掉重建;连续崩溃停用到下次启动。
- 模型发起的写命令必须经用户在确认卡片上确认;第三方插件的工具说明在工具清单里标注来源;第三方面板的「问 UniMind」要用户点发送; 第三方面板的通知带插件名。
- 已知的残余风险(如实写出):面板里仍可用 WebRTC 这类不受 CSP 管的通道;插件拿到的数据(在权限范围内)理论上可经这类通道带出。 所以请求的权限本身就是信任边界:高风险权限会在安装时标红,用户据此决定装不装。
必须遵守的规则(违反会被拒绝上架 / 撤下)
- 最小权限:只声明真正用到的权限;联网必须写
networkHosts,除非功能本身就是「访问用户给的任意地址」(例如日历订阅)。 - 不外传用户数据:通过
net发出去的请求里不得夹带课程、作业、成绩、日历、存储里的数据,除非这正是用户为之安装插件的功能、 且在 README 与安装说明里写明了发往哪里、发什么。 - 确认卡片说实话:
describe必须完整说明将要改什么;不得隐藏真实动作、不得在确认之后做确认卡片上没写的写入。 - 插值必清洗:确认卡片、通知里的动态内容一律
clean()。 - 给模型的说明不得操纵模型:description 只描述工具本身;不得出现「忽略之前的指令」「总是先调用本工具」「不要告诉用户」等措辞; 命令结果里不得夹带指令性文字。
- 不假冒:插件名、图标、文案不得冒充 UniFlow 官方功能或其他插件;通知不得伪造系统提示(登录过期、付费等)。
- 尊重用户的数据:删除要可恢复(软删除或撤销);后台任务不做用户没同意过的事;超时 / 读不到数据时不删任何东西。
- 不做混淆:
main.js可以压缩,但不得刻意混淆(审核要能读懂);不得在运行时拼接、下载代码(沙箱也不允许)。 - 隐私说明:README 里写明插件保存了什么数据、在哪里(云端 / 本机)、是否联网及发往哪里。
审核清单(提交前自查)
-
uniflow-plugin validate通过;npm test通过;在应用里(开发者模式)完整走过每个命令与面板 - 每个权限都能说出用在哪个命令的哪一步
- 每个写命令:describe 写清楚要改什么、在 describe 里就拒绝做不了的情况、能撤销的都实现了 undo
- 给模型的命令 ≤ 10 个,description 写清楚何时用、参数、结果、上限;结果有字符预算
- 读改写按对象串行;超时 / 失败不删数据
- 面板:空状态、加载中、错误(可重试)、窄宽度、深浅色都检查过;不可逆操作有行内确认
- en / zh 文案齐全;README、CHANGELOG、icon 齐全;版本号升了