mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-16 07:33:06 +08:00
Extend the local plugin system's host<->plugin contract with generic, capability-neutral facilities, so transport plugins can be built on top without embedding plugin-specific logic in the host. Host services (plugin dials a broker-provided HostService gRPC): - per-plugin namespaced KV store (key/value size and TTL bounded) - account directory: ListAccounts + ResolveOutboundIdentity, restricted to the accounts a plugin's declared capability already covers - InitHostServices lifecycle hook; plugins that don't implement it run unchanged and are simply offered no host services Read-only runtime status channel: - HealthResponse gains an opaque, plugin-defined status_json produced passively (no config apply, no upstream call, no side effects) - GET /admin/plugins/:id/status (ungated) and the plugin.status UI-bridge verb map to Health, so a status UI can poll live state without a step-up prompt or a "test" side effect - config.test no longer force-shows a host success toast; the plugin UI owns result presentation, so plugins that read status do not spam toasts Document the UI-bridge verb taxonomy (read vs mutate/test gating) and the status contract under pkg/pluginapi.
60 lines
2.0 KiB
Markdown
60 lines
2.0 KiB
Markdown
# UI Bridge v1
|
||
|
||
## 加载方式
|
||
|
||
宿主为每次打开配置页创建短时 UI 会话:
|
||
|
||
```text
|
||
/api/v1/plugin-ui/<asset-token>/index.html#bridge_token=<bridge-token>
|
||
```
|
||
|
||
资源 Token 用于读取包内 `ui/` 文件,Bridge Token 只存在于 URL fragment,不会发送到服务器。iframe 使用 `sandbox="allow-scripts"`,不授予 `allow-same-origin`。
|
||
|
||
UI 只能加载包内、已在清单声明的资源。CSP 禁止外部网络连接、表单提交和外部 frame。
|
||
|
||
## 消息信封
|
||
|
||
UI 到宿主:
|
||
|
||
```json
|
||
{
|
||
"source": "sub2api-plugin-ui",
|
||
"bridge_token": "TOKEN",
|
||
"type": "config.load",
|
||
"request_id": "UNIQUE_ID"
|
||
}
|
||
```
|
||
|
||
宿主到 UI:
|
||
|
||
```json
|
||
{
|
||
"source": "sub2api-plugin-host",
|
||
"bridge_token": "TOKEN",
|
||
"request_id": "UNIQUE_ID",
|
||
"ok": true
|
||
}
|
||
```
|
||
|
||
## 方法
|
||
|
||
| `type` | UI 参数 | 成功响应 |
|
||
|---|---|---|
|
||
| `sub2api.plugin.ready` | 无 | 无响应 |
|
||
| `config.load` | 无 | `config` |
|
||
| `config.save` | `config` 对象 | 规范化后的 `config` |
|
||
| `config.test` | 无 | `result` |
|
||
| `plugin.status` | 无 | `result`(`Health`:`{healthy, message, status_json}`) |
|
||
| `ui.resize` | `height` | 无响应 |
|
||
| `ui.notify` | `level`、`message` | 无响应 |
|
||
|
||
`config.test` 在 v1 中测试已保存配置(需二次验证,可产生副作用)。UI 若要测试当前表单,应先调用 `config.save`。
|
||
|
||
`plugin.status` 是只读运行时状态通道:无副作用、免二次验证、不弹宿主提示,供状态面板轮询。它映射到插件 `Health`,`result.status_json` 是插件自定义的不透明 JSON 快照。带状态展示的插件应使用它,而不是把 `config.test` 当作状态轮询。
|
||
|
||
## 必须执行的校验
|
||
|
||
UI 接收消息时必须验证 `event.source === parent`、消息来源标识、Bridge Token 和等待中的 `request_id`。每个请求必须有超时和卸载清理。
|
||
|
||
宿主不会向 iframe 提供管理员 Token。插件 UI 不得尝试访问管理 API、Cookie、父页面 DOM 或浏览器存储中的宿主数据。
|