Files
sub2api/backend/pkg/pluginapi/docs/ui-bridge.md
T
shaw c63bd14a02 feat(plugin): generic host services + read-only status bridge channel
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.
2026-09-19 11:25:56 +08:00

60 lines
2.0 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.
# 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 或浏览器存储中的宿主数据。