@clipbus/plugin-sdk 0.9.6 → 0.9.8
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 +0 -2
- package/README.md +13 -5
- package/SPECIFICATION.md +7 -3
- package/dist/generated/data.generated.d.ts +0 -2
- package/dist/validate/index.cjs +5 -5
- package/dist/validate/index.js +5 -5
- package/docs/authoring.md +7 -4
- package/docs/manifest.md +9 -8
- package/docs/preview.md +1 -1
- package/package.json +1 -1
package/API.md
CHANGED
|
@@ -505,7 +505,6 @@ export interface PluginRegistry {
|
|
|
505
505
|
|
|
506
506
|
- `attachmentKey`: `string`
|
|
507
507
|
- `payloadJson`: `string`
|
|
508
|
-
- `syncScope`: `string`
|
|
509
508
|
- `createdAtMs?`: `int`
|
|
510
509
|
- `updatedAtMs?`: `int`
|
|
511
510
|
|
|
@@ -663,7 +662,6 @@ Discriminated union on `kind`: { kind: `'text'`, text: `string` } | { kind: `'im
|
|
|
663
662
|
- `attachmentKey`: `string`
|
|
664
663
|
- `payloadJson`: `string`
|
|
665
664
|
- `searchProjection?`: [`PluginDetectorSearchProjection`](#plugindetectorsearchprojection)
|
|
666
|
-
- `attachmentSyncScope?`: `string`
|
|
667
665
|
- `createdAtMs?`: `int`
|
|
668
666
|
- `updatedAtMs?`: `int`
|
|
669
667
|
|
package/README.md
CHANGED
|
@@ -55,6 +55,9 @@ module.exports = definePlugin({
|
|
|
55
55
|
### `actionResult.text(value, options?)`
|
|
56
56
|
|
|
57
57
|
Returns a locked `{ result: { resultKind: 'text', text }, userMessage }` shape.
|
|
58
|
+
When returned by an auto-run Action, or submitted by a Draft Action through
|
|
59
|
+
`clipbus.action.complete(...)`, a successful value can be explicitly advanced
|
|
60
|
+
by the user as the next Action input.
|
|
58
61
|
|
|
59
62
|
| Param | Type | Description |
|
|
60
63
|
|---|---|---|
|
|
@@ -80,7 +83,8 @@ Returns a locked `{ result: { resultKind: 'image', imageTempPath, imageFormatHin
|
|
|
80
83
|
Returns a safe path-reference result. Entries must either reuse a current input
|
|
81
84
|
entry (`{source: 'input', inputIndex}`) or reference a path allocated by
|
|
82
85
|
`ctx.host.action.allocateOutputFilePath()` (`{source: 'allocated_file', path, displayName}`).
|
|
83
|
-
Arbitrary filesystem paths are rejected by the host.
|
|
86
|
+
Arbitrary filesystem paths are rejected by the host. Like text and image,
|
|
87
|
+
`path_reference` is a value result that the user can explicitly advance.
|
|
84
88
|
|
|
85
89
|
---
|
|
86
90
|
|
|
@@ -89,9 +93,13 @@ Arbitrary filesystem paths are rejected by the host.
|
|
|
89
93
|
Action handlers receive `{ sourceItem, content, attachments }`.
|
|
90
94
|
`sourceItem` remains the original clipboard item identity used by item mutation
|
|
91
95
|
verbs; `content` is the current cascade value and may change kind after every
|
|
92
|
-
|
|
93
|
-
is currently always `[]` in SDK 0.9.0. Draft
|
|
94
|
-
|
|
96
|
+
Action step. The Action `attachments` field is reserved for wire stability and
|
|
97
|
+
is currently always `[]` in SDK 0.9.0. Successful Draft results with `text`,
|
|
98
|
+
`image`, or `path_reference` are shown for confirmation and can be explicitly
|
|
99
|
+
advanced by the user; `none` remains non-continuable. Completion never
|
|
100
|
+
auto-advances or implicitly selects another Action. This is host behavior for
|
|
101
|
+
the existing schema v4 result shapes, so plugins do not need a manifest or
|
|
102
|
+
generated-code update.
|
|
95
103
|
|
|
96
104
|
### `messageHandlers` — handle UI → Runtime RPC calls
|
|
97
105
|
|
|
@@ -320,7 +328,7 @@ Namespace of verbs and sub-topics scoped to the action WebView. `clipbus.action`
|
|
|
320
328
|
| Member | Shape | Description |
|
|
321
329
|
|---|---|---|
|
|
322
330
|
| `clipbus.action.setButtons({buttons})` | `Verb` | Replace native action button list (whole-list replace; first call overrides `resolveSession` seed). Strict wire shape — pass `{buttons: [...]}`. |
|
|
323
|
-
| `clipbus.action.complete({result, userMessage?})` | `Verb` | Submit
|
|
331
|
+
| `clipbus.action.complete({result, userMessage?})` | `Verb` | Submit a Draft result and enter the host success presentation; a text/image/path_reference value may then be explicitly advanced by the user, while none cannot advance |
|
|
324
332
|
| `clipbus.action.onHostInvoke(fn)` | `Stream` | Subscribe to host-dispatched button clicks; callback receives `{ buttonID }` |
|
|
325
333
|
|
|
326
334
|
#### `clipbus.action.input` — Topic\<PluginActionUIInput\>
|
package/SPECIFICATION.md
CHANGED
|
@@ -106,8 +106,12 @@ Both Action inputs use `{ sourceItem, content, attachments }`. `sourceItem`
|
|
|
106
106
|
preserves the original clipboard identity for item mutations; `content` is the
|
|
107
107
|
current cascade value and can change kind between Actions. The Action
|
|
108
108
|
`attachments` field is reserved for wire stability and is currently always `[]`
|
|
109
|
-
in SDK 0.9.0. Draft
|
|
110
|
-
|
|
109
|
+
in SDK 0.9.0. A Draft `complete(...)` result with `text`, `image`, or
|
|
110
|
+
`path_reference` enters the host's success presentation and can be explicitly
|
|
111
|
+
advanced by the user as the next Action input; `none` cannot advance. Completion
|
|
112
|
+
does not auto-advance or implicitly select another Action. These semantics use
|
|
113
|
+
the existing schema v4 result shapes and require no protocol or generated-code
|
|
114
|
+
change.
|
|
111
115
|
|
|
112
116
|
### Strongly typed drafts
|
|
113
117
|
|
|
@@ -173,7 +177,7 @@ Capabilities are split by catalog `surface.side`: runtime capabilities are expos
|
|
|
173
177
|
| Auto-fit height | `window.autoFit` | — | `clipbus.window.autoFit()` | Verb |
|
|
174
178
|
| Draft | draftHostEvent | input param | `clipbus.action.draft.current()` | OptionalTopic; UI is read-only — no `update()` verb |
|
|
175
179
|
| Replace action button list | `action.setButtons` | — | `clipbus.action.setButtons({buttons})` | Verb; buttons have `isEnabled?: boolean` field |
|
|
176
|
-
| Submit draft result | `action.complete` | — | `clipbus.action.complete({result, userMessage?})` | Verb; draft lifecycle only |
|
|
180
|
+
| Submit draft result | `action.complete` | — | `clipbus.action.complete({result, userMessage?})` | Verb; draft lifecycle only; value results can be explicitly advanced by the user, `none` cannot |
|
|
177
181
|
| Allocate image temp path | `action.allocateImageTempPath` | `ctx.host.action.allocateImageTempPath({formatHint?})` | — | Verb; runtime-only via user RPC bridge; removed from UI in plugin-api-shrink |
|
|
178
182
|
| Materialize current Action image | `action.materializeInputImagePath` | `ctx.host.action.materializeInputImagePath()` | — | Reads current cascade image, not the original item |
|
|
179
183
|
| Allocate Action output file | `action.allocateOutputFilePath` | `ctx.host.action.allocateOutputFilePath({suggestedName?})` | — | Path may only be returned as an `allocated_file` result entry |
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export interface PluginAttachmentMutationEntry {
|
|
2
2
|
attachmentKey: string;
|
|
3
3
|
payloadJson: string;
|
|
4
|
-
syncScope: string;
|
|
5
4
|
createdAtMs?: number;
|
|
6
5
|
updatedAtMs?: number;
|
|
7
6
|
}
|
|
@@ -201,7 +200,6 @@ export interface PluginDetectorArtifact {
|
|
|
201
200
|
attachmentKey: string;
|
|
202
201
|
payloadJson: string;
|
|
203
202
|
searchProjection?: PluginDetectorSearchProjection;
|
|
204
|
-
attachmentSyncScope?: string;
|
|
205
203
|
createdAtMs?: number;
|
|
206
204
|
updatedAtMs?: number;
|
|
207
205
|
}
|
package/dist/validate/index.cjs
CHANGED
|
@@ -99,7 +99,7 @@ function isValidPluginID(id) {
|
|
|
99
99
|
}
|
|
100
100
|
function validateSchemaVersion(raw, issues) {
|
|
101
101
|
const version = typeof raw["schemaVersion"] === "number" ? raw["schemaVersion"] : 0;
|
|
102
|
-
if (version !==
|
|
102
|
+
if (version !== 4) {
|
|
103
103
|
issues.push(issue("unsupportedSchemaVersion", `Unsupported plugin schema version: ${version}`));
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -118,13 +118,13 @@ var LEGACY_ACTION_FIELDS = [
|
|
|
118
118
|
function validateLegacyFields(raw, issues) {
|
|
119
119
|
const plugin = asRecord(raw["plugin"]);
|
|
120
120
|
if (plugin && "displayName" in plugin) {
|
|
121
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
121
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: plugin.displayName`));
|
|
122
122
|
}
|
|
123
123
|
const renderers = asRecordArray(raw["attachmentRenderers"]);
|
|
124
124
|
for (let i = 0; i < renderers.length; i++) {
|
|
125
125
|
for (const field of LEGACY_RENDERER_FIELDS) {
|
|
126
126
|
if (field in renderers[i]) {
|
|
127
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
127
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: attachmentRenderers[${i}].${field}`));
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -132,7 +132,7 @@ function validateLegacyFields(raw, issues) {
|
|
|
132
132
|
for (let i = 0; i < detectors.length; i++) {
|
|
133
133
|
for (const field of LEGACY_DETECTOR_FIELDS) {
|
|
134
134
|
if (field in detectors[i]) {
|
|
135
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
135
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: detectors[${i}].${field}`));
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
}
|
|
@@ -140,7 +140,7 @@ function validateLegacyFields(raw, issues) {
|
|
|
140
140
|
for (let i = 0; i < actions.length; i++) {
|
|
141
141
|
for (const field of LEGACY_ACTION_FIELDS) {
|
|
142
142
|
if (field in actions[i]) {
|
|
143
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
143
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: actions[${i}].${field}`));
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
}
|
package/dist/validate/index.js
CHANGED
|
@@ -64,7 +64,7 @@ function isValidPluginID(id) {
|
|
|
64
64
|
}
|
|
65
65
|
function validateSchemaVersion(raw, issues) {
|
|
66
66
|
const version = typeof raw["schemaVersion"] === "number" ? raw["schemaVersion"] : 0;
|
|
67
|
-
if (version !==
|
|
67
|
+
if (version !== 4) {
|
|
68
68
|
issues.push(issue("unsupportedSchemaVersion", `Unsupported plugin schema version: ${version}`));
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -83,13 +83,13 @@ var LEGACY_ACTION_FIELDS = [
|
|
|
83
83
|
function validateLegacyFields(raw, issues) {
|
|
84
84
|
const plugin = asRecord(raw["plugin"]);
|
|
85
85
|
if (plugin && "displayName" in plugin) {
|
|
86
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
86
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: plugin.displayName`));
|
|
87
87
|
}
|
|
88
88
|
const renderers = asRecordArray(raw["attachmentRenderers"]);
|
|
89
89
|
for (let i = 0; i < renderers.length; i++) {
|
|
90
90
|
for (const field of LEGACY_RENDERER_FIELDS) {
|
|
91
91
|
if (field in renderers[i]) {
|
|
92
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
92
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: attachmentRenderers[${i}].${field}`));
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -97,7 +97,7 @@ function validateLegacyFields(raw, issues) {
|
|
|
97
97
|
for (let i = 0; i < detectors.length; i++) {
|
|
98
98
|
for (const field of LEGACY_DETECTOR_FIELDS) {
|
|
99
99
|
if (field in detectors[i]) {
|
|
100
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
100
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: detectors[${i}].${field}`));
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -105,7 +105,7 @@ function validateLegacyFields(raw, issues) {
|
|
|
105
105
|
for (let i = 0; i < actions.length; i++) {
|
|
106
106
|
for (const field of LEGACY_ACTION_FIELDS) {
|
|
107
107
|
if (field in actions[i]) {
|
|
108
|
-
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in
|
|
108
|
+
issues.push(issue("legacyFieldNotSupported", `Legacy manifest field is not supported in v4: actions[${i}].${field}`));
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
package/docs/authoring.md
CHANGED
|
@@ -28,7 +28,6 @@ const detector: PluginDetectorHandler = {
|
|
|
28
28
|
attachmentType: 'plugin.example.sample.card', // 必须已在 manifest 声明
|
|
29
29
|
attachmentKey: `card-${input.item.id}`, // 稳定 key,不允许空字符串
|
|
30
30
|
payloadJson: JSON.stringify({ text: input.content.text }),
|
|
31
|
-
attachmentSyncScope: 'syncable', // 'syncable' | 'local_only'
|
|
32
31
|
searchProjection: { // 可选
|
|
33
32
|
scope: 'sample',
|
|
34
33
|
searchText: input.content.text.slice(0, 80),
|
|
@@ -45,6 +44,7 @@ const detector: PluginDetectorHandler = {
|
|
|
45
44
|
- 未命中时返回 `[]`,不要返回半成品 artifact
|
|
46
45
|
- Detector 内不应执行宿主 mutation(标签写入等);那是 action 的职责
|
|
47
46
|
- `attachmentType` 必须出自 manifest 的 `detectors[].attachmentTypes`(manifest 结构见 [manifest.md](./manifest.md))
|
|
47
|
+
- Attachment 是当前设备的 detector 派生数据。schema v4 不提供同步范围字段,宿主统一以 `local_only` 持久化;若内容需要在尚未选中 item 时参与跨设备搜索,请显式提供 `searchProjection`
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
@@ -262,12 +262,15 @@ async function handleApply() {
|
|
|
262
262
|
}
|
|
263
263
|
```
|
|
264
264
|
|
|
265
|
-
Draft
|
|
266
|
-
|
|
265
|
+
Draft 完成后宿主先展示结果供确认、复制或关闭;`text`、`image` 与
|
|
266
|
+
`path_reference` 实际值可由用户显式提交为下一个 Action 的输入,`none`
|
|
267
|
+
不可继续。`complete(...)` 本身不会自动推进,也不会隐式选择其他 Action。
|
|
268
|
+
这是既有 schema v4 结果形状的宿主交互变化,插件无需修改 manifest、
|
|
269
|
+
重新 codegen 或重建。
|
|
267
270
|
|
|
268
271
|
### Draft Action:UI 需要 runtime 协助时
|
|
269
272
|
|
|
270
|
-
`clipbus.action.complete` 接收 `{result: {resultKind: 'text' | 'image' | 'none', …}}`。**image 结果的 `imageTempPath` 必须由 runtime 端通过 `host.action.allocateImageTempPath` 分配**(UI 端没有这个能力),所以图片类 draft 的典型流程是:
|
|
273
|
+
`clipbus.action.complete` 接收 `{result: {resultKind: 'text' | 'image' | 'path_reference' | 'none', …}}`。**image 结果的 `imageTempPath` 必须由 runtime 端通过 `host.action.allocateImageTempPath` 分配**(UI 端没有这个能力),所以图片类 draft 的典型流程是:
|
|
271
274
|
|
|
272
275
|
```ts
|
|
273
276
|
// shared/contracts.ts —— 两端共享类型契约
|
package/docs/manifest.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
| 字段 | 类型 | 必填 | 说明 |
|
|
12
12
|
|---|---|---|---|
|
|
13
|
-
| `schemaVersion` | `number` | 是 | 固定 `
|
|
13
|
+
| `schemaVersion` | `number` | 是 | 固定 `4` |
|
|
14
14
|
| `plugin` | `object` | 是 | 插件身份信息 |
|
|
15
15
|
| `install` | `object` | 否 | 安装期 hook 配置 |
|
|
16
16
|
| `runtime` | `object` | 是 | runtime 与 UI 根目录 |
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
|
|
110
110
|
```json
|
|
111
111
|
{
|
|
112
|
-
"schemaVersion":
|
|
112
|
+
"schemaVersion": 4,
|
|
113
113
|
"plugin": {
|
|
114
114
|
"id": "plugin.example.sample",
|
|
115
115
|
"title": "Sample Plugin",
|
|
@@ -150,10 +150,11 @@
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
## 从 schema
|
|
153
|
+
## 从 schema v3 升级
|
|
154
154
|
|
|
155
|
-
schema
|
|
156
|
-
`
|
|
157
|
-
`
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
schema v4 是 attachment 本机化的 breaking change。Detector artifact 删除
|
|
156
|
+
`attachmentSyncScope`,`item.setAttachments` 的每个 entry 删除 `syncScope`;
|
|
157
|
+
宿主统一以 `local_only` 写入 attachment。Search extension 仍可同步,因此需要
|
|
158
|
+
跨设备预搜索的 detector 文本应继续通过 `searchProjection` 或
|
|
159
|
+
`item.setSearchExtension` 显式写入。宿主不提供 v3/v4 字段兼容层;已安装或开发
|
|
160
|
+
插件会显示“需要更新”,直到 manifest 和构建产物通过 v4 校验。
|
package/docs/preview.md
CHANGED
|
@@ -88,7 +88,7 @@ interface PreviewScenario {
|
|
|
88
88
|
| `viewport` | 该 scenario 的视口配置;未设置时使用 `opts.defaultViewport` |
|
|
89
89
|
| `view` | 透传给 `mount` adapter 的不透明 hint(e.g. `'compact'`/`'expanded'`) |
|
|
90
90
|
|
|
91
|
-
> **
|
|
91
|
+
> **Preview 不模拟完整宿主级联。** 真实宿主收到 `clipbus.action.complete()` 的 `text`、`image` 或 `path_reference` 结果后,会先展示确认阶段,用户可再显式推进到下一 Action;`none` 不可继续。Preview harness 只模拟 Draft 交互与结果提交并记录 native call,不实现宿主的结果确认、“下一步 Action”、动态过滤、rollback 或焦点状态机。
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipbus/plugin-sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed SDK for authoring Clipbus plugins — runtime (Node.js) and UI (WebView) helpers generated from the Clipbus plugin wire contract.",
|
|
6
6
|
"keywords": [
|