@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
@@ -0,0 +1,16 @@
1
+ import type { PluginAttachmentRendererHandler, PluginAutoRunActionHandler, PluginDetectorHandler } from './runtime.handlers.generated.js';
2
+ import type { HostClient } from './hostClients.generated.js';
3
+ export interface MessageHandlerContext {
4
+ host: HostClient;
5
+ }
6
+ export type MessageHandler<TReq = unknown, TResp = unknown> = (request: TReq, ctx: MessageHandlerContext) => Promise<TResp> | TResp;
7
+ export interface PluginRegistry {
8
+ attachmentRenderers?: Record<string, PluginAttachmentRendererHandler>;
9
+ detectors?: Record<string, PluginDetectorHandler>;
10
+ actions?: Record<string, PluginAutoRunActionHandler>;
11
+ messageHandlers?: Record<string, MessageHandler>;
12
+ }
13
+ export interface PluginSetup {
14
+ setup(): PluginRegistry;
15
+ }
16
+ export declare function definePlugin(definition: PluginRegistry | PluginSetup): PluginSetup;
@@ -0,0 +1,20 @@
1
+ import type { PluginActionOperationResult, PluginActionResolveResult, PluginAttachmentResolveResult, PluginAutoRunActionInput, PluginDetectorArtifact, PluginDetectorInput, PluginResolveActionSessionInput, PluginResolveAttachmentInput } from './data.generated.js';
2
+ import type { HostClient } from './hostClients.generated.js';
3
+ export interface PluginAttachmentRendererHandler {
4
+ resolveAttachment(input: PluginResolveAttachmentInput, ctx?: {
5
+ host?: HostClient;
6
+ }): Promise<PluginAttachmentResolveResult>;
7
+ }
8
+ export interface PluginDetectorHandler {
9
+ detect(input: PluginDetectorInput, ctx?: {
10
+ host?: HostClient;
11
+ }): Promise<PluginDetectorArtifact[]>;
12
+ }
13
+ export interface PluginAutoRunActionHandler {
14
+ resolveSession(input: PluginResolveActionSessionInput, ctx?: {
15
+ host?: HostClient;
16
+ }): Promise<PluginActionResolveResult>;
17
+ runAutoAction(input: PluginAutoRunActionInput, ctx?: {
18
+ host?: HostClient;
19
+ }): Promise<PluginActionOperationResult>;
20
+ }
@@ -0,0 +1,34 @@
1
+ import type { PluginActionAllocateImageTempPathPayload, PluginActionAllocateImageTempPathResponse, PluginAssetRegisterImagePayload, PluginAssetRegisterImageResponse, PluginClipboardCopyTextPayload, PluginClipboardCopyTextResponse, PluginConsoleLogPayload, PluginConsoleLogResponse, PluginItemAddTagsPayload, PluginItemAddTagsResponse, PluginItemMaterializeImagePathResponse, PluginItemReadAttachmentPayload, PluginItemReadAttachmentResponse, PluginItemRemoveTagsPayload, PluginItemRemoveTagsResponse, PluginItemSetAttachmentsPayload, PluginItemSetAttachmentsResponse, PluginItemSetPinnedPayload, PluginItemSetPinnedResponse, PluginItemSetSearchExtensionPayload, PluginItemSetSearchExtensionResponse, PluginItemSetTagsPayload, PluginItemSetTagsResponse, PluginNavigationOpenFilePathPayload, PluginNavigationOpenFilePathResponse, PluginNavigationOpenUrlPayload, PluginNavigationOpenUrlResponse, PluginNavigationRevealInFinderPayload, PluginNavigationRevealInFinderResponse, PluginSettingsGetAllResponse, PluginSettingsGetPayload, PluginSettingsGetResponse } from './capabilityClients.generated.js';
2
+ export declare const host: {
3
+ item: {
4
+ setTags: (payload: PluginItemSetTagsPayload) => Promise<PluginItemSetTagsResponse>;
5
+ addTags: (payload: PluginItemAddTagsPayload) => Promise<PluginItemAddTagsResponse>;
6
+ removeTags: (payload: PluginItemRemoveTagsPayload) => Promise<PluginItemRemoveTagsResponse>;
7
+ setPinned: (payload: PluginItemSetPinnedPayload) => Promise<PluginItemSetPinnedResponse>;
8
+ setAttachments: (payload: PluginItemSetAttachmentsPayload) => Promise<PluginItemSetAttachmentsResponse>;
9
+ setSearchExtension: (payload: PluginItemSetSearchExtensionPayload) => Promise<PluginItemSetSearchExtensionResponse>;
10
+ materializeImagePath: () => Promise<PluginItemMaterializeImagePathResponse>;
11
+ readAttachment: (payload: PluginItemReadAttachmentPayload) => Promise<PluginItemReadAttachmentResponse>;
12
+ };
13
+ asset: {
14
+ registerImage: (payload: PluginAssetRegisterImagePayload) => Promise<PluginAssetRegisterImageResponse>;
15
+ };
16
+ clipboard: {
17
+ copyText: (payload: PluginClipboardCopyTextPayload) => Promise<PluginClipboardCopyTextResponse>;
18
+ };
19
+ navigation: {
20
+ openUrl: (payload: PluginNavigationOpenUrlPayload) => Promise<PluginNavigationOpenUrlResponse>;
21
+ revealInFinder: (payload: PluginNavigationRevealInFinderPayload) => Promise<PluginNavigationRevealInFinderResponse>;
22
+ openFilePath: (payload: PluginNavigationOpenFilePathPayload) => Promise<PluginNavigationOpenFilePathResponse>;
23
+ };
24
+ action: {
25
+ allocateImageTempPath: (payload: PluginActionAllocateImageTempPathPayload) => Promise<PluginActionAllocateImageTempPathResponse>;
26
+ };
27
+ settings: {
28
+ get: (payload: PluginSettingsGetPayload) => Promise<PluginSettingsGetResponse>;
29
+ getAll: () => Promise<PluginSettingsGetAllResponse>;
30
+ };
31
+ console: {
32
+ log: (payload: PluginConsoleLogPayload) => Promise<PluginConsoleLogResponse>;
33
+ };
34
+ };
@@ -0,0 +1,32 @@
1
+ import type { PluginAttachmentPayload, PluginClipboardItem, PluginThemeTokenSnapshot } from './data.generated.js';
2
+ export interface PluginContextPayload {
3
+ mode: 'attachmentRenderer' | 'action';
4
+ pluginID: string;
5
+ }
6
+ export declare function onContext(listener: (payload: PluginContextPayload) => void): () => void;
7
+ export declare function getContextSnapshot(): PluginContextPayload | undefined;
8
+ export declare function onItem(listener: (payload: PluginClipboardItem) => void): () => void;
9
+ export declare function getItemSnapshot(): PluginClipboardItem | undefined;
10
+ export declare function onAttachment(listener: (payload: PluginAttachmentPayload) => void): () => void;
11
+ export declare function getAttachmentSnapshot(): PluginAttachmentPayload | undefined;
12
+ export declare function onDraft(listener: (payload: Record<string, unknown>) => void): () => void;
13
+ export declare function getDraftSnapshot(): Record<string, unknown> | undefined;
14
+ export declare function onTheme(listener: (payload: PluginThemeTokenSnapshot) => void): () => void;
15
+ export declare function getThemeSnapshot(): PluginThemeTokenSnapshot | undefined;
16
+ export interface PluginAttachmentHostInvokePayload {
17
+ buttonID: string;
18
+ }
19
+ export declare function onAttachmentHostInvoke(listener: (payload: PluginAttachmentHostInvokePayload) => void): () => void;
20
+ export interface PluginActionHostInvokePayload {
21
+ buttonID: string;
22
+ }
23
+ export declare function onActionHostInvoke(listener: (payload: PluginActionHostInvokePayload) => void): () => void;
24
+ export interface PluginInfoPanelOnActionPayload {
25
+ panelID: string;
26
+ buttonID: string;
27
+ }
28
+ export declare function onInfoPanelOnAction(listener: (payload: PluginInfoPanelOnActionPayload) => void): () => void;
29
+ export interface PluginInfoPanelOnClosePayload {
30
+ panelID: string;
31
+ }
32
+ export declare function onInfoPanelOnClose(listener: (payload: PluginInfoPanelOnClosePayload) => void): () => void;
@@ -0,0 +1,15 @@
1
+ import type { PluginAttachmentPayload, PluginClipboardItem, PluginThemeTokenSnapshot } from './data.generated.js';
2
+ import type { PluginActionHostInvokePayload, PluginAttachmentHostInvokePayload, PluginContextPayload, PluginInfoPanelOnActionPayload, PluginInfoPanelOnClosePayload } from './topicSubscribers.generated.js';
3
+ export declare const _pluginContextTopic: import("../internal/topic.js").MutableTopic<PluginContextPayload>;
4
+ export declare const _itemTopic: import("../internal/topic.js").MutableTopic<PluginClipboardItem>;
5
+ export declare const _itemAttachmentTopic: import("../internal/topic.js").MutableTopic<PluginAttachmentPayload>;
6
+ export declare const _actionDraftTopic: import("../internal/topic.js").MutableTopic<Record<string, unknown>>;
7
+ export declare const _themeTopic: import("../internal/topic.js").MutableTopic<PluginThemeTokenSnapshot>;
8
+ export declare const _attachmentRendererOnHostInvokeStream: import("../internal/topic.js").MutableStream<PluginAttachmentHostInvokePayload>;
9
+ export declare const _actionOnHostInvokeStream: import("../internal/topic.js").MutableStream<PluginActionHostInvokePayload>;
10
+ export declare const _infoPanelOnActionStream: import("../internal/topic.js").MutableStream<PluginInfoPanelOnActionPayload>;
11
+ export declare const _infoPanelOnCloseStream: import("../internal/topic.js").MutableStream<PluginInfoPanelOnClosePayload>;
12
+ export declare class PluginContextError extends Error {
13
+ constructor(message: string);
14
+ }
15
+ export declare function guardContext<A extends unknown[], R>(expected: 'attachmentRenderer' | 'action', run: (...args: A) => R): (...args: A) => R;
@@ -0,0 +1,79 @@
1
+ import type { PluginActionCompletePayload, PluginActionCompleteResponse, PluginActionSetButtonsPayload, PluginActionSetButtonsResponse, PluginAssetCurrentItemImageUrlResponse, PluginAssetPathReferenceImageUrlPayload, PluginAssetPathReferenceImageUrlResponse, PluginAttachmentRendererSetButtonsPayload, PluginAttachmentRendererSetButtonsResponse, PluginClipboardCopyTextPayload, PluginClipboardCopyTextResponse, PluginConsoleLogPayload, PluginConsoleLogResponse, PluginInfoPanelClosePayload, PluginInfoPanelCloseResponse, PluginInfoPanelOpenPayload, PluginInfoPanelOpenResponse, PluginItemReadAttachmentPayload, PluginItemReadAttachmentResponse, PluginNavigationOpenFilePathPayload, PluginNavigationOpenFilePathResponse, PluginNavigationOpenUrlPayload, PluginNavigationOpenUrlResponse, PluginNavigationRevealInFinderPayload, PluginNavigationRevealInFinderResponse, PluginRuntimeInvokePayload, PluginSettingsGetAllResponse, PluginSettingsGetPayload, PluginSettingsGetResponse, PluginTextInputStateChangedPayload, PluginTextInputStateChangedResponse, PluginWindowAutoFitResponse, PluginWindowSetHeightPayload, PluginWindowSetHeightResponse } from './capabilityClients.generated.js';
2
+ import type { PluginAttachmentPayload, PluginClipboardItem, PluginThemeTokenSnapshot } from './data.generated.js';
3
+ import type { PluginActionHostInvokePayload, PluginAttachmentHostInvokePayload, PluginContextPayload, PluginInfoPanelOnActionPayload, PluginInfoPanelOnClosePayload } from './topicSubscribers.generated.js';
4
+ export declare const clipbus: {
5
+ capabilities: import("../internal/capabilities.js").CapabilitiesApi;
6
+ runtime: {
7
+ invoke: <TResp = unknown>(payload: PluginRuntimeInvokePayload) => Promise<TResp>;
8
+ };
9
+ item: {
10
+ current: () => PluginClipboardItem | undefined;
11
+ on: (fn: (payload: PluginClipboardItem) => void) => import("../internal/topic.js").Unsubscribe;
12
+ readAttachment: (payload: PluginItemReadAttachmentPayload) => Promise<PluginItemReadAttachmentResponse>;
13
+ attachment: {
14
+ current: () => PluginAttachmentPayload | undefined;
15
+ on: (fn: (payload: PluginAttachmentPayload) => void) => import("../internal/topic.js").Unsubscribe;
16
+ };
17
+ };
18
+ asset: {
19
+ currentItemImageUrl: () => Promise<PluginAssetCurrentItemImageUrlResponse>;
20
+ pathReferenceImageUrl: (payload: PluginAssetPathReferenceImageUrlPayload) => Promise<PluginAssetPathReferenceImageUrlResponse>;
21
+ };
22
+ clipboard: {
23
+ copyText: (payload: PluginClipboardCopyTextPayload) => Promise<PluginClipboardCopyTextResponse>;
24
+ };
25
+ navigation: {
26
+ openUrl: (payload: PluginNavigationOpenUrlPayload) => Promise<PluginNavigationOpenUrlResponse>;
27
+ revealInFinder: (payload: PluginNavigationRevealInFinderPayload) => Promise<PluginNavigationRevealInFinderResponse>;
28
+ openFilePath: (payload: PluginNavigationOpenFilePathPayload) => Promise<PluginNavigationOpenFilePathResponse>;
29
+ };
30
+ action: {
31
+ setButtons: (payload: PluginActionSetButtonsPayload) => Promise<PluginActionSetButtonsResponse>;
32
+ complete: (payload: PluginActionCompletePayload) => Promise<PluginActionCompleteResponse>;
33
+ draft: {
34
+ current: () => Record<string, unknown> | undefined;
35
+ on: (fn: (payload: Record<string, unknown>) => void) => import("../internal/topic.js").Unsubscribe;
36
+ };
37
+ onHostInvoke: {
38
+ on: (fn: (payload: PluginActionHostInvokePayload) => void) => import("../internal/topic.js").Unsubscribe;
39
+ };
40
+ };
41
+ attachmentRenderer: {
42
+ setButtons: (payload: PluginAttachmentRendererSetButtonsPayload) => Promise<PluginAttachmentRendererSetButtonsResponse>;
43
+ onHostInvoke: {
44
+ on: (fn: (payload: PluginAttachmentHostInvokePayload) => void) => import("../internal/topic.js").Unsubscribe;
45
+ };
46
+ };
47
+ window: {
48
+ setHeight: (payload: PluginWindowSetHeightPayload) => Promise<PluginWindowSetHeightResponse>;
49
+ autoFit: () => Promise<PluginWindowAutoFitResponse>;
50
+ };
51
+ infoPanel: {
52
+ open: (payload: PluginInfoPanelOpenPayload) => Promise<PluginInfoPanelOpenResponse>;
53
+ close: (payload: PluginInfoPanelClosePayload) => Promise<PluginInfoPanelCloseResponse>;
54
+ onAction: {
55
+ on: (fn: (payload: PluginInfoPanelOnActionPayload) => void) => import("../internal/topic.js").Unsubscribe;
56
+ };
57
+ onClose: {
58
+ on: (fn: (payload: PluginInfoPanelOnClosePayload) => void) => import("../internal/topic.js").Unsubscribe;
59
+ };
60
+ };
61
+ settings: {
62
+ get: (payload: PluginSettingsGetPayload) => Promise<PluginSettingsGetResponse>;
63
+ getAll: () => Promise<PluginSettingsGetAllResponse>;
64
+ };
65
+ console: {
66
+ log: (payload: PluginConsoleLogPayload) => Promise<PluginConsoleLogResponse>;
67
+ };
68
+ textInput: {
69
+ stateChanged: (payload: PluginTextInputStateChangedPayload) => Promise<PluginTextInputStateChangedResponse>;
70
+ };
71
+ pluginContext: {
72
+ current: () => PluginContextPayload | undefined;
73
+ on: (fn: (payload: PluginContextPayload) => void) => import("../internal/topic.js").Unsubscribe;
74
+ };
75
+ theme: {
76
+ current: () => PluginThemeTokenSnapshot | undefined;
77
+ on: (fn: (payload: PluginThemeTokenSnapshot) => void) => import("../internal/topic.js").Unsubscribe;
78
+ };
79
+ };
@@ -0,0 +1,3 @@
1
+ export declare const STRUCTURED_ERROR_PREFIX: "__clipbus_structured_error__:";
2
+ export declare const CAPABILITIES_GLOBAL: "__CLIPBUS_PLUGIN_CAPABILITIES__";
3
+ export declare const CAPABILITY_UNSUPPORTED_ERROR_NAME: "PluginCapabilityUnsupported";
@@ -0,0 +1,31 @@
1
+ import type { CapabilityMethodName } from '../generated/capabilityClients.generated.js';
2
+ /**
3
+ * 宿主不支持某 capability 时抛出的类型化错误。
4
+ * 插件可通过 `instanceof CapabilityUnsupportedError` 识别并降级处理。
5
+ */
6
+ export declare class CapabilityUnsupportedError extends Error {
7
+ readonly capability: string;
8
+ constructor(capability: string);
9
+ }
10
+ /**
11
+ * 从 window 全局读取宿主注入的能力清单。
12
+ * 缺失/非法 → 空集(→ has() 恒 false,老宿主行为)。
13
+ */
14
+ export declare function readInjectedCapabilities(global: unknown, key: string): ReadonlySet<string>;
15
+ export interface CapabilitiesApi {
16
+ has(name: CapabilityMethodName): boolean;
17
+ }
18
+ /**
19
+ * 创建 capabilities 命名空间对象。
20
+ * `getSet` 是惰性求值函数,每次 `has()` 调用时执行(确保读到最新注入值)。
21
+ */
22
+ export declare function createCapabilitiesApi(getSet: () => ReadonlySet<string>): CapabilitiesApi;
23
+ /**
24
+ * 把已解码的 reply error 收敛为类型化的 CapabilityUnsupportedError(D6)。
25
+ *
26
+ * 识别两条路径:
27
+ * 1. 结构化路径(新宿主):`err.name === unsupportedName`,从 `err.data.capability` 提取能力名。
28
+ * 2. 老宿主 freeform 路径:`err.message` 匹配 `"Unknown method: <cap>"`。
29
+ * 其余错误原样透传。
30
+ */
31
+ export declare function mapToCapabilityError(err: Error, unsupportedName: string): Error;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/internal/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CapabilityUnsupportedError: () => CapabilityUnsupportedError,
24
+ createCapabilitiesApi: () => createCapabilitiesApi,
25
+ mapToCapabilityError: () => mapToCapabilityError,
26
+ readInjectedCapabilities: () => readInjectedCapabilities
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/internal/capabilities.ts
31
+ var CapabilityUnsupportedError = class extends Error {
32
+ capability;
33
+ constructor(capability) {
34
+ super(`Capability not supported by host: ${capability}`);
35
+ this.name = "CapabilityUnsupportedError";
36
+ this.capability = capability;
37
+ Object.setPrototypeOf(this, new.target.prototype);
38
+ }
39
+ };
40
+ function readInjectedCapabilities(global, key) {
41
+ const obj = global;
42
+ const raw = obj?.[key];
43
+ if (Array.isArray(raw?.capabilities)) {
44
+ return new Set(raw.capabilities);
45
+ }
46
+ return /* @__PURE__ */ new Set();
47
+ }
48
+ function createCapabilitiesApi(getSet) {
49
+ return {
50
+ has: (name) => getSet().has(name)
51
+ };
52
+ }
53
+ function mapToCapabilityError(err, unsupportedName) {
54
+ if (err.name === unsupportedName) {
55
+ const cap = err.data?.capability ?? "";
56
+ return new CapabilityUnsupportedError(cap);
57
+ }
58
+ const m = /^Unknown method:\s*(.+)$/.exec(err.message);
59
+ if (m) return new CapabilityUnsupportedError(m[1]);
60
+ return err;
61
+ }
62
+ // Annotate the CommonJS export names for ESM import in node:
63
+ 0 && (module.exports = {
64
+ CapabilityUnsupportedError,
65
+ createCapabilitiesApi,
66
+ mapToCapabilityError,
67
+ readInjectedCapabilities
68
+ });
@@ -0,0 +1 @@
1
+ export { readInjectedCapabilities, createCapabilitiesApi, mapToCapabilityError, CapabilityUnsupportedError } from './capabilities.js';
@@ -0,0 +1,7 @@
1
+ type LogFn = (...args: unknown[]) => void;
2
+ export declare const internalConsole: Readonly<{
3
+ log: LogFn;
4
+ warn: LogFn;
5
+ error: LogFn;
6
+ }>;
7
+ export {};
@@ -0,0 +1,48 @@
1
+ export interface IPCBusIO {
2
+ write(line: string): void;
3
+ onLine(handler: (line: string) => void): void;
4
+ }
5
+ export interface InboundHandler<Req, Resp> {
6
+ (request: Req): Promise<Resp> | Resp;
7
+ }
8
+ export interface IPCBus {
9
+ request<Req, Resp>(method: string, payload: Req): Promise<Resp>;
10
+ onMethod<Req, Resp>(method: string, handler: InboundHandler<Req, Resp>): void;
11
+ start(): void;
12
+ }
13
+ /**
14
+ * Structured error frame shape (D6.1 upgrade). Old wire shape was `error: string`;
15
+ * the bus now emits `error: { name, message, data? }` and accepts both shapes on
16
+ * the inbound path. See docs/specs/2026-05-19-plugin-ui-to-runtime-rpc-design.md §7.
17
+ */
18
+ export interface IPCBusErrorFrame {
19
+ name: string;
20
+ message: string;
21
+ data?: unknown;
22
+ }
23
+ /**
24
+ * Serialize a thrown value into the structured wire shape `{name, message, data?}`.
25
+ * Preserves Error subclass `.name` and any `.data` payload custom Error
26
+ * subclasses may carry. Non-Error throws collapse to `name: 'Error'`.
27
+ */
28
+ export declare function serializeError(err: unknown): IPCBusErrorFrame;
29
+ /**
30
+ * Reconstruct an Error from a wire-side error field. Accepts both the legacy
31
+ * bare-string shape (older native runtime) and the new structured shape
32
+ * (D6.1+). Custom Error subclass prototypes cannot be restored across the bus
33
+ * — callers should branch on `err.name` and read `(err as any).data` for
34
+ * business fields.
35
+ */
36
+ export declare function deserializeError(raw: unknown): Error;
37
+ export declare function createIPCBus(io: IPCBusIO): IPCBus;
38
+ /**
39
+ * Configure the global IPC bus singleton.
40
+ * Must be called once by the plugin runtime before any generated code runs.
41
+ */
42
+ export declare function configureIpcBus(bus: IPCBus): void;
43
+ /**
44
+ * The global IPC bus singleton.
45
+ * Access is proxied so callers can import `ipcBus` at module evaluation time
46
+ * without requiring the bus to be configured yet.
47
+ */
48
+ export declare const ipcBus: IPCBus;
@@ -0,0 +1,3 @@
1
+ import type { PluginRuntimeInvokePayload } from '../generated/capabilityClients.generated.js';
2
+ export declare function callRuntimeInvokeStrict(payload: PluginRuntimeInvokePayload): Promise<unknown>;
3
+ export declare function parseReplyError(raw: unknown): Error;
@@ -0,0 +1,20 @@
1
+ export type Unsubscribe = () => void;
2
+ export interface Stream<T> {
3
+ on(listener: (event: T) => void): Unsubscribe;
4
+ }
5
+ export interface Topic<T> extends Stream<T> {
6
+ current(): T | undefined;
7
+ }
8
+ export interface MutableTopic<T> extends Topic<T> {
9
+ set(value: T): void;
10
+ }
11
+ export interface MutableStream<T> extends Stream<T> {
12
+ emit(event: T): void;
13
+ }
14
+ export declare function createTopic<T>(initial?: T): MutableTopic<T>;
15
+ export declare function createStream<T>(): MutableStream<T>;
16
+ /**
17
+ * Read a window global by name and return its value (or undefined in
18
+ * non-browser environments such as Node test runners).
19
+ */
20
+ export declare function readWindowGlobal<T = unknown>(key: string): T | undefined;
@@ -0,0 +1,6 @@
1
+ import type { MessageContract } from '../shared/defineMessage.js';
2
+ import type { MessageHandler, MessageHandlerContext } from '../generated/runtime.definePlugin.generated.js';
3
+ export interface RuntimeMessageContract<TReq, TResp> extends MessageContract<TReq, TResp> {
4
+ handle(fn: (req: TReq, ctx: MessageHandlerContext) => Promise<TResp> | TResp): readonly [string, MessageHandler];
5
+ }
6
+ export declare function defineMessage<TReq, TResp>(key: string): RuntimeMessageContract<TReq, TResp>;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/runtime/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CapabilityUnsupportedError: () => CapabilityUnsupportedError,
24
+ actionResult: () => actionResult,
25
+ defineMessage: () => defineMessage,
26
+ definePlugin: () => definePlugin,
27
+ host: () => host
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/internal/internalConsole.ts
32
+ function pick(method) {
33
+ if (typeof globalThis === "undefined") return () => {
34
+ };
35
+ const g = globalThis;
36
+ const fn = g.console?.[method];
37
+ if (typeof fn !== "function") return () => {
38
+ };
39
+ return fn.bind(g.console);
40
+ }
41
+ var internalConsole = Object.freeze({
42
+ log: pick("log"),
43
+ warn: pick("warn"),
44
+ error: pick("error")
45
+ });
46
+
47
+ // src/internal/ipcBus.ts
48
+ var _instance = null;
49
+ var ipcBus = new Proxy({}, {
50
+ get(_target, prop) {
51
+ if (!_instance) {
52
+ throw new Error("[clipbus-plugin] ipcBus accessed before configureIpcBus() was called.");
53
+ }
54
+ return _instance[prop];
55
+ }
56
+ });
57
+
58
+ // src/generated/runtime.host.generated.ts
59
+ var host = {
60
+ item: {
61
+ setTags: (payload) => ipcBus.request("item.setTags", payload),
62
+ addTags: (payload) => ipcBus.request("item.addTags", payload),
63
+ removeTags: (payload) => ipcBus.request("item.removeTags", payload),
64
+ setPinned: (payload) => ipcBus.request("item.setPinned", payload),
65
+ setAttachments: (payload) => ipcBus.request("item.setAttachments", payload),
66
+ setSearchExtension: (payload) => ipcBus.request("item.setSearchExtension", payload),
67
+ materializeImagePath: () => ipcBus.request("item.materializeImagePath", {}),
68
+ readAttachment: (payload) => ipcBus.request("item.readAttachment", payload)
69
+ },
70
+ asset: {
71
+ registerImage: (payload) => ipcBus.request("asset.registerImage", payload)
72
+ },
73
+ clipboard: {
74
+ copyText: (payload) => ipcBus.request("clipboard.copyText", payload)
75
+ },
76
+ navigation: {
77
+ openUrl: (payload) => ipcBus.request("navigation.openUrl", payload),
78
+ revealInFinder: (payload) => ipcBus.request("navigation.revealInFinder", payload),
79
+ openFilePath: (payload) => ipcBus.request("navigation.openFilePath", payload)
80
+ },
81
+ action: {
82
+ allocateImageTempPath: (payload) => ipcBus.request("action.allocateImageTempPath", payload)
83
+ },
84
+ settings: {
85
+ get: (payload) => ipcBus.request("settings.get", payload),
86
+ getAll: () => ipcBus.request("settings.getAll", {})
87
+ },
88
+ console: {
89
+ log: (payload) => ipcBus.request("console.log", payload)
90
+ }
91
+ };
92
+
93
+ // src/generated/runtime.definePlugin.generated.ts
94
+ function definePlugin(definition) {
95
+ if ("setup" in definition) {
96
+ return {
97
+ setup() {
98
+ const registry = definition.setup();
99
+ validateRegistry(registry);
100
+ return registry;
101
+ }
102
+ };
103
+ }
104
+ validateRegistry(definition);
105
+ return { setup() {
106
+ return definition;
107
+ } };
108
+ }
109
+ function validateRegistry(registry) {
110
+ for (const [id, handler] of Object.entries(registry.attachmentRenderers ?? {})) {
111
+ if (handler && typeof handler === "object" && "invokeOperation" in handler) {
112
+ throw new Error(`attachmentRenderers["${id}"]: invokeOperation has been removed.`);
113
+ }
114
+ }
115
+ for (const [id, handler] of Object.entries(registry.actions ?? {})) {
116
+ if (handler && typeof handler === "object" && "invokeOperation" in handler) {
117
+ throw new Error(`actions["${id}"]: invokeOperation has been removed.`);
118
+ }
119
+ }
120
+ }
121
+
122
+ // src/generated/runtime.actionResult.generated.ts
123
+ var actionResult = {
124
+ text: (text, options) => ({
125
+ result: { resultKind: "text", text },
126
+ userMessage: options?.userMessage
127
+ }),
128
+ image: (imageTempPath, options) => ({
129
+ result: { resultKind: "image", imageTempPath, ...options && "imageFormatHint" in options ? { imageFormatHint: options.imageFormatHint } : {} },
130
+ userMessage: options?.userMessage
131
+ }),
132
+ none: (options) => ({
133
+ result: { resultKind: "none" },
134
+ userMessage: options?.userMessage
135
+ })
136
+ };
137
+
138
+ // src/runtime/defineMessage.ts
139
+ function defineMessage(key) {
140
+ return {
141
+ key,
142
+ handle: (fn) => [key, ((req, ctx) => fn(req, ctx))]
143
+ };
144
+ }
145
+
146
+ // src/internal/capabilities.ts
147
+ var CapabilityUnsupportedError = class extends Error {
148
+ capability;
149
+ constructor(capability) {
150
+ super(`Capability not supported by host: ${capability}`);
151
+ this.name = "CapabilityUnsupportedError";
152
+ this.capability = capability;
153
+ Object.setPrototypeOf(this, new.target.prototype);
154
+ }
155
+ };
156
+ // Annotate the CommonJS export names for ESM import in node:
157
+ 0 && (module.exports = {
158
+ CapabilityUnsupportedError,
159
+ actionResult,
160
+ defineMessage,
161
+ definePlugin,
162
+ host
163
+ });
@@ -0,0 +1,4 @@
1
+ export * from '../generated/INDEX.runtime.generated.js';
2
+ export { defineMessage } from './defineMessage.js';
3
+ export type { RuntimeMessageContract } from './defineMessage.js';
4
+ export { CapabilityUnsupportedError } from '../internal/capabilities.js';
@@ -0,0 +1,4 @@
1
+ export * from '../generated/INDEX.runtime.generated.js';
2
+ export { defineMessage } from './defineMessage.js';
3
+ export type { RuntimeMessageContract } from './defineMessage.js';
4
+ export { CapabilityUnsupportedError } from '../internal/capabilities.js';