@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.
Files changed (54) hide show
  1. package/API.md +641 -0
  2. package/LICENSE +21 -0
  3. package/README.md +466 -0
  4. package/SPECIFICATION.md +355 -0
  5. package/dist/dom/autoFit.d.ts +15 -0
  6. package/dist/dom/consolePatch.d.ts +1 -0
  7. package/dist/dom/index.cjs +211 -0
  8. package/dist/dom/index.d.cts +6 -0
  9. package/dist/dom/index.d.ts +6 -0
  10. package/dist/dom/index.js +188 -0
  11. package/dist/dom/textInputState.d.ts +1 -0
  12. package/dist/dom/topicAdapter.d.ts +30 -0
  13. package/dist/generated/INDEX.runtime.generated.d.ts +6 -0
  14. package/dist/generated/INDEX.ui.generated.d.ts +4 -0
  15. package/dist/generated/capabilityClients.generated.d.ts +199 -0
  16. package/dist/generated/data.generated.d.ts +193 -0
  17. package/dist/generated/hostClients.generated.d.ts +38 -0
  18. package/dist/generated/runtime.actionResult.generated.d.ts +28 -0
  19. package/dist/generated/runtime.definePlugin.generated.d.ts +16 -0
  20. package/dist/generated/runtime.handlers.generated.d.ts +20 -0
  21. package/dist/generated/runtime.host.generated.d.ts +34 -0
  22. package/dist/generated/topicSubscribers.generated.d.ts +32 -0
  23. package/dist/generated/ui.bootstrap.generated.d.ts +15 -0
  24. package/dist/generated/ui.clipbus.generated.d.ts +79 -0
  25. package/dist/generated/wireConstants.generated.d.ts +3 -0
  26. package/dist/internal/capabilities.d.ts +31 -0
  27. package/dist/internal/index.cjs +68 -0
  28. package/dist/internal/index.d.ts +1 -0
  29. package/dist/internal/internalConsole.d.ts +7 -0
  30. package/dist/internal/ipcBus.d.ts +48 -0
  31. package/dist/internal/runtimeInvokeClient.d.ts +3 -0
  32. package/dist/internal/topic.d.ts +20 -0
  33. package/dist/runtime/defineMessage.d.ts +6 -0
  34. package/dist/runtime/index.cjs +163 -0
  35. package/dist/runtime/index.d.cts +4 -0
  36. package/dist/runtime/index.d.ts +4 -0
  37. package/dist/runtime/index.js +132 -0
  38. package/dist/shared/defineMessage.d.ts +7 -0
  39. package/dist/ui/defineMessage.d.ts +7 -0
  40. package/dist/ui/index.cjs +362 -0
  41. package/dist/ui/index.d.cts +4 -0
  42. package/dist/ui/index.d.ts +4 -0
  43. package/dist/ui/index.js +339 -0
  44. package/docs/README.md +34 -0
  45. package/docs/authoring.md +288 -0
  46. package/docs/capability-detection.md +105 -0
  47. package/docs/concepts.md +80 -0
  48. package/docs/entry.md +137 -0
  49. package/docs/faq.md +65 -0
  50. package/docs/item-context.md +186 -0
  51. package/docs/manifest.md +149 -0
  52. package/docs/permissions.md +32 -0
  53. package/docs/rpc.md +84 -0
  54. package/package.json +76 -0
