@burdenoff/fe-libs 2026.521.2 → 2026.521.4
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/dist/shared/plugins/iframe-mount/PluginIframe.d.ts +75 -0
- package/dist/shared/plugins/iframe-mount/PluginIframe.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/PluginIframe.js +158 -0
- package/dist/shared/plugins/iframe-mount/PluginMount.d.ts +59 -0
- package/dist/shared/plugins/iframe-mount/PluginMount.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/PluginMount.js +129 -0
- package/dist/shared/plugins/iframe-mount/client/index.d.ts +3 -0
- package/dist/shared/plugins/iframe-mount/client/index.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/client/message-bus.d.ts +71 -0
- package/dist/shared/plugins/iframe-mount/client/message-bus.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/client/message-bus.js +65 -0
- package/dist/shared/plugins/iframe-mount/client/rpc.d.ts +25 -0
- package/dist/shared/plugins/iframe-mount/client/rpc.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/client/rpc.js +63 -0
- package/dist/shared/plugins/iframe-mount/index.d.ts +6 -0
- package/dist/shared/plugins/iframe-mount/index.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/index.js +4 -0
- package/dist/shared/plugins/iframe-mount/protocol/contribution.d.ts +83 -0
- package/dist/shared/plugins/iframe-mount/protocol/contribution.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/protocol/envelope.d.ts +136 -0
- package/dist/shared/plugins/iframe-mount/protocol/envelope.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/protocol/envelope.js +10 -0
- package/dist/shared/plugins/iframe-mount/protocol/index.d.ts +3 -0
- package/dist/shared/plugins/iframe-mount/protocol/index.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/sandbox.d.ts +3 -0
- package/dist/shared/plugins/iframe-mount/sandbox.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/sandbox.js +19 -0
- package/dist/shared/plugins/iframe-mount/types.d.ts +64 -0
- package/dist/shared/plugins/iframe-mount/types.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/useFetchContributions.d.ts +31 -0
- package/dist/shared/plugins/iframe-mount/useFetchContributions.d.ts.map +1 -0
- package/dist/shared/plugins/iframe-mount/useFetchContributions.js +68 -0
- package/dist/shared/plugins/index.d.ts +1 -0
- package/dist/shared/plugins/index.d.ts.map +1 -1
- package/dist/shared-plugins.js +6 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PluginCapabilities, PluginErrorPayload, PluginEventEmitPayload, PluginResizeRequestPayload, PluginSetBadgePayload, PluginSetTitlePayload } from './protocol/index.js';
|
|
3
|
+
export interface PluginIframeRpcContext {
|
|
4
|
+
capabilities: PluginCapabilities;
|
|
5
|
+
/** Reflects the iframe iframe back through for downstream handlers. */
|
|
6
|
+
iframe: HTMLIFrameElement;
|
|
7
|
+
}
|
|
8
|
+
export type PluginIframeRpcHandler = (method: string, args: unknown, ctx: PluginIframeRpcContext) => Promise<unknown>;
|
|
9
|
+
export interface PluginIframeProps {
|
|
10
|
+
/** Absolute or relative URL the iframe loads. */
|
|
11
|
+
src: string;
|
|
12
|
+
/** Origin the iframe is allowed to postMessage to / from. */
|
|
13
|
+
origin: string;
|
|
14
|
+
/** Mount point id passed to the plugin in `host:init`. */
|
|
15
|
+
mountPoint: string;
|
|
16
|
+
/** Context payload passed to the plugin in `host:init` (e.g. `{ vibeId }`). */
|
|
17
|
+
context: Record<string, unknown>;
|
|
18
|
+
/** Agent id whose tunnel serves the iframe. */
|
|
19
|
+
agentId: string;
|
|
20
|
+
/** Profile name (CLI segment on the agent). */
|
|
21
|
+
profile: string;
|
|
22
|
+
/** Tunnel base URL the plugin should call for REST. */
|
|
23
|
+
tunnelUrl: string;
|
|
24
|
+
/** Iframe token scoped to the plugin's `capabilities.restPaths`. */
|
|
25
|
+
iframeToken: string;
|
|
26
|
+
/** Capabilities the plugin declared in its manifest. Used to derive sandbox. */
|
|
27
|
+
capabilities: PluginCapabilities;
|
|
28
|
+
/** Theme broadcast to the plugin. Updates re-flow into the iframe via host:theme-change. */
|
|
29
|
+
theme: {
|
|
30
|
+
colorMode: 'light' | 'dark';
|
|
31
|
+
tokens: Record<string, string>;
|
|
32
|
+
};
|
|
33
|
+
/** Locale broadcast to the plugin. */
|
|
34
|
+
locale: string;
|
|
35
|
+
/** Feature-flag snapshot broadcast to the plugin. */
|
|
36
|
+
featureFlags: Record<string, boolean>;
|
|
37
|
+
/** Host version surfaced via `host:init`. */
|
|
38
|
+
hostVersion: string;
|
|
39
|
+
/** RPC handler the host wires up. Method allow-list is enforced separately. */
|
|
40
|
+
onRpcRequest: PluginIframeRpcHandler;
|
|
41
|
+
/** Called when the plugin emits an event UP to the host EventBus. */
|
|
42
|
+
onPluginEvent?: (payload: PluginEventEmitPayload) => void;
|
|
43
|
+
/** Called when the plugin asks to update its tab/widget badge. */
|
|
44
|
+
onBadgeRequest?: (value: PluginSetBadgePayload['value']) => void;
|
|
45
|
+
/** Called when the plugin asks to update its tab/widget title. */
|
|
46
|
+
onTitleRequest?: (value: PluginSetTitlePayload['value']) => void;
|
|
47
|
+
/** Called when the plugin asks the host to resize the iframe. Host decides. */
|
|
48
|
+
onResizeRequest?: (opts: PluginResizeRequestPayload) => void;
|
|
49
|
+
/** Called when the plugin self-reports a runtime error. */
|
|
50
|
+
onPluginError?: (payload: PluginErrorPayload) => void;
|
|
51
|
+
/** Rendered while the iframe is loading / before `plugin:ready`. */
|
|
52
|
+
loadingFallback?: ReactNode;
|
|
53
|
+
/** Rendered when the handshake times out. Receives the error message. */
|
|
54
|
+
errorFallback?: (error: {
|
|
55
|
+
message: string;
|
|
56
|
+
}) => ReactNode;
|
|
57
|
+
/** Override the 10s ready timeout. */
|
|
58
|
+
readyTimeoutMs?: number;
|
|
59
|
+
/** Forwarded `<iframe>` attributes for layout / styling. */
|
|
60
|
+
title?: string;
|
|
61
|
+
className?: string;
|
|
62
|
+
style?: React.CSSProperties;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Host-side iframe primitive. Mounts an iframe at `src`, runs the v1
|
|
66
|
+
* postMessage handshake, derives the sandbox attribute from the
|
|
67
|
+
* plugin's manifest capabilities, and translates the plugin's RPC
|
|
68
|
+
* requests into host service calls.
|
|
69
|
+
*
|
|
70
|
+
* Cross-product: depends only on the inlined `./protocol` + `./client` envelope
|
|
71
|
+
* but not on any product-specific gateway / tunnel concept. Host pages
|
|
72
|
+
* supply the URL + token + RPC handler.
|
|
73
|
+
*/
|
|
74
|
+
export declare function PluginIframe(props: PluginIframeProps): import("react/jsx-runtime").JSX.Element;
|
|
75
|
+
//# sourceMappingURL=PluginIframe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginIframe.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/PluginIframe.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7E,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EAEtB,0BAA0B,EAE1B,qBAAqB,EACrB,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAY7B,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,kBAAkB,CAAC;IACjC,uEAAuE;IACvE,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,sBAAsB,KACxB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,YAAY,EAAE,kBAAkB,CAAC;IACjC,4FAA4F;IAC5F,KAAK,EAAE;QAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACvE,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,YAAY,EAAE,sBAAsB,CAAC;IACrC,qEAAqE;IACrE,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC1D,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACjE,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACjE,+EAA+E;IAC/E,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC7D,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACtD,oEAAoE;IACpE,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,yEAAyE;IACzE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAC;IAC1D,sCAAsC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CA6QpD"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { deriveSandbox as e } from "./sandbox.js";
|
|
2
|
+
import { ParentMessageBus as t, buildHostEnvelope as n } from "./client/message-bus.js";
|
|
3
|
+
import { RpcDispatcher as r } from "./client/rpc.js";
|
|
4
|
+
import { useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
|
|
5
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
6
|
+
//#region src/shared/plugins/iframe-mount/PluginIframe.tsx
|
|
7
|
+
var u = 1e4;
|
|
8
|
+
function d(d) {
|
|
9
|
+
let { src: f, origin: p, mountPoint: m, context: h, agentId: g, profile: _, tunnelUrl: v, iframeToken: y, capabilities: b, theme: x, locale: S, featureFlags: C, hostVersion: w, onRpcRequest: T, onPluginEvent: E, onBadgeRequest: D, onTitleRequest: O, onResizeRequest: k, onPluginError: A, loadingFallback: j = null, errorFallback: M, readyTimeoutMs: N = u, title: P, className: F, style: I } = d, L = o(null), R = o(null), z = o(null), B = o(!1), [V, H] = s("loading"), [U, W] = s(null), ee = a(() => e(b), [b]), G = o({
|
|
10
|
+
iframeToken: y,
|
|
11
|
+
tunnelUrl: v,
|
|
12
|
+
mountPoint: m,
|
|
13
|
+
context: h,
|
|
14
|
+
agentId: g,
|
|
15
|
+
profile: _,
|
|
16
|
+
theme: x,
|
|
17
|
+
locale: S,
|
|
18
|
+
capabilities: b,
|
|
19
|
+
featureFlags: C,
|
|
20
|
+
sdkVersion: "1",
|
|
21
|
+
hostVersion: w
|
|
22
|
+
});
|
|
23
|
+
G.current = {
|
|
24
|
+
iframeToken: y,
|
|
25
|
+
tunnelUrl: v,
|
|
26
|
+
mountPoint: m,
|
|
27
|
+
context: h,
|
|
28
|
+
agentId: g,
|
|
29
|
+
profile: _,
|
|
30
|
+
theme: x,
|
|
31
|
+
locale: S,
|
|
32
|
+
capabilities: b,
|
|
33
|
+
featureFlags: C,
|
|
34
|
+
sdkVersion: "1",
|
|
35
|
+
hostVersion: w
|
|
36
|
+
};
|
|
37
|
+
let K = () => G.current, q = o(T);
|
|
38
|
+
q.current = T;
|
|
39
|
+
let J = o(b);
|
|
40
|
+
J.current = b;
|
|
41
|
+
let Y = o(E);
|
|
42
|
+
Y.current = E;
|
|
43
|
+
let X = o(D);
|
|
44
|
+
X.current = D;
|
|
45
|
+
let Z = o(O);
|
|
46
|
+
Z.current = O;
|
|
47
|
+
let Q = o(k);
|
|
48
|
+
Q.current = k;
|
|
49
|
+
let $ = o(A);
|
|
50
|
+
return $.current = A, i(() => {
|
|
51
|
+
let e = L.current;
|
|
52
|
+
if (!e) return;
|
|
53
|
+
let i = e.contentWindow, a = new t({
|
|
54
|
+
allowedOrigins: [p],
|
|
55
|
+
iframe: e,
|
|
56
|
+
expectedSource: i
|
|
57
|
+
});
|
|
58
|
+
R.current = a;
|
|
59
|
+
let o = new r({ send(e, t, n, r) {} });
|
|
60
|
+
z.current = o;
|
|
61
|
+
let s = setTimeout(() => {
|
|
62
|
+
B.current || (H("error"), W(`Plugin did not respond within ${N}ms`));
|
|
63
|
+
}, N), c = a.on(async (t) => {
|
|
64
|
+
switch (t.kind) {
|
|
65
|
+
case "plugin:ready":
|
|
66
|
+
t.payload, B.current = !0, H("ready"), W(null), a.send(n("host:init", K()));
|
|
67
|
+
return;
|
|
68
|
+
case "plugin:rpc-request": {
|
|
69
|
+
let r = t.payload, i = t.requestId;
|
|
70
|
+
if (!i) return;
|
|
71
|
+
if (!J.current.rpcMethods.includes(r.method)) {
|
|
72
|
+
a.send(n("host:rpc-response", {
|
|
73
|
+
ok: !1,
|
|
74
|
+
error: {
|
|
75
|
+
code: "capability_denied",
|
|
76
|
+
message: `Method '${r.method}' is not in the plugin's declared rpcMethods.`
|
|
77
|
+
}
|
|
78
|
+
}, i));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
let t = await q.current(r.method, r.args, {
|
|
83
|
+
capabilities: J.current,
|
|
84
|
+
iframe: e
|
|
85
|
+
});
|
|
86
|
+
a.send(n("host:rpc-response", {
|
|
87
|
+
ok: !0,
|
|
88
|
+
result: t
|
|
89
|
+
}, i));
|
|
90
|
+
} catch (e) {
|
|
91
|
+
let t = e instanceof Error ? e.message : String(e), r = e && typeof e == "object" && "code" in e ? String(e.code ?? "rpc_handler_failed") : "rpc_handler_failed";
|
|
92
|
+
a.send(n("host:rpc-response", {
|
|
93
|
+
ok: !1,
|
|
94
|
+
error: {
|
|
95
|
+
code: r,
|
|
96
|
+
message: t
|
|
97
|
+
}
|
|
98
|
+
}, i));
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
case "plugin:event-emit":
|
|
103
|
+
Y.current?.(t.payload);
|
|
104
|
+
return;
|
|
105
|
+
case "plugin:set-badge":
|
|
106
|
+
X.current?.(t.payload.value);
|
|
107
|
+
return;
|
|
108
|
+
case "plugin:set-title":
|
|
109
|
+
Z.current?.(t.payload.value);
|
|
110
|
+
return;
|
|
111
|
+
case "plugin:resize-request":
|
|
112
|
+
Q.current?.(t.payload);
|
|
113
|
+
return;
|
|
114
|
+
case "plugin:error":
|
|
115
|
+
$.current?.(t.payload);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return () => {
|
|
120
|
+
clearTimeout(s), c(), a.send(n("host:dispose", {})), a.dispose(), o.rejectAll(/* @__PURE__ */ Error("PluginIframe unmounted")), R.current = null, z.current = null, B.current = !1;
|
|
121
|
+
};
|
|
122
|
+
}, [f, p]), i(() => {
|
|
123
|
+
B.current && R.current?.send(n("host:theme-change", {
|
|
124
|
+
colorMode: x.colorMode,
|
|
125
|
+
tokens: x.tokens
|
|
126
|
+
}));
|
|
127
|
+
}, [x.colorMode, x.tokens]), i(() => {
|
|
128
|
+
B.current && R.current?.send(n("host:locale-change", { locale: S }));
|
|
129
|
+
}, [S]), i(() => {
|
|
130
|
+
B.current && R.current?.send(n("host:context-change", { context: h }));
|
|
131
|
+
}, [h]), i(() => {
|
|
132
|
+
if (B.current) for (let [e, t] of Object.entries(C)) R.current?.send(n("host:feature-flag", {
|
|
133
|
+
flag: e,
|
|
134
|
+
value: t
|
|
135
|
+
}));
|
|
136
|
+
}, [C]), /* @__PURE__ */ l("div", {
|
|
137
|
+
className: F,
|
|
138
|
+
style: I,
|
|
139
|
+
children: [
|
|
140
|
+
V === "error" && M ? M({ message: U ?? "" }) : null,
|
|
141
|
+
V === "loading" ? j : null,
|
|
142
|
+
/* @__PURE__ */ c("iframe", {
|
|
143
|
+
ref: L,
|
|
144
|
+
src: f,
|
|
145
|
+
title: P ?? "Plugin iframe",
|
|
146
|
+
sandbox: ee,
|
|
147
|
+
style: {
|
|
148
|
+
width: "100%",
|
|
149
|
+
height: "100%",
|
|
150
|
+
border: 0,
|
|
151
|
+
display: V === "error" ? "none" : "block"
|
|
152
|
+
}
|
|
153
|
+
})
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
export { d as PluginIframe };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { PluginIframe, PluginIframeProps, PluginIframeRpcHandler } from './PluginIframe';
|
|
3
|
+
import { DiscoveredContribution, InProcessPluginEntry, RuntimePreference } from './types';
|
|
4
|
+
export interface PluginMountChildProps {
|
|
5
|
+
/** Discovered contribution being mounted. */
|
|
6
|
+
contribution: DiscoveredContribution;
|
|
7
|
+
/** The chosen runtime (`'iframe'` or `'in-process'`). */
|
|
8
|
+
runtime: 'iframe' | 'in-process';
|
|
9
|
+
/** Rendered iframe element (only present for `runtime === 'iframe'`). */
|
|
10
|
+
iframeProps?: Omit<PluginIframeProps, 'loadingFallback' | 'errorFallback' | 'title' | 'className' | 'style'>;
|
|
11
|
+
/** Rendered React component (only present for `runtime === 'in-process'`). */
|
|
12
|
+
inProcessNode?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
export interface PluginMountProps {
|
|
15
|
+
/** Discovered iframe contributions from the agent. */
|
|
16
|
+
contributions: DiscoveredContribution[];
|
|
17
|
+
/** In-process plugin components registered by the host shell. */
|
|
18
|
+
inProcess?: InProcessPluginEntry[];
|
|
19
|
+
/** Per-page context passed to the plugin via `host:init`. */
|
|
20
|
+
context: Record<string, unknown>;
|
|
21
|
+
/** Agent id whose tunnel serves the iframe contributions. */
|
|
22
|
+
agentId: string;
|
|
23
|
+
/** Theme broadcast to plugin iframes (and to in-process plugins via the bridge). */
|
|
24
|
+
theme: {
|
|
25
|
+
colorMode: 'light' | 'dark';
|
|
26
|
+
tokens: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
/** Locale broadcast to plugins. */
|
|
29
|
+
locale: string;
|
|
30
|
+
/** Feature flags surfaced to plugins. */
|
|
31
|
+
featureFlags: Record<string, boolean>;
|
|
32
|
+
/** Host shell version surfaced via `host:init`. */
|
|
33
|
+
hostVersion: string;
|
|
34
|
+
/** RPC handler that resolves `plugin:rpc-request` calls. */
|
|
35
|
+
onRpcRequest: PluginIframeRpcHandler;
|
|
36
|
+
/**
|
|
37
|
+
* Preference between runtimes when a contribution declares both. The
|
|
38
|
+
* default is `iframe` (sandboxed; works for user-installable plugins).
|
|
39
|
+
* Pages that want first-party in-process plugins to win can pass
|
|
40
|
+
* `'in-process'`.
|
|
41
|
+
*/
|
|
42
|
+
prefer?: RuntimePreference;
|
|
43
|
+
/**
|
|
44
|
+
* Renders each contribution. The host page is responsible for the
|
|
45
|
+
* actual tab/widget chrome; this primitive just feeds it the right
|
|
46
|
+
* props.
|
|
47
|
+
*/
|
|
48
|
+
children: (props: PluginMountChildProps) => ReactNode;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Iterator over discovered contributions. Picks a runtime per
|
|
52
|
+
* contribution (iframe or in-process), mints/refreshes the iframe
|
|
53
|
+
* token, and delegates rendering to the consumer via the `children`
|
|
54
|
+
* render-prop.
|
|
55
|
+
*/
|
|
56
|
+
export declare function PluginMount(props: PluginMountProps): import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
/** Re-export so consumers can render the iframe directly from their child render-prop. */
|
|
58
|
+
export { PluginIframe };
|
|
59
|
+
//# sourceMappingURL=PluginMount.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginMount.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/PluginMount.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,KAAK,EACV,sBAAsB,EACtB,oBAAoB,EAEpB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,YAAY,EAAE,sBAAsB,CAAC;IACrC,yDAAyD;IACzD,OAAO,EAAE,QAAQ,GAAG,YAAY,CAAC;IACjC,yEAAyE;IACzE,WAAW,CAAC,EAAE,IAAI,CAChB,iBAAiB,EACjB,iBAAiB,GAAG,eAAe,GAAG,OAAO,GAAG,WAAW,GAAG,OAAO,CACtE,CAAC;IACF,8EAA8E;IAC9E,aAAa,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,aAAa,EAAE,sBAAsB,EAAE,CAAC;IACxC,iEAAiE;IACjE,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACnC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,KAAK,EAAE;QAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACvE,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,YAAY,EAAE,sBAAsB,CAAC;IACrC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,SAAS,CAAC;CACvD;AAOD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAgGlD;AAkKD,0FAA0F;AAC1F,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import "./PluginIframe.js";
|
|
2
|
+
import { useEffect as e, useMemo as t, useRef as n, useState as r } from "react";
|
|
3
|
+
import { Fragment as i, jsx as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/shared/plugins/iframe-mount/PluginMount.tsx
|
|
5
|
+
function o(e) {
|
|
6
|
+
let { contributions: n, inProcess: r = [], context: o, agentId: l, theme: u, locale: d, featureFlags: f, hostVersion: p, onRpcRequest: m, prefer: h = "iframe", children: g } = e, _ = t(() => {
|
|
7
|
+
let e = /* @__PURE__ */ new Map();
|
|
8
|
+
for (let t of r) e.set(`${t.pluginKey}::${t.mountPoint}::${t.id}`, t);
|
|
9
|
+
return e;
|
|
10
|
+
}, [r]);
|
|
11
|
+
return /* @__PURE__ */ a(i, { children: n.map((e) => {
|
|
12
|
+
let { contribution: t, tunnel: n, url: r } = e, i = _.get(`${e.pluginKey}::${t.mountPoint}::${t.id}`), v = t.runtimes.includes("iframe"), y = t.runtimes.includes("in-process") && !!i, b = null;
|
|
13
|
+
if (h === "in-process" && y ? b = "in-process" : h === "iframe" && v || v ? b = "iframe" : y && (b = "in-process"), !b) return console.warn(`[PluginMount] No runtime available for contribution ${t.id} (mount ${t.mountPoint}). Declared:`, t.runtimes), null;
|
|
14
|
+
if (b === "in-process") {
|
|
15
|
+
let n = i.Component;
|
|
16
|
+
return /* @__PURE__ */ a(s, {
|
|
17
|
+
child: g,
|
|
18
|
+
childProps: {
|
|
19
|
+
contribution: e,
|
|
20
|
+
runtime: "in-process",
|
|
21
|
+
inProcessNode: /* @__PURE__ */ a(n, { context: o })
|
|
22
|
+
}
|
|
23
|
+
}, `in-process:${e.pluginKey}::${t.mountPoint}::${t.id}`);
|
|
24
|
+
}
|
|
25
|
+
return /* @__PURE__ */ a(c, {
|
|
26
|
+
discovered: e,
|
|
27
|
+
tunnel: n,
|
|
28
|
+
url: r,
|
|
29
|
+
context: o,
|
|
30
|
+
agentId: l,
|
|
31
|
+
theme: u,
|
|
32
|
+
locale: d,
|
|
33
|
+
featureFlags: f,
|
|
34
|
+
hostVersion: p,
|
|
35
|
+
onRpcRequest: m,
|
|
36
|
+
render: (t) => g({
|
|
37
|
+
contribution: e,
|
|
38
|
+
runtime: "iframe",
|
|
39
|
+
iframeProps: t
|
|
40
|
+
})
|
|
41
|
+
}, `iframe:${e.pluginKey}::${t.mountPoint}::${t.id}`);
|
|
42
|
+
}) });
|
|
43
|
+
}
|
|
44
|
+
function s(e) {
|
|
45
|
+
return /* @__PURE__ */ a(i, { children: e.child(e.childProps) });
|
|
46
|
+
}
|
|
47
|
+
function c(o) {
|
|
48
|
+
let { discovered: s, tunnel: c, url: l, context: u, agentId: d, theme: f, locale: p, featureFlags: m, hostVersion: h, onRpcRequest: g, render: _ } = o, [v, y] = r({
|
|
49
|
+
token: null,
|
|
50
|
+
expiresAt: 0
|
|
51
|
+
}), b = n(!0), x = s.capabilities.restPaths.join("|"), S = t(() => {
|
|
52
|
+
let e = s.capabilities.restPaths;
|
|
53
|
+
return e && e.length > 0 ? e : [`/ui/${s.pluginKey}`];
|
|
54
|
+
}, [s.pluginKey, x]);
|
|
55
|
+
if (e(() => {
|
|
56
|
+
return b.current = !0, e(S), () => {
|
|
57
|
+
b.current = !1;
|
|
58
|
+
};
|
|
59
|
+
async function e(e) {
|
|
60
|
+
try {
|
|
61
|
+
let { token: t, expiresAt: n } = await c.mintIframeToken({ pathPrefixes: e });
|
|
62
|
+
if (!b.current) return;
|
|
63
|
+
let r = Date.parse(n);
|
|
64
|
+
if (!Number.isFinite(r)) {
|
|
65
|
+
y({
|
|
66
|
+
token: null,
|
|
67
|
+
expiresAt: 0
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
y({
|
|
72
|
+
token: t,
|
|
73
|
+
expiresAt: r
|
|
74
|
+
});
|
|
75
|
+
} catch {
|
|
76
|
+
if (!b.current) return;
|
|
77
|
+
y({
|
|
78
|
+
token: null,
|
|
79
|
+
expiresAt: 0
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [c, S]), e(() => {
|
|
84
|
+
if (!v.token || v.expiresAt <= 0) return;
|
|
85
|
+
let e = Math.max(5e3, v.expiresAt - Date.now() - 6e4);
|
|
86
|
+
if (!Number.isFinite(e)) return;
|
|
87
|
+
let t = setTimeout(() => {
|
|
88
|
+
c.mintIframeToken({ pathPrefixes: S }).then(({ token: e, expiresAt: t }) => {
|
|
89
|
+
if (!b.current) return;
|
|
90
|
+
let n = Date.parse(t);
|
|
91
|
+
Number.isFinite(n) && y({
|
|
92
|
+
token: e,
|
|
93
|
+
expiresAt: n
|
|
94
|
+
});
|
|
95
|
+
}).catch(() => {});
|
|
96
|
+
}, e);
|
|
97
|
+
return () => clearTimeout(t);
|
|
98
|
+
}, [
|
|
99
|
+
v.token,
|
|
100
|
+
v.expiresAt,
|
|
101
|
+
c,
|
|
102
|
+
S
|
|
103
|
+
]), !v.token) return null;
|
|
104
|
+
let C = (() => {
|
|
105
|
+
try {
|
|
106
|
+
return new URL(c.tunnelUrl).origin;
|
|
107
|
+
} catch {
|
|
108
|
+
return c.tunnelUrl;
|
|
109
|
+
}
|
|
110
|
+
})();
|
|
111
|
+
return /* @__PURE__ */ a(i, { children: _({
|
|
112
|
+
src: `${c.tunnelUrl.replace(/\/$/, "")}${l.startsWith("/") ? l : `/${l}`}?vt=${encodeURIComponent(v.token)}`,
|
|
113
|
+
origin: C,
|
|
114
|
+
mountPoint: s.contribution.mountPoint,
|
|
115
|
+
context: u,
|
|
116
|
+
agentId: d,
|
|
117
|
+
profile: c.profile,
|
|
118
|
+
tunnelUrl: c.tunnelUrl,
|
|
119
|
+
iframeToken: v.token,
|
|
120
|
+
capabilities: s.capabilities,
|
|
121
|
+
theme: f,
|
|
122
|
+
locale: p,
|
|
123
|
+
featureFlags: m,
|
|
124
|
+
hostVersion: h,
|
|
125
|
+
onRpcRequest: g
|
|
126
|
+
}) });
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
export { o as PluginMount };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Envelope, HostEnvelope, HostOp, PluginEnvelope, PluginOp } from '../protocol/envelope.js';
|
|
2
|
+
export type EnvelopeHandler<E extends Envelope = Envelope> = (env: E) => void;
|
|
3
|
+
/** Subset of the DOM `Window` we depend on. Tests pass a stub. */
|
|
4
|
+
export interface MessageWindow {
|
|
5
|
+
addEventListener(type: 'message', listener: (event: MessageEvent) => void, options?: {
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}): void;
|
|
8
|
+
removeEventListener(type: 'message', listener: (event: MessageEvent) => void): void;
|
|
9
|
+
}
|
|
10
|
+
export interface MessageTarget {
|
|
11
|
+
postMessage(message: unknown, targetOrigin: string): void;
|
|
12
|
+
}
|
|
13
|
+
export interface BusOptions {
|
|
14
|
+
/** Identity check on every receive. Tightens the trust boundary. */
|
|
15
|
+
allowedOrigins: string[];
|
|
16
|
+
/** Optional handle to a specific `MessageEventSource` we expect. */
|
|
17
|
+
expectedSource?: MessageEventSource | null;
|
|
18
|
+
/** Stub-friendly window. Defaults to the platform `window` at runtime. */
|
|
19
|
+
window?: MessageWindow;
|
|
20
|
+
}
|
|
21
|
+
declare abstract class BaseMessageBus<TSend extends Envelope, TRecv extends Envelope> {
|
|
22
|
+
protected readonly options: BusOptions;
|
|
23
|
+
protected handlers: Set<EnvelopeHandler<TRecv>>;
|
|
24
|
+
protected disposed: boolean;
|
|
25
|
+
private readonly listener;
|
|
26
|
+
private readonly hostWindow;
|
|
27
|
+
constructor(options: BusOptions);
|
|
28
|
+
on(handler: EnvelopeHandler<TRecv>): () => void;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
protected abstract get target(): MessageTarget;
|
|
31
|
+
protected abstract get targetOrigin(): string;
|
|
32
|
+
protected abstract isExpectedDirection(env: Envelope): env is TRecv;
|
|
33
|
+
send(envelope: TSend): void;
|
|
34
|
+
private handleMessage;
|
|
35
|
+
}
|
|
36
|
+
export interface IframeBusOptions extends BusOptions {
|
|
37
|
+
/** The parent we postMessage UP to. Defaults to `window.parent`. */
|
|
38
|
+
parent?: MessageTarget;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The bus a plugin instance uses to talk to its host shell. Send a
|
|
42
|
+
* `PluginEnvelope` UP, receive `HostEnvelope`s DOWN.
|
|
43
|
+
*/
|
|
44
|
+
export declare class IframeMessageBus extends BaseMessageBus<PluginEnvelope, HostEnvelope> {
|
|
45
|
+
private readonly parentTarget;
|
|
46
|
+
private readonly origin;
|
|
47
|
+
constructor(opts: IframeBusOptions);
|
|
48
|
+
protected get target(): MessageTarget;
|
|
49
|
+
protected get targetOrigin(): string;
|
|
50
|
+
protected isExpectedDirection(env: Envelope): env is HostEnvelope;
|
|
51
|
+
}
|
|
52
|
+
export interface ParentBusOptions extends BusOptions {
|
|
53
|
+
/** The iframe element we postMessage DOWN to. */
|
|
54
|
+
iframe: HTMLIFrameElement;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The bus a host page uses to talk to one iframe-mounted plugin instance.
|
|
58
|
+
* Send a `HostEnvelope` DOWN, receive `PluginEnvelope`s UP.
|
|
59
|
+
*/
|
|
60
|
+
export declare class ParentMessageBus extends BaseMessageBus<HostEnvelope, PluginEnvelope> {
|
|
61
|
+
private readonly iframe;
|
|
62
|
+
private readonly origin;
|
|
63
|
+
constructor(opts: ParentBusOptions);
|
|
64
|
+
protected get target(): MessageTarget;
|
|
65
|
+
protected get targetOrigin(): string;
|
|
66
|
+
protected isExpectedDirection(env: Envelope): env is PluginEnvelope;
|
|
67
|
+
}
|
|
68
|
+
export declare function buildHostEnvelope<P = unknown>(kind: HostOp, payload: P, requestId?: string): HostEnvelope<P>;
|
|
69
|
+
export declare function buildPluginEnvelope<P = unknown>(kind: PluginOp, payload: P, requestId?: string): PluginEnvelope<P>;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=message-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-bus.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/client/message-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { isEnvelope as e, isPluginEnvelope as t } from "../protocol/envelope.js";
|
|
2
|
+
//#region src/shared/plugins/iframe-mount/client/message-bus.ts
|
|
3
|
+
function n(e, t) {
|
|
4
|
+
return t.includes("*") ? !0 : t.includes(e);
|
|
5
|
+
}
|
|
6
|
+
function r() {
|
|
7
|
+
if (typeof globalThis > "u" || !("window" in globalThis)) throw Error("No `window` available — postMessage transport unavailable");
|
|
8
|
+
return globalThis.window;
|
|
9
|
+
}
|
|
10
|
+
var i = class {
|
|
11
|
+
handlers = /* @__PURE__ */ new Set();
|
|
12
|
+
disposed = !1;
|
|
13
|
+
listener;
|
|
14
|
+
hostWindow;
|
|
15
|
+
constructor(e) {
|
|
16
|
+
this.options = e, this.hostWindow = e.window ?? r(), this.listener = (e) => this.handleMessage(e), this.hostWindow.addEventListener("message", this.listener);
|
|
17
|
+
}
|
|
18
|
+
on(e) {
|
|
19
|
+
return this.handlers.add(e), () => this.handlers.delete(e);
|
|
20
|
+
}
|
|
21
|
+
dispose() {
|
|
22
|
+
this.disposed || (this.disposed = !0, this.handlers.clear(), this.hostWindow.removeEventListener("message", this.listener));
|
|
23
|
+
}
|
|
24
|
+
send(e) {
|
|
25
|
+
if (!this.disposed) {
|
|
26
|
+
if (e.v !== 1) throw Error(`Refusing to send envelope with version ${e.v} — runtime expects v1`);
|
|
27
|
+
this.target.postMessage(e, this.targetOrigin);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
handleMessage(t) {
|
|
31
|
+
if (!this.disposed && n(t.origin, this.options.allowedOrigins) && !(this.options.expectedSource !== void 0 && this.options.expectedSource !== null && t.source !== this.options.expectedSource) && e(t.data) && this.isExpectedDirection(t.data)) for (let e of this.handlers) try {
|
|
32
|
+
e(t.data);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.error("[vibecontrols-ui-plugin-sdk] handler threw", e);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, a = class extends i {
|
|
38
|
+
iframe;
|
|
39
|
+
origin;
|
|
40
|
+
constructor(e) {
|
|
41
|
+
super(e), this.iframe = e.iframe, this.origin = e.allowedOrigins.length === 1 ? e.allowedOrigins[0] : e.allowedOrigins[0] ?? "*";
|
|
42
|
+
}
|
|
43
|
+
get target() {
|
|
44
|
+
let e = this.iframe.contentWindow;
|
|
45
|
+
if (!e) throw Error("iframe.contentWindow is null — iframe is not yet loaded");
|
|
46
|
+
return e;
|
|
47
|
+
}
|
|
48
|
+
get targetOrigin() {
|
|
49
|
+
return this.origin;
|
|
50
|
+
}
|
|
51
|
+
isExpectedDirection(e) {
|
|
52
|
+
return t(e);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
function o(e, t, n) {
|
|
56
|
+
return {
|
|
57
|
+
v: 1,
|
|
58
|
+
source: "host",
|
|
59
|
+
kind: e,
|
|
60
|
+
payload: t,
|
|
61
|
+
requestId: n
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { a as ParentMessageBus, o as buildHostEnvelope };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HostRpcProgressPayload, HostRpcResponsePayload } from '../protocol/envelope.js';
|
|
2
|
+
export type RpcMethod = string;
|
|
3
|
+
export interface RpcCallOpts<TProgress = unknown> {
|
|
4
|
+
/** Receive intermediate progress events for a streaming call. */
|
|
5
|
+
onProgress?: (progress: TProgress) => void;
|
|
6
|
+
/** Optional abort. The dispatcher fires `controller.abort` reasons through. */
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
/** Overrides the default 30s timeout. Set to `null` to disable. */
|
|
9
|
+
timeoutMs?: number | null;
|
|
10
|
+
}
|
|
11
|
+
export interface RpcSender {
|
|
12
|
+
/** Push the outbound RPC over the underlying transport. */
|
|
13
|
+
send(requestId: string, method: RpcMethod, args: unknown, streaming: boolean): void;
|
|
14
|
+
}
|
|
15
|
+
export declare class RpcDispatcher {
|
|
16
|
+
private readonly sender;
|
|
17
|
+
private readonly pending;
|
|
18
|
+
constructor(sender: RpcSender);
|
|
19
|
+
call<TResult = unknown, TProgress = unknown>(method: RpcMethod, args: unknown, opts?: RpcCallOpts<TProgress>): Promise<TResult>;
|
|
20
|
+
handleResponse(requestId: string, payload: HostRpcResponsePayload): void;
|
|
21
|
+
handleProgress(requestId: string, payload: HostRpcProgressPayload): void;
|
|
22
|
+
rejectAll(reason: unknown): void;
|
|
23
|
+
private settle;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/client/rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAE9F,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,WAAW,CAAC,SAAS,GAAG,OAAO;IAC9C,iEAAiE;IACjE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,IAAI,CAAC;IAC3C,+EAA+E;IAC/E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAWD,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;CACrF;AAUD,qBAAa,aAAa;IAGZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;gBAE5B,MAAM,EAAE,SAAS;IAE9C,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,SAAS,GAAG,OAAO,EACzC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,OAAO,EACb,IAAI,GAAE,WAAW,CAAC,SAAS,CAAM,GAChC,OAAO,CAAC,OAAO,CAAC;IAqCnB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAaxE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAKxE,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAMhC,OAAO,CAAC,MAAM;CAWf"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/shared/plugins/iframe-mount/client/rpc.ts
|
|
2
|
+
var e = 3e4, t = 0;
|
|
3
|
+
function n() {
|
|
4
|
+
return t = (t + 1) % (2 ** 53 - 1), `rpc-${Date.now().toString(36)}-${t.toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
5
|
+
}
|
|
6
|
+
var r = class {
|
|
7
|
+
pending = /* @__PURE__ */ new Map();
|
|
8
|
+
constructor(e) {
|
|
9
|
+
this.sender = e;
|
|
10
|
+
}
|
|
11
|
+
call(t, r, i = {}) {
|
|
12
|
+
let a = n(), o = !!i.onProgress;
|
|
13
|
+
return new Promise((n, s) => {
|
|
14
|
+
let c = i.timeoutMs === null ? null : i.timeoutMs ?? e, l = {
|
|
15
|
+
resolve: (e) => n(e),
|
|
16
|
+
reject: s,
|
|
17
|
+
onProgress: i.onProgress,
|
|
18
|
+
signal: i.signal
|
|
19
|
+
};
|
|
20
|
+
if (this.pending.set(a, l), c !== null && c > 0 && (l.timeoutHandle = setTimeout(() => {
|
|
21
|
+
this.settle(a, !1, /* @__PURE__ */ Error(`RPC timed out after ${c}ms`));
|
|
22
|
+
}, c)), i.signal) {
|
|
23
|
+
if (i.signal.aborted) {
|
|
24
|
+
this.settle(a, !1, /* @__PURE__ */ Error("RPC aborted"));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
l.abortHandler = () => {
|
|
28
|
+
this.settle(a, !1, /* @__PURE__ */ Error("RPC aborted"));
|
|
29
|
+
}, i.signal.addEventListener("abort", l.abortHandler, { once: !0 });
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
this.sender.send(a, t, r, o);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
this.settle(a, !1, e);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
handleResponse(e, t) {
|
|
39
|
+
if (t.ok) this.settle(e, !0, t.result);
|
|
40
|
+
else {
|
|
41
|
+
let n = t.error ?? {
|
|
42
|
+
code: "rpc_unknown_error",
|
|
43
|
+
message: "Unknown RPC error"
|
|
44
|
+
}, r = Object.assign(Error(n.message), {
|
|
45
|
+
code: n.code,
|
|
46
|
+
data: n.data
|
|
47
|
+
});
|
|
48
|
+
this.settle(e, !1, r);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
handleProgress(e, t) {
|
|
52
|
+
this.pending.get(e)?.onProgress?.(t.progress);
|
|
53
|
+
}
|
|
54
|
+
rejectAll(e) {
|
|
55
|
+
for (let [t] of this.pending) this.settle(t, !1, e);
|
|
56
|
+
}
|
|
57
|
+
settle(e, t, n) {
|
|
58
|
+
let r = this.pending.get(e);
|
|
59
|
+
r && (this.pending.delete(e), r.timeoutHandle !== void 0 && clearTimeout(r.timeoutHandle), r.signal && r.abortHandler && r.signal.removeEventListener("abort", r.abortHandler), t ? r.resolve(n) : r.reject(n));
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
//#endregion
|
|
63
|
+
export { r as RpcDispatcher };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export { deriveSandbox } from './sandbox';
|
|
3
|
+
export { usePluginContributions, type UsePluginContributionsOptions, } from './useFetchContributions';
|
|
4
|
+
export { PluginIframe, type PluginIframeProps, type PluginIframeRpcContext, type PluginIframeRpcHandler, } from './PluginIframe';
|
|
5
|
+
export { PluginMount, type PluginMountProps, type PluginMountChildProps } from './PluginMount';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin contribution shape — the manifest entry a plugin author writes to
|
|
3
|
+
* declare that they want to be mounted at a given extension point.
|
|
4
|
+
*
|
|
5
|
+
* Mount points are open-ended strings the host page declares
|
|
6
|
+
* (`vibe.detailTab`, `agent.detailTab`, `target.detailTab`,
|
|
7
|
+
* `dashboard.widget`, …). Adding a new mount point does NOT require an
|
|
8
|
+
* SDK release: the host page consumes the matching contributions and
|
|
9
|
+
* interprets `meta` however it needs.
|
|
10
|
+
*/
|
|
11
|
+
export type PluginRuntime = 'iframe' | 'in-process';
|
|
12
|
+
export interface PluginCapabilities {
|
|
13
|
+
/**
|
|
14
|
+
* REST path prefixes the plugin is allowed to hit via the iframe token.
|
|
15
|
+
* Globs (`*`) are honoured by `request-security` on the agent.
|
|
16
|
+
*
|
|
17
|
+
* Example: `["/api/profiles/*\/my-plugin/*"]`
|
|
18
|
+
*/
|
|
19
|
+
restPaths: string[];
|
|
20
|
+
/** WebSocket topics this plugin subscribes to via the host relay. */
|
|
21
|
+
wsTopics: string[];
|
|
22
|
+
/**
|
|
23
|
+
* Host RPC methods the plugin may call (e.g. `navigate`, `toast`,
|
|
24
|
+
* `storage.get`). The host enforces this allow-list before invocation;
|
|
25
|
+
* mismatches return a structured error rather than executing.
|
|
26
|
+
*/
|
|
27
|
+
rpcMethods: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface ContributionGate {
|
|
30
|
+
/** Vibe-level feature catalog id (`isFeatureEnabled(feature)`). */
|
|
31
|
+
feature?: string;
|
|
32
|
+
/** Platform-level GrowthBook flag (`isPlatformTabEnabled(flag)`). */
|
|
33
|
+
platformFlag?: string;
|
|
34
|
+
/** Hide the contribution when no agent is attached to the surface. */
|
|
35
|
+
requiresAgent?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface PluginContribution {
|
|
38
|
+
/** Open-ended mount point id. The host page knows how to read it. */
|
|
39
|
+
mountPoint: string;
|
|
40
|
+
/** Unique within (pluginKey, mountPoint). */
|
|
41
|
+
id: string;
|
|
42
|
+
title: string;
|
|
43
|
+
/** Lucide icon name. Host resolves to a component; SDK stays icon-set agnostic. */
|
|
44
|
+
icon?: string;
|
|
45
|
+
/** Lower = earlier in the strip / grid. */
|
|
46
|
+
order?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Which runtimes this contribution supports. The host picks the first
|
|
49
|
+
* entry that matches its preference and is available; warns and skips
|
|
50
|
+
* the contribution when nothing matches.
|
|
51
|
+
*/
|
|
52
|
+
runtimes: PluginRuntime[];
|
|
53
|
+
capabilities: PluginCapabilities;
|
|
54
|
+
gate?: ContributionGate;
|
|
55
|
+
/** Mount-point-specific extras (e.g. `defaultSize` for dashboard widgets). */
|
|
56
|
+
meta?: Record<string, unknown>;
|
|
57
|
+
}
|
|
58
|
+
export interface PluginManifest {
|
|
59
|
+
/** Globally unique. Convention: npm-package-style (`vibe-plugin-ui-git`). */
|
|
60
|
+
id: string;
|
|
61
|
+
/** Human-readable. */
|
|
62
|
+
name?: string;
|
|
63
|
+
/** CalVer version of the plugin package itself. */
|
|
64
|
+
version?: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
contributions: PluginContribution[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* `defineUiPlugin` is a typed identity helper — it lets the plugin author
|
|
70
|
+
* declare the manifest + render function once and have the resulting
|
|
71
|
+
* object accepted by both adapters without `as const` ceremony.
|
|
72
|
+
*
|
|
73
|
+
* The `render` thunk runs *inside* the chosen adapter, after the host
|
|
74
|
+
* handshake has populated `VibeHostContext`. The hooks in `./react` are
|
|
75
|
+
* what consumers actually use; this signature is intentionally untyped
|
|
76
|
+
* for React to keep the protocol module DOM-free.
|
|
77
|
+
*/
|
|
78
|
+
export interface UiPluginDefinition<TRender = unknown> {
|
|
79
|
+
manifest: PluginManifest;
|
|
80
|
+
render: () => TRender;
|
|
81
|
+
}
|
|
82
|
+
export declare function defineUiPlugin<TRender>(plugin: UiPluginDefinition<TRender>): UiPluginDefinition<TRender>;
|
|
83
|
+
//# sourceMappingURL=contribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contribution.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/protocol/contribution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;OAIG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,YAAY,EAAE,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,kBAAkB,EAAE,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB,CAAC,OAAO,GAAG,OAAO;IACnD,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,OAAO,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,OAAO,EACpC,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAClC,kBAAkB,CAAC,OAAO,CAAC,CAE7B"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versioned envelope shared by every postMessage between a UI plugin
|
|
3
|
+
* (iframe-mounted or in-process) and its host shell.
|
|
4
|
+
*
|
|
5
|
+
* Both sides import these types from this module — there is no other
|
|
6
|
+
* source of truth for the wire format. Bumping the envelope is a
|
|
7
|
+
* deliberate breaking-change event; the major version embedded in
|
|
8
|
+
* `ENVELOPE_VERSION` rides independently of the package's CalVer.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ENVELOPE_VERSION: 1;
|
|
11
|
+
export type EnvelopeVersion = typeof ENVELOPE_VERSION;
|
|
12
|
+
/** Operations the host sends to the plugin. */
|
|
13
|
+
export type HostOp = 'host:init' | 'host:theme-change' | 'host:locale-change' | 'host:feature-flag' | 'host:context-change' | 'host:event' | 'host:rpc-response' | 'host:rpc-progress' | 'host:dispose';
|
|
14
|
+
/** Operations the plugin sends to the host. */
|
|
15
|
+
export type PluginOp = 'plugin:ready' | 'plugin:rpc-request' | 'plugin:event-emit' | 'plugin:set-badge' | 'plugin:set-title' | 'plugin:resize-request' | 'plugin:error';
|
|
16
|
+
export interface HostEnvelope<P = unknown> {
|
|
17
|
+
v: EnvelopeVersion;
|
|
18
|
+
source: 'host';
|
|
19
|
+
kind: HostOp;
|
|
20
|
+
/** Set when this envelope answers (or progresses) a prior plugin RPC. */
|
|
21
|
+
requestId?: string;
|
|
22
|
+
payload: P;
|
|
23
|
+
}
|
|
24
|
+
export interface PluginEnvelope<P = unknown> {
|
|
25
|
+
v: EnvelopeVersion;
|
|
26
|
+
source: 'plugin';
|
|
27
|
+
kind: PluginOp;
|
|
28
|
+
/** Set on rpc-request / set on plugin:error when caused by a specific RPC. */
|
|
29
|
+
requestId?: string;
|
|
30
|
+
payload: P;
|
|
31
|
+
}
|
|
32
|
+
export type Envelope<P = unknown> = HostEnvelope<P> | PluginEnvelope<P>;
|
|
33
|
+
/**
|
|
34
|
+
* Type guard that an unknown postMessage payload looks like a valid v1
|
|
35
|
+
* envelope. Origin and `event.source` checks are *not* performed here —
|
|
36
|
+
* the caller must do those *before* trusting the payload, because a
|
|
37
|
+
* well-formed envelope from a hostile origin is still hostile.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isEnvelope(value: unknown): value is Envelope;
|
|
40
|
+
/** Convenience: narrow to a HostEnvelope (caller already trusts the origin). */
|
|
41
|
+
export declare function isHostEnvelope(value: unknown): value is HostEnvelope;
|
|
42
|
+
/** Convenience: narrow to a PluginEnvelope (caller already trusts the origin). */
|
|
43
|
+
export declare function isPluginEnvelope(value: unknown): value is PluginEnvelope;
|
|
44
|
+
/** Sent in reply to `plugin:ready`. The plugin blocks render until it arrives. */
|
|
45
|
+
export interface HostInitPayload {
|
|
46
|
+
/** Scoped iframe token. Bounded by manifest capabilities. */
|
|
47
|
+
iframeToken: string;
|
|
48
|
+
tunnelUrl: string;
|
|
49
|
+
mountPoint: string;
|
|
50
|
+
context: Record<string, unknown>;
|
|
51
|
+
agentId: string;
|
|
52
|
+
profile: string;
|
|
53
|
+
theme: {
|
|
54
|
+
colorMode: 'light' | 'dark';
|
|
55
|
+
tokens: Record<string, string>;
|
|
56
|
+
};
|
|
57
|
+
locale: string;
|
|
58
|
+
capabilities: {
|
|
59
|
+
restPaths: string[];
|
|
60
|
+
wsTopics: string[];
|
|
61
|
+
rpcMethods: string[];
|
|
62
|
+
};
|
|
63
|
+
featureFlags: Record<string, boolean>;
|
|
64
|
+
sdkVersion: string;
|
|
65
|
+
hostVersion: string;
|
|
66
|
+
}
|
|
67
|
+
export interface HostThemeChangePayload {
|
|
68
|
+
colorMode: 'light' | 'dark';
|
|
69
|
+
tokens: Record<string, string>;
|
|
70
|
+
}
|
|
71
|
+
export interface HostLocaleChangePayload {
|
|
72
|
+
locale: string;
|
|
73
|
+
}
|
|
74
|
+
export interface HostFeatureFlagPayload {
|
|
75
|
+
flag: string;
|
|
76
|
+
value: boolean;
|
|
77
|
+
}
|
|
78
|
+
export interface HostContextChangePayload {
|
|
79
|
+
context: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
export interface HostEventPayload<T = unknown> {
|
|
82
|
+
name: string;
|
|
83
|
+
data: T;
|
|
84
|
+
}
|
|
85
|
+
export interface HostRpcResponsePayload<T = unknown> {
|
|
86
|
+
ok: boolean;
|
|
87
|
+
result?: T;
|
|
88
|
+
error?: {
|
|
89
|
+
code: string;
|
|
90
|
+
message: string;
|
|
91
|
+
data?: unknown;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export interface HostRpcProgressPayload<T = unknown> {
|
|
95
|
+
progress: T;
|
|
96
|
+
}
|
|
97
|
+
export type HostDisposePayload = Record<string, never>;
|
|
98
|
+
export interface PluginReadyPayload {
|
|
99
|
+
pluginId: string;
|
|
100
|
+
pluginVersion: string;
|
|
101
|
+
sdkVersion: string;
|
|
102
|
+
declaredCapabilities: {
|
|
103
|
+
restPaths: string[];
|
|
104
|
+
wsTopics: string[];
|
|
105
|
+
rpcMethods: string[];
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export interface PluginRpcRequestPayload {
|
|
109
|
+
method: string;
|
|
110
|
+
args: unknown;
|
|
111
|
+
/** Caller hint that the RPC may stream progress before terminal response. */
|
|
112
|
+
streaming?: boolean;
|
|
113
|
+
}
|
|
114
|
+
export interface PluginEventEmitPayload<T = unknown> {
|
|
115
|
+
name: string;
|
|
116
|
+
data: T;
|
|
117
|
+
}
|
|
118
|
+
export interface PluginSetBadgePayload {
|
|
119
|
+
value: string | number | null;
|
|
120
|
+
}
|
|
121
|
+
export interface PluginSetTitlePayload {
|
|
122
|
+
value: string;
|
|
123
|
+
}
|
|
124
|
+
export interface PluginResizeRequestPayload {
|
|
125
|
+
/** Suggested iframe height in pixels. Host may ignore. */
|
|
126
|
+
height?: number;
|
|
127
|
+
width?: number;
|
|
128
|
+
}
|
|
129
|
+
export interface PluginErrorPayload {
|
|
130
|
+
code: string;
|
|
131
|
+
message: string;
|
|
132
|
+
stack?: string;
|
|
133
|
+
/** Optional reference to a specific in-flight requestId. */
|
|
134
|
+
requestId?: string;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/protocol/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function e(e) {
|
|
2
|
+
if (typeof e != "object" || !e) return !1;
|
|
3
|
+
let t = e;
|
|
4
|
+
return t.v !== 1 || t.source !== "host" && t.source !== "plugin" || typeof t.kind != "string" || "requestId" in t && typeof t.requestId != "string" && t.requestId !== void 0 ? !1 : "payload" in t;
|
|
5
|
+
}
|
|
6
|
+
function t(t) {
|
|
7
|
+
return e(t) && t.source === "plugin";
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { e as isEnvelope, t as isPluginEnvelope };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/shared/plugins/iframe-mount/protocol/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAuC9D,wBAAgB,aAAa,CAAC,YAAY,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAmBzF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/shared/plugins/iframe-mount/sandbox.ts
|
|
2
|
+
var e = ["allow-scripts", "allow-same-origin"], t = {
|
|
3
|
+
"clipboard.write": ["allow-clipboard-write"],
|
|
4
|
+
"clipboard.read": ["allow-clipboard-read"],
|
|
5
|
+
openExternal: ["allow-popups", "allow-popups-to-escape-sandbox"],
|
|
6
|
+
downloads: ["allow-downloads"],
|
|
7
|
+
pointerLock: ["allow-pointer-lock"],
|
|
8
|
+
fullscreen: ["allow-presentation"]
|
|
9
|
+
};
|
|
10
|
+
function n(n) {
|
|
11
|
+
let r = new Set(e), i = n?.rpcMethods ?? [];
|
|
12
|
+
for (let e of i) {
|
|
13
|
+
let n = t[e];
|
|
14
|
+
if (n) for (let e of n) r.add(e);
|
|
15
|
+
}
|
|
16
|
+
return Array.from(r).join(" ");
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { n as deriveSandbox };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { PluginCapabilities, PluginContribution, PluginRuntime } from './protocol/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* A "tunnel" the host page can query for contributions and from which
|
|
4
|
+
* iframe-mounted plugins are served. For VibeControls this is the
|
|
5
|
+
* vibecontrols-agent's Cloudflare tunnel + the current profile name;
|
|
6
|
+
* other products map to whatever serves their plugins.
|
|
7
|
+
*/
|
|
8
|
+
export interface MountTunnel {
|
|
9
|
+
/** Base URL — used for both fetch + iframe src. */
|
|
10
|
+
tunnelUrl: string;
|
|
11
|
+
/** Profile or scope segment the agent uses to namespace plugins. */
|
|
12
|
+
profile: string;
|
|
13
|
+
/** Optional human-readable label for picker UIs / errors. */
|
|
14
|
+
label?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Factory that mints a fresh iframe token scoped to a contribution's
|
|
17
|
+
* capability `restPaths`. Called once on first mount + on each
|
|
18
|
+
* scheduled refresh. The host supplies this so the SDK stays
|
|
19
|
+
* transport-agnostic.
|
|
20
|
+
*/
|
|
21
|
+
mintIframeToken: (input: {
|
|
22
|
+
pathPrefixes: string[];
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
token: string;
|
|
25
|
+
expiresAt: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* What `usePluginContributions` returns per-contribution after
|
|
30
|
+
* fetching from one or more tunnels. The `tunnel` is the source the
|
|
31
|
+
* contribution came from; multiple tunnels' results are unioned (last
|
|
32
|
+
* wins on id collisions).
|
|
33
|
+
*/
|
|
34
|
+
export interface DiscoveredContribution {
|
|
35
|
+
pluginKey: string;
|
|
36
|
+
pluginPackageName?: string;
|
|
37
|
+
contribution: PluginContribution;
|
|
38
|
+
capabilities: PluginCapabilities;
|
|
39
|
+
/**
|
|
40
|
+
* Relative URL — the host concatenates with `tunnel.tunnelUrl` to
|
|
41
|
+
* mount the iframe. Returned by the agent as e.g. `/ui/<pluginKey>`.
|
|
42
|
+
*/
|
|
43
|
+
url: string;
|
|
44
|
+
tunnel: MountTunnel;
|
|
45
|
+
}
|
|
46
|
+
export type RuntimePreference = PluginRuntime | 'auto';
|
|
47
|
+
export interface InProcessPluginEntry {
|
|
48
|
+
/**
|
|
49
|
+
* Plugin package key (matches `DiscoveredContribution.pluginKey`).
|
|
50
|
+
* Required to disambiguate when two different plugins contribute
|
|
51
|
+
* the same local `id` at the same `mountPoint` — without this, the
|
|
52
|
+
* later registration silently overwrites the earlier one.
|
|
53
|
+
*/
|
|
54
|
+
pluginKey: string;
|
|
55
|
+
/** Matches `contribution.id`. */
|
|
56
|
+
id: string;
|
|
57
|
+
/** Matches `contribution.mountPoint`. */
|
|
58
|
+
mountPoint: string;
|
|
59
|
+
/** React component to render. Receives the same context object the iframe would. */
|
|
60
|
+
Component: React.ComponentType<{
|
|
61
|
+
context: Record<string, unknown>;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEjG;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,eAAe,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC;QAC9D,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,kBAAkB,CAAC;IACjC,YAAY,EAAE,kBAAkB,CAAC;IACjC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CACtE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DiscoveredContribution, MountTunnel } from './types';
|
|
2
|
+
export interface UsePluginContributionsOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Filter to a single mount point. When omitted, the hook returns the
|
|
5
|
+
* union of every contribution across every mount point so the host
|
|
6
|
+
* can seed multiple tab strips from one request.
|
|
7
|
+
*/
|
|
8
|
+
mountPoint?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Polling cadence. Defaults to 60s. Set to `false` to disable; the
|
|
11
|
+
* hook will only refetch on tunnel reconnect / focus.
|
|
12
|
+
*/
|
|
13
|
+
refetchIntervalMs?: number | false;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fetch plugin contributions from every supplied tunnel. Results are
|
|
18
|
+
* unioned; if two tunnels report contributions with the same `id`, the
|
|
19
|
+
* one whose tunnel.label is lexicographically smaller wins (stable,
|
|
20
|
+
* deterministic, debuggable). Authors should pick unique ids anyway.
|
|
21
|
+
*/
|
|
22
|
+
export declare function usePluginContributions(tunnels: MountTunnel[], opts?: UsePluginContributionsOptions): {
|
|
23
|
+
data: DiscoveredContribution[];
|
|
24
|
+
isFetching: boolean;
|
|
25
|
+
errors: Array<{
|
|
26
|
+
tunnel: MountTunnel;
|
|
27
|
+
error: unknown;
|
|
28
|
+
}>;
|
|
29
|
+
refetch: () => void;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=useFetchContributions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFetchContributions.d.ts","sourceRoot":"","sources":["../../../../src/shared/plugins/iframe-mount/useFetchContributions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAwCnE,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,WAAW,EAAE,EACtB,IAAI,GAAE,6BAAkC,GACvC;IACD,IAAI,EAAE,sBAAsB,EAAE,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACvD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAsEA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useMemo as e } from "react";
|
|
2
|
+
import { useQueries as t } from "@tanstack/react-query";
|
|
3
|
+
//#region src/shared/plugins/iframe-mount/useFetchContributions.ts
|
|
4
|
+
var n = 6e4;
|
|
5
|
+
async function r(e, t, n) {
|
|
6
|
+
let r = `${e.tunnelUrl.replace(/\/$/, "")}/api/profiles/${encodeURIComponent(e.profile)}/plugins/contributions${t ? `?mountPoint=${encodeURIComponent(t)}` : ""}`, i = await fetch(r, {
|
|
7
|
+
signal: n,
|
|
8
|
+
headers: { Accept: "application/json" }
|
|
9
|
+
});
|
|
10
|
+
if (!i.ok) throw Error(`Contributions fetch failed: ${i.status} ${i.statusText}`);
|
|
11
|
+
return ((await i.json()).contributions ?? []).map((t) => ({
|
|
12
|
+
pluginKey: t.pluginKey,
|
|
13
|
+
pluginPackageName: t.pluginPackageName,
|
|
14
|
+
contribution: t.contribution,
|
|
15
|
+
capabilities: t.capabilities,
|
|
16
|
+
url: t.url,
|
|
17
|
+
tunnel: e
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function i(i, a = {}) {
|
|
21
|
+
let { mountPoint: o, refetchIntervalMs: s = n, enabled: c = !0 } = a, l = t({ queries: i.map((e) => ({
|
|
22
|
+
queryKey: [
|
|
23
|
+
"vibe-plugin-contributions",
|
|
24
|
+
e.tunnelUrl,
|
|
25
|
+
e.profile,
|
|
26
|
+
o
|
|
27
|
+
],
|
|
28
|
+
queryFn: ({ signal: t }) => r(e, o, t),
|
|
29
|
+
refetchInterval: s === !1 ? !1 : s,
|
|
30
|
+
staleTime: 3e4,
|
|
31
|
+
enabled: c
|
|
32
|
+
})) }), u = l.map((e) => `${e.dataUpdatedAt}:${e.data?.length ?? 0}`).join("|"), d = l.map((e) => e.error ? `${e.errorUpdatedAt}` : "").join("|"), f = e(() => {
|
|
33
|
+
let e = (e) => `${e.pluginKey}::${e.contribution.mountPoint}::${e.contribution.id}`, t = /* @__PURE__ */ new Map();
|
|
34
|
+
for (let n = 0; n < l.length; n += 1) {
|
|
35
|
+
let r = l[n].data ?? [];
|
|
36
|
+
for (let n of r) {
|
|
37
|
+
let r = e(n), i = t.get(r);
|
|
38
|
+
if (!i) {
|
|
39
|
+
t.set(r, n);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
let a = i.tunnel.label ?? i.tunnel.tunnelUrl;
|
|
43
|
+
(n.tunnel.label ?? n.tunnel.tunnelUrl) < a && t.set(r, n);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return Array.from(t.values());
|
|
47
|
+
}, [u]), p = e(() => {
|
|
48
|
+
let e = [];
|
|
49
|
+
for (let t = 0; t < l.length; t += 1) {
|
|
50
|
+
let n = l[t]?.error;
|
|
51
|
+
n && e.push({
|
|
52
|
+
tunnel: i[t],
|
|
53
|
+
error: n
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return e;
|
|
57
|
+
}, [d, i]);
|
|
58
|
+
return {
|
|
59
|
+
data: f,
|
|
60
|
+
isFetching: l.some((e) => e.isFetching),
|
|
61
|
+
errors: p,
|
|
62
|
+
refetch: () => {
|
|
63
|
+
for (let e of l) e.refetch();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { i as usePluginContributions };
|
|
@@ -37,4 +37,5 @@ export { useSettingsRegistryStore } from './registries/useSettingsRegistry';
|
|
|
37
37
|
export { useWidgetRegistryStore } from './registries/useWidgetRegistry';
|
|
38
38
|
export { useToolbarRegistryStore } from './registries/useToolbarRegistry';
|
|
39
39
|
export { useContextMenuRegistryStore } from './registries/useContextMenuRegistry';
|
|
40
|
+
export * from './iframe-mount';
|
|
40
41
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,GACV,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,yBAAyB,GAC/B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,GACV,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EACL,QAAQ,EACR,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGpE,OAAO,EACL,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,0BAA0B,EAC1B,KAAK,YAAY,EACjB,KAAK,yBAAyB,GAC/B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAKlF,cAAc,gBAAgB,CAAC"}
|
package/dist/shared-plugins.js
CHANGED
|
@@ -12,4 +12,9 @@ import { useWidgetRegistryStore as d } from "./shared/plugins/registries/useWidg
|
|
|
12
12
|
import { useToolbarRegistryStore as f } from "./shared/plugins/registries/useToolbarRegistry.js";
|
|
13
13
|
import { useContextMenuRegistryStore as p } from "./shared/plugins/registries/useContextMenuRegistry.js";
|
|
14
14
|
import { PluginRuntimeProvider as m, usePluginRuntime as h } from "./shared/plugins/PluginRuntimeProvider.js";
|
|
15
|
-
|
|
15
|
+
import { deriveSandbox as g } from "./shared/plugins/iframe-mount/sandbox.js";
|
|
16
|
+
import { usePluginContributions as _ } from "./shared/plugins/iframe-mount/useFetchContributions.js";
|
|
17
|
+
import { PluginIframe as v } from "./shared/plugins/iframe-mount/PluginIframe.js";
|
|
18
|
+
import { PluginMount as y } from "./shared/plugins/iframe-mount/PluginMount.js";
|
|
19
|
+
import "./shared/plugins/iframe-mount/index.js";
|
|
20
|
+
export { e as DisposableCollection, t as EventBus, v as PluginIframe, y as PluginMount, i as PluginRuntime, m as PluginRuntimeProvider, a as createContributionRegistry, r as createPluginContext, g as deriveSandbox, o as useCommandRegistryStore, p as useContextMenuRegistryStore, c as usePanelRegistryStore, _ as usePluginContributions, n as usePluginEvent, h as usePluginRuntime, s as useRouteRegistryStore, u as useSettingsRegistryStore, l as useStatusBarRegistryStore, f as useToolbarRegistryStore, d as useWidgetRegistryStore };
|