@clipbus/plugin-sdk 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +641 -0
- package/LICENSE +21 -0
- package/README.md +466 -0
- package/SPECIFICATION.md +355 -0
- package/dist/dom/autoFit.d.ts +15 -0
- package/dist/dom/consolePatch.d.ts +1 -0
- package/dist/dom/index.cjs +211 -0
- package/dist/dom/index.d.cts +6 -0
- package/dist/dom/index.d.ts +6 -0
- package/dist/dom/index.js +188 -0
- package/dist/dom/textInputState.d.ts +1 -0
- package/dist/dom/topicAdapter.d.ts +30 -0
- package/dist/generated/INDEX.runtime.generated.d.ts +6 -0
- package/dist/generated/INDEX.ui.generated.d.ts +4 -0
- package/dist/generated/capabilityClients.generated.d.ts +199 -0
- package/dist/generated/data.generated.d.ts +193 -0
- package/dist/generated/hostClients.generated.d.ts +38 -0
- package/dist/generated/runtime.actionResult.generated.d.ts +28 -0
- package/dist/generated/runtime.definePlugin.generated.d.ts +16 -0
- package/dist/generated/runtime.handlers.generated.d.ts +20 -0
- package/dist/generated/runtime.host.generated.d.ts +34 -0
- package/dist/generated/topicSubscribers.generated.d.ts +32 -0
- package/dist/generated/ui.bootstrap.generated.d.ts +15 -0
- package/dist/generated/ui.clipbus.generated.d.ts +79 -0
- package/dist/generated/wireConstants.generated.d.ts +3 -0
- package/dist/internal/capabilities.d.ts +31 -0
- package/dist/internal/index.cjs +68 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/internalConsole.d.ts +7 -0
- package/dist/internal/ipcBus.d.ts +48 -0
- package/dist/internal/runtimeInvokeClient.d.ts +3 -0
- package/dist/internal/topic.d.ts +20 -0
- package/dist/runtime/defineMessage.d.ts +6 -0
- package/dist/runtime/index.cjs +163 -0
- package/dist/runtime/index.d.cts +4 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +132 -0
- package/dist/shared/defineMessage.d.ts +7 -0
- package/dist/ui/defineMessage.d.ts +7 -0
- package/dist/ui/index.cjs +362 -0
- package/dist/ui/index.d.cts +4 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +339 -0
- package/docs/README.md +34 -0
- package/docs/authoring.md +288 -0
- package/docs/capability-detection.md +105 -0
- package/docs/concepts.md +80 -0
- package/docs/entry.md +137 -0
- package/docs/faq.md +65 -0
- package/docs/item-context.md +186 -0
- package/docs/manifest.md +149 -0
- package/docs/permissions.md +32 -0
- package/docs/rpc.md +84 -0
- package/package.json +76 -0
package/docs/manifest.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# manifest.json 规范
|
|
2
|
+
|
|
3
|
+
> 本文档属于 @clipbus/plugin-sdk 开发文档 · 返回[文档地图](./README.md) · capability 真相源见 [API.md](../API.md)
|
|
4
|
+
|
|
5
|
+
每个 Clipbus 插件的根目录必须包含一个 `manifest.json`,宿主在加载插件时读取该文件以确定身份、入口和能力声明。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 顶层字段
|
|
10
|
+
|
|
11
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `schemaVersion` | `number` | 是 | 固定 `2` |
|
|
14
|
+
| `plugin` | `object` | 是 | 插件身份信息 |
|
|
15
|
+
| `install` | `object` | 否 | 安装期 hook 配置 |
|
|
16
|
+
| `runtime` | `object` | 是 | runtime 与 UI 根目录 |
|
|
17
|
+
| `permissions` | `string[]` | 否 | mutation 权限声明(缺省 `[]`) |
|
|
18
|
+
| `attachmentRenderers` | `object[]` | 否 | attachment renderer 列表 |
|
|
19
|
+
| `detectors` | `object[]` | 否 | detector 列表 |
|
|
20
|
+
| `actions` | `object[]` | 否 | action 列表 |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## `plugin`
|
|
25
|
+
|
|
26
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
27
|
+
|---|---|---|---|
|
|
28
|
+
| `plugin.id` | `string` | 是 | 稳定命名空间,建议反向域名(`plugin.example.demo`) |
|
|
29
|
+
| `plugin.title` | `string` | 是 | 显示名称 |
|
|
30
|
+
| `plugin.version` | `string` | 是 | 版本号;宿主按字符串处理 |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## `install`(可选)
|
|
35
|
+
|
|
36
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
37
|
+
|---|---|---|---|
|
|
38
|
+
| `install.runtime` | `'node' \| 'bash'` | 是 | 安装脚本运行时 |
|
|
39
|
+
| `install.entry` | `string` | 是 | 脚本路径,相对插件根目录,不允许逃出 |
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## `runtime`
|
|
44
|
+
|
|
45
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| `runtime.nodeEntry` | `string` | 是 | Node runtime 入口(编译后 `.cjs`) |
|
|
48
|
+
| `runtime.uiRoot` | `string` | 是 | UI 根目录;所有 `uiEntry` 相对此目录 |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## `permissions`
|
|
53
|
+
|
|
54
|
+
仅 4 个合法值:`setTags`、`setPinned`、`setAttachment`、`setSearchExtension`。声明哪个就解锁哪组 runtime mutation verb;其余 verb(clipboard、navigation、settings 读、console、attachment 读取、图片临时路径等)默认就能调。
|
|
55
|
+
|
|
56
|
+
完整的权限-到-verb 映射、声明示例与最小权限原则见 [permissions.md](./permissions.md)。
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## `attachmentRenderers[]`
|
|
61
|
+
|
|
62
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| `id` | `string` | 是 | 局部 ID,同插件内唯一 |
|
|
65
|
+
| `title` | `string` | 是 | 显示名称 |
|
|
66
|
+
| `attachmentType` | `string` | 是 | 该 renderer 负责的 attachment type,建议 `plugin.id + "."` 前缀 |
|
|
67
|
+
| `height` | `number \| "auto" \| { min, max }` | 否 | 卡片高度策略,见下 |
|
|
68
|
+
| `uiEntry` | `string` | 否 | HTML 入口,相对 `runtime.uiRoot` |
|
|
69
|
+
|
|
70
|
+
**height 三种形态:**
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{ "height": 320 } // 固定高度(1–800 px)
|
|
74
|
+
{ "height": "auto" } // 自适应,默认范围 [80, 800]
|
|
75
|
+
{ "height": { "min": 120, "max": 480 } } // 有界范围
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
省略 `height` 等价于 `{ "min": 80, "max": 400 }`。`"auto"` 与 `{ min, max }` 下,**UI 必须显式调用 `clipbus.window.autoFit()`**——SDK 不会自动启动。
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## `detectors[]`
|
|
83
|
+
|
|
84
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
85
|
+
|---|---|---|---|
|
|
86
|
+
| `id` | `string` | 是 | 局部 ID |
|
|
87
|
+
| `title` | `string` | 是 | 显示名称 |
|
|
88
|
+
| `supportedInputKinds` | `string[]` | 是 | `'text' \| 'image' \| 'path_reference'`;非空 |
|
|
89
|
+
| `attachmentTypes` | `string[]` | 是 | 可能产出的 attachment type;每项须在 `attachmentRenderers[]` 中有对应 renderer |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## `actions[]`
|
|
94
|
+
|
|
95
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
96
|
+
|---|---|---|---|
|
|
97
|
+
| `id` | `string` | 是 | 局部 ID |
|
|
98
|
+
| `title` | `string` | 是 | 显示名称 |
|
|
99
|
+
| `supportedItemTypes` | `string[]` | 是 | `'text' \| 'image' \| 'path_reference'`;非空 |
|
|
100
|
+
| `lifecycle` | `'auto-run' \| 'draft'` | 是 | action 生命周期 |
|
|
101
|
+
| `keywords` | `string[]` | 否 | Action catalog 搜索关键词 |
|
|
102
|
+
| `uiEntry` | `string` | 否 | `lifecycle: 'draft'` 时必填 |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 最小完整示例
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"schemaVersion": 2,
|
|
111
|
+
"plugin": {
|
|
112
|
+
"id": "plugin.example.sample",
|
|
113
|
+
"title": "Sample Plugin",
|
|
114
|
+
"version": "0.1.0"
|
|
115
|
+
},
|
|
116
|
+
"runtime": {
|
|
117
|
+
"nodeEntry": "dist/runtime/index.cjs",
|
|
118
|
+
"uiRoot": "dist/ui"
|
|
119
|
+
},
|
|
120
|
+
"permissions": ["setTags"],
|
|
121
|
+
"attachmentRenderers": [
|
|
122
|
+
{
|
|
123
|
+
"id": "sample-card",
|
|
124
|
+
"title": "Sample Card",
|
|
125
|
+
"attachmentType": "plugin.example.sample.card",
|
|
126
|
+
"height": 320,
|
|
127
|
+
"uiEntry": "renderers/sample/index.html"
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"detectors": [
|
|
131
|
+
{
|
|
132
|
+
"id": "sample-detector",
|
|
133
|
+
"title": "Sample Detector",
|
|
134
|
+
"supportedInputKinds": ["text"],
|
|
135
|
+
"attachmentTypes": ["plugin.example.sample.card"]
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
"actions": [
|
|
139
|
+
{
|
|
140
|
+
"id": "sample-apply",
|
|
141
|
+
"title": "Apply Sample",
|
|
142
|
+
"supportedItemTypes": ["text"],
|
|
143
|
+
"lifecycle": "draft",
|
|
144
|
+
"keywords": ["sample", "apply"],
|
|
145
|
+
"uiEntry": "actions/sample/index.html"
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 权限模型
|
|
2
|
+
|
|
3
|
+
> 本文档属于 @clipbus/plugin-sdk 开发文档 · 返回[文档地图](./README.md) · capability 真相源见 [API.md](../API.md)
|
|
4
|
+
|
|
5
|
+
## manifest 声明
|
|
6
|
+
|
|
7
|
+
在插件 manifest 的 `permissions` 字段列出插件需要的权限:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{ "permissions": ["setTags", "setPinned"] }
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
未声明的权限对应方法在宿主侧 reject。manifest 结构详见 [manifest.md](./manifest.md)。
|
|
14
|
+
|
|
15
|
+
## 受门控的 Verb
|
|
16
|
+
|
|
17
|
+
以下 `host.*` verb 需要在 manifest 中显式声明对应权限才能调用:
|
|
18
|
+
|
|
19
|
+
| 权限 | runtime Verb |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `setTags` | `host.item.setTags` / `addTags` / `removeTags` |
|
|
22
|
+
| `setPinned` | `host.item.setPinned` |
|
|
23
|
+
| `setAttachment` | `host.item.setAttachments` |
|
|
24
|
+
| `setSearchExtension` | `host.item.setSearchExtension` |
|
|
25
|
+
|
|
26
|
+
**不受门控:** `host.clipboard.*`、`host.navigation.*`、`host.settings.*`(只读)、`host.console.log`、`host.action.allocateImageTempPath`、`host.item.materializeImagePath`、`host.item.readAttachment`、所有 `clipbus.*` 中的 UI 专属 verb(`window.*`、`action.setButtons`、`action.complete`、`attachmentRenderer.setButtons` 等)。
|
|
27
|
+
|
|
28
|
+
各 verb 的完整签名见 [API.md](../API.md)。
|
|
29
|
+
|
|
30
|
+
## 最小权限原则
|
|
31
|
+
|
|
32
|
+
只声明真正会调的权限。多声明不会导致功能异常,但会在宿主权限审查中显得可疑。
|
package/docs/rpc.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# UI ↔ Runtime RPC
|
|
2
|
+
|
|
3
|
+
> 本文档属于 @clipbus/plugin-sdk 开发文档 · 返回[文档地图](./README.md) · capability 真相源见 [API.md](../API.md)
|
|
4
|
+
|
|
5
|
+
让 UI 调用插件自己的 Node runtime 逻辑,无需写 native 桥接。
|
|
6
|
+
|
|
7
|
+
## 直接接口
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { clipbus } from '@clipbus/plugin-sdk/ui';
|
|
11
|
+
|
|
12
|
+
// clipbus.runtime.invoke<TResp> 直接返回 TResp(SDK 已自动解 wire envelope)
|
|
13
|
+
const { title } = await clipbus.runtime.invoke<{ title: string }>({
|
|
14
|
+
key: 'fetch-title',
|
|
15
|
+
payload: { url: 'https://example.com' },
|
|
16
|
+
timeoutMs: 10_000, // 可选;默认 30_000 ms
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Runtime 端:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
const { definePlugin } = require('@clipbus/plugin-sdk/runtime');
|
|
24
|
+
|
|
25
|
+
module.exports = definePlugin({
|
|
26
|
+
messageHandlers: {
|
|
27
|
+
'fetch-title': async (req, ctx) => {
|
|
28
|
+
const html = await fetch(req.url).then(r => r.text());
|
|
29
|
+
return { title: html.match(/<title>(.*?)<\/title>/)?.[1] ?? '' };
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## `defineMessage` —— 两端共享契约(推荐写法)
|
|
36
|
+
|
|
37
|
+
`defineMessage<TReq, TResp>(key)` 把字符串 key + 类型一起钉死,两端导入同一契约:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
// shared/contracts.ts —— 仅做类型,避免拼字符串
|
|
41
|
+
import { defineMessage } from '@clipbus/plugin-sdk/runtime'; // 或 /ui,类型完全相同
|
|
42
|
+
export const FetchTitle = defineMessage<{ url: string }, { title: string }>('fetch-title');
|
|
43
|
+
|
|
44
|
+
// runtime/index.ts
|
|
45
|
+
const { definePlugin } = require('@clipbus/plugin-sdk/runtime');
|
|
46
|
+
const { FetchTitle } = require('../shared/contracts');
|
|
47
|
+
|
|
48
|
+
module.exports = definePlugin({
|
|
49
|
+
messageHandlers: Object.fromEntries([
|
|
50
|
+
FetchTitle.handle(async (req, ctx) => {
|
|
51
|
+
const html = await fetch(req.url).then(r => r.text());
|
|
52
|
+
return { title: html.match(/<title>(.*?)<\/title>/)?.[1] ?? '' };
|
|
53
|
+
}),
|
|
54
|
+
]),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// ui/app.ts
|
|
58
|
+
import { FetchTitle } from '../shared/contracts';
|
|
59
|
+
const { title } = await FetchTitle.invoke({ url: 'https://example.com' }, { timeoutMs: 10_000 });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 超时与错误
|
|
63
|
+
|
|
64
|
+
- 默认超时 **30 秒**;用 `options.timeoutMs` 覆盖
|
|
65
|
+
- handler 中 `throw` 一个 Error,UI 侧 `await` reject,`name` 与 `data` 跨进程保留:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
// runtime 端
|
|
69
|
+
throw Object.assign(new Error('rate limited'), {
|
|
70
|
+
name: 'RateLimitError',
|
|
71
|
+
data: { retryAfterSec: 60 },
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// UI 端
|
|
75
|
+
try {
|
|
76
|
+
await FetchTitle.invoke({ url });
|
|
77
|
+
} catch (err: any) {
|
|
78
|
+
if (err.name === 'RateLimitError') {
|
|
79
|
+
console.log('retry in', err.data.retryAfterSec, 's');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- **不**支持通过此通道传图片字节(参见 [item-context.md](./item-context.md))
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@clipbus/plugin-sdk",
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Typed SDK for authoring Clipbus plugins — runtime (Node.js) and UI (WebView) helpers generated from the Clipbus plugin wire contract.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"clipbus",
|
|
8
|
+
"plugin",
|
|
9
|
+
"sdk"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/scubers/clipbus.git",
|
|
15
|
+
"directory": "packages/plugin-sdk"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18.0.0"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/runtime/index.cjs",
|
|
21
|
+
"exports": {
|
|
22
|
+
"./runtime": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./dist/runtime/index.d.ts",
|
|
25
|
+
"default": "./dist/runtime/index.js"
|
|
26
|
+
},
|
|
27
|
+
"require": {
|
|
28
|
+
"types": "./dist/runtime/index.d.cts",
|
|
29
|
+
"default": "./dist/runtime/index.cjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"./ui": {
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/ui/index.d.ts",
|
|
35
|
+
"default": "./dist/ui/index.js"
|
|
36
|
+
},
|
|
37
|
+
"require": {
|
|
38
|
+
"types": "./dist/ui/index.d.cts",
|
|
39
|
+
"default": "./dist/ui/index.cjs"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"./dom": {
|
|
43
|
+
"import": {
|
|
44
|
+
"types": "./dist/dom/index.d.ts",
|
|
45
|
+
"default": "./dist/dom/index.js"
|
|
46
|
+
},
|
|
47
|
+
"require": {
|
|
48
|
+
"types": "./dist/dom/index.d.cts",
|
|
49
|
+
"default": "./dist/dom/index.cjs"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"prepare": "node ./scripts/build.mjs",
|
|
55
|
+
"build": "node ./scripts/build.mjs",
|
|
56
|
+
"pretest": "node ./scripts/build.mjs",
|
|
57
|
+
"test": "node --require ./tests/setup.cjs --test 'tests/**/*.test.cjs'",
|
|
58
|
+
"prepublishOnly": "npm run build && npm test"
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"dist",
|
|
62
|
+
"SPECIFICATION.md",
|
|
63
|
+
"README.md",
|
|
64
|
+
"API.md",
|
|
65
|
+
"docs"
|
|
66
|
+
],
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/node": "^25.9.0",
|
|
72
|
+
"esbuild": "^0.25.0",
|
|
73
|
+
"jsdom": "^25.0.0",
|
|
74
|
+
"typescript": "^5.0.0"
|
|
75
|
+
}
|
|
76
|
+
}
|