package/API.md ADDED
@@ -0,0 +1,641 @@
1
+ <!-- AUTO-GENERATED FILE — DO NOT EDIT BY HAND.
2
+ Regenerate via `cd protocol/plugin && npm run codegen`.
3
+ Source contract: protocol/plugin/src/catalog.ts -->
4
+
5
+ # Clipbus Plugin API
6
+
7
+ Authoritative API reference, generated from `protocol/plugin/src/catalog.ts`.
8
+ Every entry below maps 1:1 to a catalog descriptor — there is no hidden surface.
9
+
10
+ ## 1. Overview
11
+
12
+ - **Capabilities**: 28
13
+ - **Host events**: 9
14
+ - **Node IPC methods**: 6
15
+ - **Named types**: 28
16
+
17
+ ## 2. Capabilities
18
+
19
+ ### action
20
+
21
+ #### `action.allocateImageTempPath`
22
+
23
+ - **Side**: runtime
24
+ - **Context**: action
25
+ - **Path**: `action.allocateImageTempPath`
26
+ - **Payload**: { formatHint: `string` }
27
+ - **Response**: { path: `string` }
28
+
29
+ #### `action.setButtons`
30
+
31
+ - **Side**: ui
32
+ - **Context**: action
33
+ - **Path**: `action.setButtons`
34
+ - **Payload**: { buttons: { id: `string`, title: `string`, isEnabled?: `bool` }[] }
35
+ - **Response**: { }
36
+
37
+ #### `action.complete`
38
+
39
+ - **Side**: ui
40
+ - **Context**: action
41
+ - **Path**: `action.complete`
42
+ - **Payload**: { result: [`PluginActionResult`](#pluginactionresult), userMessage?: `string` }
43
+ - **Response**: { }
44
+
45
+ ### asset
46
+
47
+ #### `asset.currentItemImageUrl`
48
+
49
+ - **Side**: ui
50
+ - **Context**: any
51
+ - **Path**: `asset.currentItemImageUrl`
52
+ - **Payload**: { }
53
+ - **Response**: { url?: `string` }
54
+
55
+ #### `asset.pathReferenceImageUrl`
56
+
57
+ - **Side**: ui
58
+ - **Context**: any
59
+ - **Path**: `asset.pathReferenceImageUrl`
60
+ - **Payload**: { index: `int` }
61
+ - **Response**: { url?: `string` }
62
+
63
+ #### `asset.registerImage`
64
+
65
+ - **Side**: runtime
66
+ - **Context**: any
67
+ - **Path**: `asset.registerImage`
68
+ - **Payload**: { path: `string` }
69
+ - **Response**: { url: `string` }
70
+
71
+ ### attachmentRenderer
72
+
73
+ #### `attachmentRenderer.setButtons`
74
+
75
+ - **Side**: ui
76
+ - **Context**: attachmentRenderer
77
+ - **Path**: `attachmentRenderer.setButtons`
78
+ - **Payload**: { buttons: { id: `string`, title: `string`, isEnabled?: `bool` }[] }
79
+ - **Response**: { }
80
+
81
+ ### clipboard
82
+
83
+ #### `clipboard.copyText`
84
+
85
+ - **Side**: both
86
+ - **Context**: any
87
+ - **Path**: `clipboard.copyText`
88
+ - **Payload**: { text: `string` }
89
+ - **Response**: { }
90
+
91
+ ### console
92
+
93
+ #### `console.log`
94
+
95
+ - **Side**: both
96
+ - **Context**: any
97
+ - **Path**: `console.log`
98
+ - **Payload**: { level: [`PluginConsoleLogLevel`](#pluginconsoleloglevel), message: `string` }
99
+ - **Response**: { }
100
+
101
+ ### infoPanel
102
+
103
+ #### `infoPanel.open`
104
+
105
+ - **Side**: ui
106
+ - **Context**: any
107
+ - **Path**: `infoPanel.open`
108
+ - **Payload**: { document: [`PluginInfoPanelDocument`](#plugininfopaneldocument) }
109
+ - **Response**: { panelID: `string` }
110
+
111
+ #### `infoPanel.close`
112
+
113
+ - **Side**: ui
114
+ - **Context**: any
115
+ - **Path**: `infoPanel.close`
116
+ - **Payload**: { panelID: `string` }
117
+ - **Response**: { }
118
+
119
+ ### item
120
+
121
+ #### `item.setTags`
122
+
123
+ - **Side**: runtime
124
+ - **Context**: any
125
+ - **Path**: `item.setTags`
126
+ - **Payload**: { tags: `string`[] }
127
+ - **Response**: { tags: `string`[] }
128
+
129
+ #### `item.addTags`
130
+
131
+ - **Side**: runtime
132
+ - **Context**: any
133
+ - **Path**: `item.addTags`
134
+ - **Payload**: { tags: `string`[] }
135
+ - **Response**: { tags: `string`[] }
136
+
137
+ #### `item.removeTags`
138
+
139
+ - **Side**: runtime
140
+ - **Context**: any
141
+ - **Path**: `item.removeTags`
142
+ - **Payload**: { tags: `string`[] }
143
+ - **Response**: { tags: `string`[] }
144
+
145
+ #### `item.setPinned`
146
+
147
+ - **Side**: runtime
148
+ - **Context**: any
149
+ - **Path**: `item.setPinned`
150
+ - **Payload**: { pinned: `bool` }
151
+ - **Response**: { pinned: `bool` }
152
+
153
+ #### `item.setAttachments`
154
+
155
+ - **Side**: runtime
156
+ - **Context**: any
157
+ - **Path**: `item.setAttachments`
158
+ - **Payload**: { owner: `string`, attachmentType: `string`, attachments: [`PluginAttachmentMutationEntry`](#pluginattachmentmutationentry)[] }
159
+ - **Response**: { }
160
+
161
+ #### `item.setSearchExtension`
162
+
163
+ - **Side**: runtime
164
+ - **Context**: any
165
+ - **Path**: `item.setSearchExtension`
166
+ - **Payload**: { scope: `string`, owner: `string`, entries: [`PluginSearchExtensionEntry`](#pluginsearchextensionentry)[] }
167
+ - **Response**: { }
168
+
169
+ #### `item.materializeImagePath`
170
+
171
+ - **Side**: runtime
172
+ - **Context**: any
173
+ - **Path**: `item.materializeImagePath`
174
+ - **Payload**: { }
175
+ - **Response**: { path: `string` }
176
+
177
+ #### `item.readAttachment`
178
+
179
+ - **Side**: both
180
+ - **Context**: any
181
+ - **Path**: `item.readAttachment`
182
+ - **Payload**: { attachmentType: `string`, attachmentKey: `string` }
183
+ - **Response**: { payloadJson?: `string` }
184
+
185
+ ### navigation
186
+
187
+ #### `navigation.openUrl`
188
+
189
+ - **Side**: both
190
+ - **Context**: any
191
+ - **Path**: `navigation.openUrl`
192
+ - **Payload**: { url: `string` }
193
+ - **Response**: { }
194
+
195
+ #### `navigation.revealInFinder`
196
+
197
+ - **Side**: both
198
+ - **Context**: any
199
+ - **Path**: `navigation.revealInFinder`
200
+ - **Payload**: { path: `string` }
201
+ - **Response**: { }
202
+
203
+ #### `navigation.openFilePath`
204
+
205
+ - **Side**: both
206
+ - **Context**: any
207
+ - **Path**: `navigation.openFilePath`
208
+ - **Payload**: { path: `string` }
209
+ - **Response**: { }
210
+
211
+ ### runtime
212
+
213
+ #### `runtime.invoke`
214
+
215
+ - **Side**: ui
216
+ - **Context**: any
217
+ - **Path**: `runtime.invoke`
218
+ - **Payload**: { key: `string`, payload: `json`, timeoutMs?: `int` }
219
+ - **Response**: { response: `json` }
220
+
221
+ ### settings
222
+
223
+ #### `settings.get`
224
+
225
+ - **Side**: both
226
+ - **Context**: any
227
+ - **Path**: `settings.get`
228
+ - **Payload**: { key: `string` }
229
+ - **Response**: { value: `json` \| `null` }
230
+
231
+ #### `settings.getAll`
232
+
233
+ - **Side**: both
234
+ - **Context**: any
235
+ - **Path**: `settings.getAll`
236
+ - **Payload**: { }
237
+ - **Response**: { settings: record<`json`> }
238
+
239
+ ### textInput
240
+
241
+ #### `textInput.stateChanged`
242
+
243
+ - **Side**: ui
244
+ - **Context**: any
245
+ - **Path**: `textInput.stateChanged`
246
+ - **Payload**: { isFocused: `bool`, isComposing: `bool` }
247
+ - **Response**: { }
248
+
249
+ ### window
250
+
251
+ #### `window.setHeight`
252
+
253
+ - **Side**: ui
254
+ - **Context**: any
255
+ - **Path**: `window.setHeight`
256
+ - **Payload**: { height: `int` }
257
+ - **Response**: { }
258
+
259
+ #### `window.autoFit`
260
+
261
+ - **Side**: ui
262
+ - **Context**: any
263
+ - **Path**: `window.autoFit`
264
+ - **Payload**: { }
265
+ - **Response**: { }
266
+
267
+ ## 3. Capability Matrix
268
+
269
+ | Capability | UI path | Runtime path | Context |
270
+ | --- | --- | --- | --- |
271
+ | `runtime.invoke` | `clipbus.runtime.invoke` | — | any |
272
+ | `item.setTags` | — | `host.item.setTags` | any |
273
+ | `item.addTags` | — | `host.item.addTags` | any |
274
+ | `item.removeTags` | — | `host.item.removeTags` | any |
275
+ | `item.setPinned` | — | `host.item.setPinned` | any |
276
+ | `item.setAttachments` | — | `host.item.setAttachments` | any |
277
+ | `item.setSearchExtension` | — | `host.item.setSearchExtension` | any |
278
+ | `item.materializeImagePath` | — | `host.item.materializeImagePath` | any |
279
+ | `item.readAttachment` | `clipbus.item.readAttachment` | `host.item.readAttachment` | any |
280
+ | `asset.currentItemImageUrl` | `clipbus.asset.currentItemImageUrl` | — | any |
281
+ | `asset.pathReferenceImageUrl` | `clipbus.asset.pathReferenceImageUrl` | — | any |
282
+ | `asset.registerImage` | — | `host.asset.registerImage` | any |
283
+ | `clipboard.copyText` | `clipbus.clipboard.copyText` | `host.clipboard.copyText` | any |
284
+ | `navigation.openUrl` | `clipbus.navigation.openUrl` | `host.navigation.openUrl` | any |
285
+ | `navigation.revealInFinder` | `clipbus.navigation.revealInFinder` | `host.navigation.revealInFinder` | any |
286
+ | `navigation.openFilePath` | `clipbus.navigation.openFilePath` | `host.navigation.openFilePath` | any |
287
+ | `action.allocateImageTempPath` | — | `host.action.allocateImageTempPath` | action |
288
+ | `action.setButtons` | `clipbus.action.setButtons` | — | action |
289
+ | `action.complete` | `clipbus.action.complete` | — | action |
290
+ | `attachmentRenderer.setButtons` | `clipbus.attachmentRenderer.setButtons` | — | attachmentRenderer |
291
+ | `window.setHeight` | `clipbus.window.setHeight` | — | any |
292
+ | `window.autoFit` | `clipbus.window.autoFit` | — | any |
293
+ | `infoPanel.open` | `clipbus.infoPanel.open` | — | any |
294
+ | `infoPanel.close` | `clipbus.infoPanel.close` | — | any |
295
+ | `settings.get` | `clipbus.settings.get` | `host.settings.get` | any |
296
+ | `settings.getAll` | `clipbus.settings.getAll` | `host.settings.getAll` | any |
297
+ | `console.log` | `clipbus.console.log` | `host.console.log` | any |
298
+ | `textInput.stateChanged` | `clipbus.textInput.stateChanged` | — | any |
299
+
300
+ ## 4. Host Events
301
+
302
+ ### `clipbus-plugin-context`
303
+
304
+ - **Window global**: `__CLIPBUS_PLUGIN_CONTEXT__`
305
+ - **Topic**: `pluginContext`
306
+ - **Shape**: topic
307
+ - **Context**: any
308
+ - **Payload**: { mode: `'attachmentRenderer'` \| `'action'`, pluginID: `string` }
309
+
310
+ ### `clipbus-plugin-item`
311
+
312
+ - **Window global**: `__CLIPBUS_PLUGIN_ITEM__`
313
+ - **Topic**: `item`
314
+ - **Shape**: topic
315
+ - **Context**: any
316
+ - **Payload**: [`PluginClipboardItem`](#pluginclipboarditem)
317
+
318
+ ### `clipbus-plugin-attachment`
319
+
320
+ - **Window global**: `__CLIPBUS_PLUGIN_ATTACHMENT__`
321
+ - **Topic**: `item.attachment`
322
+ - **Shape**: topic
323
+ - **Context**: attachmentRenderer
324
+ - **Payload**: [`PluginAttachmentPayload`](#pluginattachmentpayload)
325
+
326
+ ### `clipbus-plugin-draft`
327
+
328
+ - **Window global**: `__CLIPBUS_PLUGIN_DRAFT__`
329
+ - **Topic**: `action.draft`
330
+ - **Shape**: topic
331
+ - **Context**: action
332
+ - **Payload**: record<`json`>
333
+
334
+ ### `clipbus-plugin-theme`
335
+
336
+ - **Window global**: `__CLIPBUS_PLUGIN_THEME__`
337
+ - **Topic**: `theme`
338
+ - **Shape**: topic
339
+ - **Context**: any
340
+ - **Payload**: [`PluginThemeTokenSnapshot`](#pluginthemetokensnapshot)
341
+
342
+ ### `clipbus-plugin-attachment-host-invoke`
343
+
344
+ - **Topic**: `attachmentRenderer.onHostInvoke`
345
+ - **Shape**: stream
346
+ - **Context**: attachmentRenderer
347
+ - **Payload**: { buttonID: `string` }
348
+
349
+ ### `clipbus-plugin-action-host-invoke`
350
+
351
+ - **Topic**: `action.onHostInvoke`
352
+ - **Shape**: stream
353
+ - **Context**: action
354
+ - **Payload**: { buttonID: `string` }
355
+
356
+ ### `clipbus-plugin-info-panel-on-action`
357
+
358
+ - **Topic**: `infoPanel.onAction`
359
+ - **Shape**: stream
360
+ - **Context**: any
361
+ - **Payload**: { panelID: `string`, buttonID: `string` }
362
+
363
+ ### `clipbus-plugin-info-panel-on-close`
364
+
365
+ - **Topic**: `infoPanel.onClose`
366
+ - **Shape**: stream
367
+ - **Context**: any
368
+ - **Payload**: { panelID: `string` }
369
+
370
+ ## 5. Host Event Matrix
371
+
372
+ | Event | Topic | Shape | Window global | Context |
373
+ | --- | --- | --- | --- | --- |
374
+ | `clipbus-plugin-context` | pluginContext | topic | `__CLIPBUS_PLUGIN_CONTEXT__` | any |
375
+ | `clipbus-plugin-item` | item | topic | `__CLIPBUS_PLUGIN_ITEM__` | any |
376
+ | `clipbus-plugin-attachment` | item.attachment | topic | `__CLIPBUS_PLUGIN_ATTACHMENT__` | attachmentRenderer |
377
+ | `clipbus-plugin-draft` | action.draft | topic | `__CLIPBUS_PLUGIN_DRAFT__` | action |
378
+ | `clipbus-plugin-theme` | theme | topic | `__CLIPBUS_PLUGIN_THEME__` | any |
379
+ | `clipbus-plugin-attachment-host-invoke` | attachmentRenderer.onHostInvoke | stream | — | attachmentRenderer |
380
+ | `clipbus-plugin-action-host-invoke` | action.onHostInvoke | stream | — | action |
381
+ | `clipbus-plugin-info-panel-on-action` | infoPanel.onAction | stream | — | any |
382
+ | `clipbus-plugin-info-panel-on-close` | infoPanel.onClose | stream | — | any |
383
+
384
+ ## 6. Node IPC
385
+
386
+ ### `runtime.userRPC`
387
+
388
+ - **Request**: { key: `string`, payload: `json` }
389
+ - **Response**: { result: `json` }
390
+
391
+ ### `runtime.invokeRenderer`
392
+
393
+ - **Request**: { requestID: `string`, rendererID: `string`, input: [`PluginResolveAttachmentInput`](#pluginresolveattachmentinput) }
394
+ - **Response**: { requestID: `string`, result?: [`PluginAttachmentResolveResult`](#pluginattachmentresolveresult), errorMessage?: `string` }
395
+ - **Handler interface**: `PluginAttachmentRendererHandler.resolveAttachment`
396
+ - **Registry key**: `attachmentRenderers`
397
+
398
+ ### `runtime.invokeDetector`
399
+
400
+ - **Request**: { requestID: `string`, detectorID: `string`, input: [`PluginDetectorInput`](#plugindetectorinput) }
401
+ - **Response**: { requestID: `string`, result?: [`PluginDetectorArtifact`](#plugindetectorartifact)[], errorMessage?: `string` }
402
+ - **Handler interface**: `PluginDetectorHandler.detect`
403
+ - **Registry key**: `detectors`
404
+
405
+ ### `runtime.invokeAction`
406
+
407
+ - **Request**: { requestID: `string`, actionID: `string`, input: [`PluginResolveActionSessionInput`](#pluginresolveactionsessioninput) }
408
+ - **Response**: { requestID: `string`, result?: [`PluginActionResolveResult`](#pluginactionresolveresult), errorMessage?: `string` }
409
+ - **Handler interface**: `PluginAutoRunActionHandler.resolveSession`
410
+ - **Registry key**: `actions`
411
+
412
+ ### `runtime.invokeActionAutoRun`
413
+
414
+ - **Request**: { requestID: `string`, actionID: `string`, input: [`PluginAutoRunActionInput`](#pluginautorunactioninput) }
415
+ - **Response**: { requestID: `string`, result?: [`PluginActionOperationResult`](#pluginactionoperationresult), errorMessage?: `string` }
416
+ - **Handler interface**: `PluginAutoRunActionHandler.runAutoAction`
417
+ - **Registry key**: `actions`
418
+
419
+ ### `runtime.ready`
420
+
421
+ - **Request**: { }
422
+ - **Response**: { }
423
+
424
+ ## 7. Plugin Registry
425
+
426
+ Plugins return a `PluginRegistry` object from `definePlugin`:
427
+
428
+ ```ts
429
+ export interface PluginRegistry {
430
+ attachmentRenderers?: Record<string, PluginAttachmentRendererHandler>;
431
+ detectors?: Record<string, PluginDetectorHandler>;
432
+ actions?: Record<string, PluginAutoRunActionHandler>;
433
+ messageHandlers?: Record<string, MessageHandler>;
434
+ }
435
+ ```
436
+
437
+ ## 8. Named Types
438
+
439
+ ### `PluginAttachmentMutationEntry`
440
+
441
+ - `attachmentKey`: `string`
442
+ - `payloadJson`: `string`
443
+ - `syncScope`: `string`
444
+ - `createdAtMs?`: `int`
445
+ - `updatedAtMs?`: `int`
446
+
447
+ ### `PluginSearchExtensionEntry`
448
+
449
+ - `entryKey`: `string`
450
+ - `searchText`: `string`
451
+ - `label?`: `string`
452
+ - `updatedAtMs?`: `int`
453
+
454
+ ### `PluginActionResult`
455
+
456
+ Discriminated union on `resultKind`: { resultKind: `'text'`, text: `string` } | { resultKind: `'image'`, imageTempPath: `string`, imageFormatHint?: `string` } | { resultKind: `'none'` }
457
+
458
+ ### `PluginInfoPanelTextStyle`
459
+
460
+ Union: `'body'` | `'mono'` | `'muted'`
461
+
462
+ ### `PluginInfoPanelCodeLanguage`
463
+
464
+ Union: `'plain'` | `'json'`
465
+
466
+ ### `PluginInfoPanelField`
467
+
468
+ - `key`: `string`
469
+ - `value`: `string`
470
+ - `isMono?`: `bool`
471
+
472
+ ### `PluginInfoPanelBlock`
473
+
474
+ Discriminated union on `type`: { type: `'label'`, text: `string` } | { type: `'text'`, text: `string`, style: [`PluginInfoPanelTextStyle`](#plugininfopaneltextstyle) } | { type: `'code'`, text: `string`, language: [`PluginInfoPanelCodeLanguage`](#plugininfopanelcodelanguage) } | { type: `'qrCode'`, value: `string` } | { type: `'fields'`, fields: [`PluginInfoPanelField`](#plugininfopanelfield)[] } | { type: `'tags'`, tags: `string`[] } | { type: `'divider'` }
475
+
476
+ ### `PluginInfoPanelAction`
477
+
478
+ - `id`: `string`
479
+ - `label`: `string`
480
+ - `isPrimary?`: `bool`
481
+
482
+ ### `PluginInfoPanelDocument`
483
+
484
+ - `icon?`: `string`
485
+ - `title`: `string`
486
+ - `subtitle?`: `string`
487
+ - `badges?`: `string`[]
488
+ - `blocks`: [`PluginInfoPanelBlock`](#plugininfopanelblock)[]
489
+ - `actions`: [`PluginInfoPanelAction`](#plugininfopanelaction)[]
490
+
491
+ ### `PluginConsoleLogLevel`
492
+
493
+ Union: `'debug'` | `'info'` | `'warn'` | `'error'`
494
+
495
+ ### `PluginClipboardItem`
496
+
497
+ - `id`: `string`
498
+ - `type`: `string`
499
+ - `tags`: `string`[]
500
+ - `sourceAppID`: `string`
501
+
502
+ ### `PluginAttachmentEntry`
503
+
504
+ - `historyID`: `string`
505
+ - `owner`: `string`
506
+ - `attachmentType`: `string`
507
+ - `attachmentKey`: `string`
508
+ - `payloadJson`: `string`
509
+
510
+ ### `PluginAttachmentPayload`
511
+
512
+ - `item`: [`PluginClipboardItem`](#pluginclipboarditem)
513
+ - `attachment`: [`PluginAttachmentEntry`](#pluginattachmententry)
514
+
515
+ ### `PluginThemeTokens`
516
+
517
+ - `surface`: `string`
518
+ - `surfaceElevated`: `string`
519
+ - `textPrimary`: `string`
520
+ - `textSecondary`: `string`
521
+ - `textTertiary`: `string`
522
+ - `accent`: `string`
523
+ - `accentContrast`: `string`
524
+ - `border`: `string`
525
+ - `divider`: `string`
526
+ - `success`: `string`
527
+ - `warning`: `string`
528
+ - `danger`: `string`
529
+
530
+ ### `PluginThemeTokenSnapshot`
531
+
532
+ - `scheme`: `string`
533
+ - `tokens`: [`PluginThemeTokens`](#pluginthemetokens)
534
+
535
+ ### `PluginPathEntry`
536
+
537
+ - `kind`: `'file'` \| `'folder'`
538
+ - `path`: `string`
539
+ - `displayName`: `string`
540
+
541
+ ### `PluginContentEnvelope`
542
+
543
+ Discriminated union on `kind`: { kind: `'text'`, text: `string` } | { kind: `'image'`, width: `int`, height: `int`, format: `string`, bytes: `int` } | { kind: `'path_reference'`, entries: [`PluginPathEntry`](#pluginpathentry)[] }
544
+
545
+ ### `PluginAttachmentRef`
546
+
547
+ - `attachmentType`: `string`
548
+ - `attachmentKey`: `string`
549
+
550
+ ### `PluginResolveAttachmentInput`
551
+
552
+ - `item`: [`PluginClipboardItem`](#pluginclipboarditem)
553
+ - `content`: [`PluginContentEnvelope`](#plugincontentenvelope)
554
+ - `attachments`: [`PluginAttachmentRef`](#pluginattachmentref)[]
555
+ - `attachment`: [`PluginAttachmentEntry`](#pluginattachmententry)
556
+
557
+ ### `PluginActionButton`
558
+
559
+ - `id`: `string`
560
+ - `title`: `string`
561
+ - `isEnabled?`: `bool`
562
+
563
+ ### `PluginAttachmentResolveResult`
564
+
565
+ - `shouldDisplay?`: `bool`
566
+ - `displayName?`: `string`
567
+ - `tintHex?`: `string`
568
+ - `buttons?`: [`PluginActionButton`](#pluginactionbutton)[]
569
+
570
+ ### `PluginDetectorInput`
571
+
572
+ - `item`: [`PluginClipboardItem`](#pluginclipboarditem)
573
+ - `content`: [`PluginContentEnvelope`](#plugincontentenvelope)
574
+ - `attachments`: [`PluginAttachmentRef`](#pluginattachmentref)[]
575
+
576
+ ### `PluginDetectorSearchProjection`
577
+
578
+ - `scope`: `string`
579
+ - `searchText`: `string`
580
+ - `label?`: `string`
581
+
582
+ ### `PluginDetectorArtifact`
583
+
584
+ - `attachmentType`: `string`
585
+ - `attachmentKey`: `string`
586
+ - `payloadJson`: `string`
587
+ - `searchProjection?`: [`PluginDetectorSearchProjection`](#plugindetectorsearchprojection)
588
+ - `attachmentSyncScope?`: `string`
589
+ - `createdAtMs?`: `int`
590
+ - `updatedAtMs?`: `int`
591
+
592
+ ### `PluginResolveActionSessionInput`
593
+
594
+ - `item`: [`PluginClipboardItem`](#pluginclipboarditem)
595
+ - `content`: [`PluginContentEnvelope`](#plugincontentenvelope)
596
+ - `attachments`: [`PluginAttachmentRef`](#pluginattachmentref)[]
597
+
598
+ ### `PluginActionResolveResult`
599
+
600
+ - `displayName?`: `string`
601
+ - `buttons`: [`PluginActionButton`](#pluginactionbutton)[]
602
+ - `defaultButtonID?`: `string`
603
+ - `initialDraft`: record<`json`>
604
+
605
+ ### `PluginAutoRunActionInput`
606
+
607
+ - `item`: [`PluginClipboardItem`](#pluginclipboarditem)
608
+ - `content`: [`PluginContentEnvelope`](#plugincontentenvelope)
609
+ - `attachments`: [`PluginAttachmentRef`](#pluginattachmentref)[]
610
+
611
+ ### `PluginActionOperationResult`
612
+
613
+ - `result`: [`PluginActionResult`](#pluginactionresult)
614
+ - `userMessage?`: `string`
615
+
616
+ ## 9. Wire Constants
617
+
618
+ - `__clipbus_structured_error__:` — prefix used by the runtime error envelope.
619
+
620
+ ## 10. Window Globals
621
+
622
+ | Window global | Source event |
623
+ | --- | --- |
624
+ | `__CLIPBUS_PLUGIN_CONTEXT__` | `clipbus-plugin-context` |
625
+ | `__CLIPBUS_PLUGIN_ITEM__` | `clipbus-plugin-item` |
626
+ | `__CLIPBUS_PLUGIN_ATTACHMENT__` | `clipbus-plugin-attachment` |
627
+ | `__CLIPBUS_PLUGIN_DRAFT__` | `clipbus-plugin-draft` |
628
+ | `__CLIPBUS_PLUGIN_THEME__` | `clipbus-plugin-theme` |
629
+
630
+ ## 11. Generated Symbol Map
631
+
632
+ | Concept | Generated file (TS) | Generated file (Swift) |
633
+ | --- | --- | --- |
634
+ | Capability payload/response types | `capabilityClients.generated.ts` | `PluginCapabilityPayloads.generated.swift` |
635
+ | UI capability tree | `ui.clipbus.generated.ts` | — |
636
+ | Runtime host tree | `runtime.host.generated.ts`, `hostClients.generated.ts` | — |
637
+ | Host event subscribers | `topicSubscribers.generated.ts` | `PluginHostTopicEmitter.generated.swift` |
638
+ | Node IPC server | `nodeIPCServer.generated.ts` | `PluginNodeIPCClient.generated.swift` |
639
+ | Named types | `data.generated.ts` | `PluginCommonTypes.generated.swift` |
640
+ | Handler interfaces | `runtime.handlers.generated.ts` | `PluginUIHostHandler.generated.swift`, `PluginRuntimeHostHandler.generated.swift` |
641
+ | `definePlugin` + registry | `runtime.definePlugin.generated.ts` | — |
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 scubers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.