@ggui-ai/iframe-runtime 0.1.0-rc.3 → 0.2.0-alpha.1
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/README.md +7 -6
- package/dist/channel-transport.d.ts +15 -15
- package/dist/channel-transport.js +32 -35
- package/dist/channels/channel-payload.d.ts +2 -2
- package/dist/channels/channel-payload.js +1 -1
- package/dist/channels/data.d.ts +14 -19
- package/dist/channels/data.js +13 -31
- package/dist/channels/drain-ack.d.ts +2 -2
- package/dist/channels/drain-ack.js +1 -1
- package/dist/channels/feedback.d.ts +1 -1
- package/dist/channels/index.d.ts +1 -1
- package/dist/channels/index.js +1 -1
- package/dist/channels/props-update.d.ts +33 -37
- package/dist/channels/props-update.js +30 -106
- package/dist/channels/render-frame.d.ts +52 -0
- package/dist/channels/render-frame.js +53 -0
- package/dist/channels/system.d.ts +1 -1
- package/dist/compiled-validators.d.ts +15 -0
- package/dist/compiled-validators.js +31 -0
- package/dist/context-observer.d.ts +68 -8
- package/dist/context-observer.js +25 -45
- package/dist/events-polling.d.ts +95 -0
- package/dist/events-polling.js +143 -0
- package/dist/gadget-loader.d.ts +1 -1
- package/dist/globals.d.ts +4 -4
- package/dist/host-context-emitter.d.ts +84 -20
- package/dist/host-context-emitter.js +159 -29
- package/dist/iframe-runtime.js +98 -59
- package/dist/index.d.ts +18 -13
- package/dist/index.js +1 -1
- package/dist/lifecycle.d.ts +2 -2
- package/dist/lifecycle.js +5 -5
- package/dist/mcp-app-iframe-host.d.ts +9 -9
- package/dist/mcp-app-iframe-host.js +16 -17
- package/dist/meta-parse.d.ts +44 -0
- package/dist/meta-parse.js +390 -0
- package/dist/observability.d.ts +6 -6
- package/dist/protocol-error.d.ts +7 -7
- package/dist/provisional-renderer.d.ts +1 -1
- package/dist/provisional-renderer.js +1 -1
- package/dist/react-renderer.d.ts +10 -11
- package/dist/react-renderer.js +8 -8
- package/dist/registry-subscribe.d.ts +27 -9
- package/dist/registry-subscribe.js +32 -27
- package/dist/render-item.d.ts +83 -0
- package/dist/{stack-item-renderer.js → render-item.js} +106 -106
- package/dist/runtime.d.ts +183 -131
- package/dist/runtime.js +1264 -1330
- package/dist/status-dom.d.ts +52 -47
- package/dist/status-dom.js +51 -34
- package/dist/system-cards/NoCredentialsCard.d.ts +1 -1
- package/dist/system-cards/NoCredentialsCard.js +1 -1
- package/dist/system-cards/ProtocolProbeCard.js +2 -2
- package/dist/system-cards/index.d.ts +4 -4
- package/dist/system-cards/index.js +4 -4
- package/dist/types.d.ts +70 -34
- package/dist/types.js +1 -1
- package/dist/validation.d.ts +2 -2
- package/dist/validation.js +2 -2
- package/dist/wire-config.d.ts +54 -82
- package/dist/wire-config.js +61 -93
- package/package.json +9 -8
- package/dist/bootstrap.d.ts +0 -72
- package/dist/bootstrap.js +0 -500
- package/dist/canvas/animator/animator-host.d.ts +0 -63
- package/dist/canvas/animator/animator-host.js +0 -105
- package/dist/canvas/animator/animator-pill.d.ts +0 -42
- package/dist/canvas/animator/animator-pill.js +0 -119
- package/dist/canvas/animator/state-machine.d.ts +0 -106
- package/dist/canvas/animator/state-machine.js +0 -150
- package/dist/canvas/canvas-shell.d.ts +0 -77
- package/dist/canvas/canvas-shell.js +0 -117
- package/dist/canvas/display-mode-policy.d.ts +0 -104
- package/dist/canvas/display-mode-policy.js +0 -98
- package/dist/canvas/mount.d.ts +0 -150
- package/dist/canvas/mount.js +0 -202
- package/dist/canvas/nav-stack.d.ts +0 -133
- package/dist/canvas/nav-stack.js +0 -172
- package/dist/channels/push.d.ts +0 -47
- package/dist/channels/push.js +0 -54
- package/dist/stack-item-renderer.d.ts +0 -103
- package/dist/stack.d.ts +0 -90
- package/dist/stack.js +0 -118
package/dist/runtime.d.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import type { DrainAckPayload } from '@ggui-ai/protocol';
|
|
1
|
+
import type { DrainAckPayload, Render } from '@ggui-ai/protocol';
|
|
2
2
|
import type { WebSocketMessage } from '@ggui-ai/protocol/transport/websocket';
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import type { ValidatedMcpAppAiGguiMeta, RenderSeedInput } from './types.js';
|
|
4
|
+
import type { McpAppAiGguiMetaParseFailureReason } from './types.js';
|
|
5
|
+
import { App } from '@modelcontextprotocol/ext-apps';
|
|
6
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
7
|
+
import type { GadgetPackageRegistry } from './globals.js';
|
|
6
8
|
import { StreamBus } from './wire-config.js';
|
|
7
9
|
import { type ChannelTransportRouter } from './channel-transport.js';
|
|
8
|
-
import { ChannelRegistry } from '@ggui-ai/channel
|
|
10
|
+
import { ChannelRegistry } from '@ggui-ai/live-channel';
|
|
9
11
|
import { type ConnectFn } from './registry-subscribe.js';
|
|
10
12
|
import { type StatusRefs } from './status-dom.js';
|
|
11
13
|
import { type RendererValidatorContext } from './validation.js';
|
|
12
|
-
import { StackRenderer } from './stack-item-renderer.js';
|
|
13
14
|
import type { WireConfig } from '@ggui-ai/wire';
|
|
14
15
|
import { type ProtocolErrorEmitter } from './protocol-error.js';
|
|
15
16
|
import { type ObservabilityEmitter } from './observability.js';
|
|
16
17
|
import { type LifecycleEmitter } from './lifecycle.js';
|
|
17
18
|
/**
|
|
18
19
|
* Drain-ack listener registry. Module-scoped so the dispatch path can
|
|
19
|
-
* register a frame-listener without threading it through the
|
|
20
|
+
* register a frame-listener without threading it through the renderer.
|
|
20
21
|
* Listeners are called in registration order on every inbound
|
|
21
22
|
* `{type:'drain_ack'}` WS frame; a listener returning `true` claims
|
|
22
23
|
* the frame (no further listeners fire). The active listener dismisses
|
|
@@ -27,24 +28,38 @@ import { type LifecycleEmitter } from './lifecycle.js';
|
|
|
27
28
|
*/
|
|
28
29
|
type DrainAckListener = (payload: DrainAckPayload) => boolean | void;
|
|
29
30
|
export declare function subscribeDrainAck(listener: DrainAckListener): () => void;
|
|
30
|
-
|
|
31
|
-
readonly
|
|
32
|
-
|
|
33
|
-
readonly
|
|
34
|
-
readonly
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
export type ConnectAppResult = {
|
|
32
|
+
readonly ok: true;
|
|
33
|
+
} | {
|
|
34
|
+
readonly ok: false;
|
|
35
|
+
readonly message: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Assign the module-level App handle. Replaces any previous handle —
|
|
39
|
+
* production runs bootSequence exactly once per iframe lifecycle, so
|
|
40
|
+
* a replace only happens in tests that reuse the module across
|
|
41
|
+
* scenarios (and want each spec to bind its own App).
|
|
42
|
+
*
|
|
43
|
+
* @internal — production callers are the boot paths
|
|
44
|
+
* (`bootProduction`, `bootSelfContained`); tests inject directly to
|
|
45
|
+
* drive outbound `tools/call` through a `MockTransport`-bound App
|
|
46
|
+
* without invoking the full boot pipeline.
|
|
47
|
+
*/
|
|
48
|
+
export declare function setCurrentApp(app: App): void;
|
|
49
|
+
/**
|
|
50
|
+
* @internal — exported for unit tests to reset module state between
|
|
51
|
+
* scenarios.
|
|
52
|
+
*/
|
|
53
|
+
export declare function __resetAppForTest(): void;
|
|
39
54
|
/**
|
|
40
55
|
* Closed union of failure reasons surfaceable from the boot path.
|
|
41
|
-
* Maps the parse reasons (`
|
|
42
|
-
* boot-orchestration reasons that don't have a canonical wire
|
|
43
|
-
* The broader `BootstrapFailureReason` extensibly-closed union
|
|
44
|
-
* `protocol-error.ts` folds these together with transport-observable
|
|
56
|
+
* Maps the parse reasons (`McpAppAiGguiMetaParseFailureReason`) plus
|
|
57
|
+
* three boot-orchestration reasons that don't have a canonical wire
|
|
58
|
+
* code. The broader `BootstrapFailureReason` extensibly-closed union
|
|
59
|
+
* in `protocol-error.ts` folds these together with transport-observable
|
|
45
60
|
* codes.
|
|
46
61
|
*/
|
|
47
|
-
export type RendererBootFailureReason =
|
|
62
|
+
export type RendererBootFailureReason = McpAppAiGguiMetaParseFailureReason | 'UI_INITIALIZE_FAILED' | 'WS_HANDSHAKE_FAILED' | 'UPGRADE_REQUIRED';
|
|
48
63
|
export interface RendererBootFailedMessage {
|
|
49
64
|
readonly type: 'ggui:bootstrap-failed';
|
|
50
65
|
readonly reason: RendererBootFailureReason;
|
|
@@ -53,17 +68,27 @@ export interface RendererBootFailedMessage {
|
|
|
53
68
|
export interface BootSequenceOptions {
|
|
54
69
|
readonly doc: Document;
|
|
55
70
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* `
|
|
71
|
+
* Spec-canonical {@link App} instance + its {@link Transport}.
|
|
72
|
+
* `bootSequence` calls `app.connect(transport)` synchronously after
|
|
73
|
+
* the toolresult listener is installed (one-shot semantics: see
|
|
74
|
+
* App's `_assertHandlerTiming` warning — handlers registered AFTER
|
|
75
|
+
* connect risk missing the host's notification).
|
|
76
|
+
*
|
|
77
|
+
* Production passes the default (constructed against `window.parent`);
|
|
78
|
+
* tests inject `MockTransport` + a fresh App so the orchestration
|
|
79
|
+
* can be driven deterministically without `window.postMessage`.
|
|
80
|
+
*
|
|
81
|
+
* `App.connect` throws on initialize failure — bootSequence catches
|
|
82
|
+
* + surfaces the rejection's `message` on the `UI_INITIALIZE_FAILED`
|
|
83
|
+
* bootstrap envelope.
|
|
60
84
|
*/
|
|
61
|
-
readonly
|
|
85
|
+
readonly app: App;
|
|
86
|
+
readonly transport: Transport;
|
|
62
87
|
/**
|
|
63
88
|
* Stand-in for the package's own `connectViaRegistry()`. Tests inject
|
|
64
89
|
* a mock so the boot smoke spec doesn't need a mock-WebSocket layer
|
|
65
90
|
* — the WS lifecycle is already covered by `registry-subscribe.test.ts`
|
|
66
|
-
* and `@ggui-ai/channel
|
|
91
|
+
* and `@ggui-ai/live-channel`'s transport tests.
|
|
67
92
|
*
|
|
68
93
|
* Default: `connectViaRegistry` from `./registry-subscribe.js`.
|
|
69
94
|
*/
|
|
@@ -126,10 +151,10 @@ export interface BootSequenceOptions {
|
|
|
126
151
|
*/
|
|
127
152
|
readonly onLifecycle?: LifecycleEmitter;
|
|
128
153
|
/**
|
|
129
|
-
* Optional
|
|
130
|
-
* (1) calls `
|
|
131
|
-
* (2)
|
|
132
|
-
*
|
|
154
|
+
* Optional renderer hook. When present, the boot sequence:
|
|
155
|
+
* (1) calls `renderer.setup()` after bootstrap parse;
|
|
156
|
+
* (2) mounts the single stack entry into the renderer's slot on
|
|
157
|
+
* first ack + re-applies on every subsequent push; (3) routes
|
|
133
158
|
* inbound `data` / `props_update` / `feedback` frames through the
|
|
134
159
|
* supplied wire config + StreamBus.
|
|
135
160
|
*
|
|
@@ -138,46 +163,46 @@ export interface BootSequenceOptions {
|
|
|
138
163
|
* without pulling React + design + wire into the spec's import
|
|
139
164
|
* graph.
|
|
140
165
|
*/
|
|
141
|
-
readonly
|
|
166
|
+
readonly renderer?: RendererHooks;
|
|
142
167
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* raw status DOM. Subsequent ack/push frames sync into the returned
|
|
150
|
-
* {@link CanvasMountHandle.navStack}.
|
|
168
|
+
* Slice meta resolved BEFORE bootSequence — the autostart layer
|
|
169
|
+
* (in `runtime.ts`'s autostart resolver) catches an inline
|
|
170
|
+
* `__GGUI_META__` global or a buffered `ui/notifications/tool-result`
|
|
171
|
+
* postMessage early, parses it, and threads the result here so
|
|
172
|
+
* bootSequence doesn't re-await the same postMessage (the autostart
|
|
173
|
+
* has already drained it).
|
|
151
174
|
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
175
|
+
* When present, both internal resolver tiers (inline global, spec-
|
|
176
|
+
* canonical async toolresult) are skipped. The App handshake still
|
|
177
|
+
* runs — spec mandates `ui/initialize` regardless of how slice meta
|
|
178
|
+
* arrives, and `hostContext` is captured from `app.getHostContext()`.
|
|
179
|
+
*/
|
|
180
|
+
readonly preResolvedMeta?: ValidatedMcpAppAiGguiMeta;
|
|
181
|
+
/**
|
|
182
|
+
* How long to wait for the spec-canonical `ui/notifications/tool-result`
|
|
183
|
+
* notification (Tier 2 of the resolver chain) before failing with
|
|
184
|
+
* the synchronous tier's parse reason. Defaults to
|
|
185
|
+
* {@link POSTMESSAGE_BOOT_TIMEOUT_MS}; tests override to a short
|
|
186
|
+
* timeout so the spec doesn't hang.
|
|
154
187
|
*/
|
|
155
|
-
readonly
|
|
188
|
+
readonly toolResultTimeoutMs?: number;
|
|
156
189
|
}
|
|
157
190
|
/**
|
|
158
|
-
*
|
|
159
|
-
* through `bootProduction` (where React + canvas modules are already
|
|
160
|
-
* dynamic-imported); tests pass a stub that fakes the React tree.
|
|
161
|
-
*/
|
|
162
|
-
export type CanvasMountHook = (params: {
|
|
163
|
-
readonly mountTarget: HTMLElement;
|
|
164
|
-
readonly callbacks: import('./canvas/mount.js').CanvasMountCallbacks;
|
|
165
|
-
}) => import('./canvas/mount.js').CanvasMountHandle;
|
|
166
|
-
/**
|
|
167
|
-
* Renderer-triad wiring hooks. The real iframe boot plumbs these via
|
|
191
|
+
* Renderer hooks. The real iframe boot plumbs these via
|
|
168
192
|
* `autoBootSequence` below; tests may pass their own fakes when
|
|
169
193
|
* exercising the full flow.
|
|
170
194
|
*/
|
|
171
|
-
export interface
|
|
195
|
+
export interface RendererHooks {
|
|
172
196
|
/**
|
|
173
197
|
* Called after bootstrap parse succeeds. Return value threads the
|
|
174
|
-
* root `WireConfig` +
|
|
175
|
-
*
|
|
198
|
+
* root `WireConfig` + the single-render mount surface back into the
|
|
199
|
+
* runtime so the channel handlers can route frames through them.
|
|
176
200
|
*
|
|
177
|
-
* `renderInto` — a DOM element the
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* containers
|
|
201
|
+
* `renderInto` — a DOM element the renderer owns. Post-stack-removal
|
|
202
|
+
* (2026-05-27) the iframe-runtime mounts exactly one React tree
|
|
203
|
+
* directly into `renderInto`; the earlier per-render
|
|
204
|
+
* `<div data-ggui-stack-item-root>` containers were retired along
|
|
205
|
+
* with `StackRenderer`.
|
|
181
206
|
*
|
|
182
207
|
* `onObserve` — optional observability emitter threaded down to
|
|
183
208
|
* the root wire config so `wired-tool-invoked` events fire on
|
|
@@ -187,37 +212,43 @@ export interface TriadWiringHooks {
|
|
|
187
212
|
* own emitters).
|
|
188
213
|
*/
|
|
189
214
|
setup(params: {
|
|
190
|
-
readonly
|
|
191
|
-
readonly stackModel: StackModel;
|
|
215
|
+
readonly meta: ValidatedMcpAppAiGguiMeta;
|
|
192
216
|
readonly renderInto: HTMLElement;
|
|
193
217
|
readonly statusRefs: StatusRefs;
|
|
194
218
|
readonly onObserve?: ObservabilityEmitter;
|
|
195
|
-
|
|
196
|
-
* Canvas-mode lifecycle sink. When wired,
|
|
197
|
-
* the triad's `data` channel handler forwards every envelope on
|
|
198
|
-
* the reserved `_ggui:lifecycle` channel to this callback so the
|
|
199
|
-
* canvas animator state machine advances. Absent ⇒ envelopes
|
|
200
|
-
* still emit on `streamBus` for declarative consumers but no
|
|
201
|
-
* animator-side dispatch fires (non-canvas iframes).
|
|
202
|
-
*/
|
|
203
|
-
readonly onCanvasLifecycle?: (payload: import('@ggui-ai/protocol').CanvasLifecyclePayload) => void;
|
|
204
|
-
}): TriadHandle;
|
|
219
|
+
}): RendererHandle;
|
|
205
220
|
/**
|
|
206
|
-
* Bind the real WS manager into the
|
|
221
|
+
* Bind the real WS manager into the renderer AFTER `connectFn` resolves.
|
|
207
222
|
* The `setup()` step supplies a buffering shim — this hook flushes
|
|
208
|
-
* the buffer + swaps in the real send surface. Optional: a
|
|
223
|
+
* the buffer + swaps in the real send surface. Optional: a renderer
|
|
209
224
|
* that doesn't emit outbound frames can skip.
|
|
210
225
|
*/
|
|
211
|
-
attachManager?(handle:
|
|
226
|
+
attachManager?(handle: RendererHandle, realManager: {
|
|
212
227
|
send: (msg: WebSocketMessage) => void;
|
|
213
228
|
}): void;
|
|
214
229
|
/** Optional cleanup — called on boot failure paths. */
|
|
215
|
-
teardown?(handle:
|
|
230
|
+
teardown?(handle: RendererHandle): void;
|
|
216
231
|
}
|
|
217
|
-
export interface
|
|
232
|
+
export interface RendererHandle {
|
|
218
233
|
readonly rootWireConfig: WireConfig;
|
|
219
234
|
readonly streamBus: StreamBus;
|
|
220
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Apply (mount-or-update) a render to the single mount slot.
|
|
237
|
+
* First call mounts the React tree into `renderInto`; subsequent
|
|
238
|
+
* calls re-apply through {@link RenderItemHandle.update} (same kind ⇒
|
|
239
|
+
* in-place; kind transition ⇒ tear-down + remount).
|
|
240
|
+
*
|
|
241
|
+
* Shared by the `render` and `props_update` channel handlers so React
|
|
242
|
+
* updates flow through one path.
|
|
243
|
+
*/
|
|
244
|
+
applyRender(render: Render | RenderSeedInput): Promise<void>;
|
|
245
|
+
/**
|
|
246
|
+
* Read the currently-mounted render. `null` until the first
|
|
247
|
+
* render frame lands. Read by the `props_update` + `data` channel
|
|
248
|
+
* handlers to validate inbound payloads against the active render's
|
|
249
|
+
* `propsSpec` / `streamSpec`.
|
|
250
|
+
*/
|
|
251
|
+
getCurrentRender(): Render | RenderSeedInput | null;
|
|
221
252
|
readonly validatorCtx: RendererValidatorContext;
|
|
222
253
|
/**
|
|
223
254
|
* Send surface for outbound frames. Wired by `setup()` to the WS
|
|
@@ -229,11 +260,10 @@ export interface TriadHandle {
|
|
|
229
260
|
};
|
|
230
261
|
/**
|
|
231
262
|
* Per-channel transport router. When the bootstrap carries
|
|
232
|
-
* `streamWebSocketLocalTools` and the active
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
* `applyStack` hook.
|
|
263
|
+
* `streamWebSocketLocalTools` and the active render declares
|
|
264
|
+
* `streamSpec[ch].source.tool`, the router decides per-channel
|
|
265
|
+
* between WS subscribe + iframe-polling fallback. Updated on every
|
|
266
|
+
* render frame via the render handler.
|
|
237
267
|
*
|
|
238
268
|
* Always present — the router gracefully no-ops when no channel
|
|
239
269
|
* declares `source.tool` (legacy data-frame path is unaffected).
|
|
@@ -241,7 +271,7 @@ export interface TriadHandle {
|
|
|
241
271
|
readonly channelTransport: ChannelTransportRouter;
|
|
242
272
|
/**
|
|
243
273
|
* Channel-client registry holding handlers for every WS frame type
|
|
244
|
-
* the iframe routes (`
|
|
274
|
+
* the iframe routes (`render`, `data`, `props_update`, `drain_ack`,
|
|
245
275
|
* `channel_payload`, `channel_error`, `system`, `feedback`). The
|
|
246
276
|
* registry-bound transport is the sole dispatch surface — frames
|
|
247
277
|
* arrive directly through registered handlers, no longer through a
|
|
@@ -254,56 +284,88 @@ export interface TriadHandle {
|
|
|
254
284
|
* `connectViaRegistry` and consumed during handshake resolution.
|
|
255
285
|
*/
|
|
256
286
|
readonly channelRegistry: ChannelRegistry;
|
|
287
|
+
/**
|
|
288
|
+
* 3rd-party gadget-package merge promise. `installGlobalRegistry`
|
|
289
|
+
* seeds `__ggui__.gadgets` synchronously with the STDLIB namespace;
|
|
290
|
+
* operator-registered packages merge in asynchronously. A static seed
|
|
291
|
+
* mount MUST `await` this (when the bootstrap declares `gadgets`)
|
|
292
|
+
* before the first `applyRender`, so a generated component importing a
|
|
293
|
+
* 3rd-party gadget sees a fully-populated catalog on first paint
|
|
294
|
+
* (otherwise the per-package data-URL shim resolves to `undefined` and
|
|
295
|
+
* crashes). Resolves to the STDLIB-only registry when no 3rd-party
|
|
296
|
+
* packages were declared.
|
|
297
|
+
*/
|
|
298
|
+
readonly composedGadgets: Promise<GadgetPackageRegistry>;
|
|
257
299
|
}
|
|
258
300
|
export interface BootSequenceResult {
|
|
259
301
|
readonly ok: boolean;
|
|
260
|
-
|
|
302
|
+
/**
|
|
303
|
+
* The render that ended up mounted in this iframe, or `null` if
|
|
304
|
+
* the boot path bailed before the first ack landed. Post-render-
|
|
305
|
+
* identity-collapse (2026-05-27) every iframe holds at most one
|
|
306
|
+
* render; this replaces the earlier `StackModel` return that wrapped
|
|
307
|
+
* a multi-item model.
|
|
308
|
+
*/
|
|
309
|
+
readonly mountedRender: Render | RenderSeedInput | null;
|
|
261
310
|
}
|
|
262
311
|
export declare function bootSequence(opts: BootSequenceOptions): Promise<BootSequenceResult>;
|
|
263
312
|
/**
|
|
264
|
-
* Self-contained
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* `SelfContainedSystemBootstrap` narrowings; the protocol's
|
|
268
|
-
* `GguiBootstrapMeta` now carries `codeUrl` / `kind` / `themeId`
|
|
269
|
-
* / `themeMode` / `propsJson` directly (alongside the existing
|
|
270
|
-
* live-mode `wsUrl` / `token` / `expiresAt` fields), so a single
|
|
271
|
-
* shared validator ({@link validateBootstrapMeta} in `bootstrap.ts`)
|
|
272
|
-
* can produce the full envelope from any of three delivery channels.
|
|
313
|
+
* Self-contained slice-meta shape — alias for {@link
|
|
314
|
+
* ValidatedMcpAppAiGguiMeta}. Post-Phase-B every delivery channel
|
|
315
|
+
* produces a single `McpAppAiGguiRenderMeta` slice.
|
|
273
316
|
*
|
|
274
317
|
* The export is kept so downstream consumers (`@ggui-ai/iframe-runtime`
|
|
275
318
|
* barrel, dependent test suites) don't break.
|
|
276
319
|
*
|
|
277
320
|
* @public
|
|
278
321
|
*/
|
|
279
|
-
export type
|
|
322
|
+
export type SelfContainedMcpAppAiGguiMeta = ValidatedMcpAppAiGguiMeta;
|
|
280
323
|
/**
|
|
281
|
-
* Read `globalThis.
|
|
282
|
-
* the unified
|
|
324
|
+
* Read `globalThis.__GGUI_META__` synchronously, validate against
|
|
325
|
+
* the unified slice-meta shape, and return the typed meta (or null
|
|
283
326
|
* on absence / malformation).
|
|
284
327
|
*
|
|
285
|
-
* Thin wrapper around {@link
|
|
328
|
+
* Thin wrapper around {@link parseMetaFromGlobal}; preserved for
|
|
286
329
|
* back-compat (downstream consumers + tests). Returns `null` instead
|
|
287
|
-
* of
|
|
288
|
-
* — the autostart resolver only needs the "valid
|
|
289
|
-
* through" signal.
|
|
330
|
+
* of {@link McpAppAiGguiMetaParseResult} to match the historical
|
|
331
|
+
* reader contract — the autostart resolver only needs the "valid
|
|
332
|
+
* meta or fall through" signal.
|
|
333
|
+
*/
|
|
334
|
+
export declare function readSelfContainedMeta(): SelfContainedMcpAppAiGguiMeta | null;
|
|
335
|
+
/**
|
|
336
|
+
* Project the inline `__GGUI_META__` bootstrap into a
|
|
337
|
+
* {@link RenderSeedInput} the mount surface can paint immediately,
|
|
338
|
+
* BEFORE the authoritative wire `Render` arrives over the WS — and with
|
|
339
|
+
* no WS at all for spec-compliant MCP-Apps hosts that expose no ggui
|
|
340
|
+
* live channel (claude.ai / ChatGPT / Claude Desktop).
|
|
341
|
+
*
|
|
342
|
+
* Two static-content shapes (the autostart discriminator):
|
|
343
|
+
* - `kind` → a system-card seed (`type:'system'`); no fetch.
|
|
344
|
+
* - `codeUrl` → a compiled-component seed; fetches the
|
|
345
|
+
* content-addressable component bytes.
|
|
346
|
+
*
|
|
347
|
+
* Returns `null` when the meta carries NEITHER (a live-only meta has
|
|
348
|
+
* nothing to seed — the first WS ack mounts it). Throws when a `codeUrl`
|
|
349
|
+
* fetch fails so the caller can surface a typed boot failure. The four
|
|
350
|
+
* server-assigned ledger fields are intentionally absent — the first
|
|
351
|
+
* ack reconciles the seed to a full `Render` (no fabrication).
|
|
290
352
|
*/
|
|
291
|
-
export declare function
|
|
353
|
+
export declare function buildRenderSeedInput(meta: SelfContainedMcpAppAiGguiMeta): Promise<RenderSeedInput | null>;
|
|
292
354
|
/**
|
|
293
|
-
* Extract a {@link
|
|
355
|
+
* Extract a {@link SelfContainedMcpAppAiGguiMeta} from a
|
|
294
356
|
* `ui/notifications/tool-result` JSON-RPC params payload — the
|
|
295
357
|
* postMessage delivery shape MCP Apps hosts (Claude Desktop, claude.ai
|
|
296
358
|
* web) use to push the active tool's `_meta` to the iframe.
|
|
297
359
|
*
|
|
298
|
-
* Thin wrapper around {@link
|
|
299
|
-
* back-compat motivation as {@link
|
|
360
|
+
* Thin wrapper around {@link parseMetaFromToolResult}; same
|
|
361
|
+
* back-compat motivation as {@link readSelfContainedMeta}.
|
|
300
362
|
*
|
|
301
363
|
* Owning this extraction inside the runtime (instead of in the shell
|
|
302
364
|
* HTML) is the architectural cure for the "shell-side validator
|
|
303
365
|
* lagged the protocol" bug class: shell + runtime drift becomes
|
|
304
|
-
* impossible because the shell never inspects the
|
|
366
|
+
* impossible because the shell never inspects the slice-meta shape.
|
|
305
367
|
*/
|
|
306
|
-
export declare function
|
|
368
|
+
export declare function extractMetaFromToolResult(params: unknown): SelfContainedMcpAppAiGguiMeta | null;
|
|
307
369
|
/**
|
|
308
370
|
* Render a wired-action's `data` payload as a short inline string
|
|
309
371
|
* for embedding in a `ui/message` consent prompt. Goal: human-
|
|
@@ -336,8 +398,7 @@ export declare function emitAudit(args: {
|
|
|
336
398
|
readonly toolName: string;
|
|
337
399
|
readonly kind: 'dispatch' | 'openLink' | 'requestDisplayMode';
|
|
338
400
|
readonly payload: Record<string, unknown>;
|
|
339
|
-
readonly
|
|
340
|
-
readonly stackItemId?: string;
|
|
401
|
+
readonly renderId: string;
|
|
341
402
|
readonly appId: string;
|
|
342
403
|
readonly actionId: string;
|
|
343
404
|
readonly firedAt: string;
|
|
@@ -347,16 +408,8 @@ export declare function dispatchWiredAction(args: {
|
|
|
347
408
|
readonly toolName: string;
|
|
348
409
|
readonly intent: string;
|
|
349
410
|
readonly data: unknown;
|
|
350
|
-
readonly
|
|
351
|
-
readonly stackItemId?: string;
|
|
411
|
+
readonly renderId: string;
|
|
352
412
|
readonly appId: string;
|
|
353
|
-
/**
|
|
354
|
-
* Optional `actionSpec[intent].nextStep` hint forwarded by the
|
|
355
|
-
* caller. Surfaced on the inline-userAction envelope when the pipe
|
|
356
|
-
* isn't available, so the agent has a strong steer toward the right
|
|
357
|
-
* tool.
|
|
358
|
-
*/
|
|
359
|
-
readonly nextStep?: string;
|
|
360
413
|
}): void;
|
|
361
414
|
/**
|
|
362
415
|
* Fire a wired action via Pattern α — direct `tools/call` against a
|
|
@@ -369,7 +422,7 @@ export declare function dispatchWiredAction(args: {
|
|
|
369
422
|
* PIPE-2 design note: Pattern α deliberately does NOT fire
|
|
370
423
|
* `submit_action` — a pipe append would queue the gesture for the
|
|
371
424
|
* agent's `ggui_consume` long-poll, causing double-processing
|
|
372
|
-
* (host's tool relay AND agent's reaction).
|
|
425
|
+
* (host's tool relay AND agent's reaction). RenderInspector loses
|
|
373
426
|
* Pattern α observability for now; re-add via a dedicated audit-only
|
|
374
427
|
* gesture kind if operators need it.
|
|
375
428
|
*
|
|
@@ -399,12 +452,15 @@ export declare function fireDirectToolCall(args: {
|
|
|
399
452
|
*
|
|
400
453
|
* @internal — exported for unit tests + production reuse.
|
|
401
454
|
*/
|
|
455
|
+
export declare function resolveDispatchToolName(): string;
|
|
456
|
+
/**
|
|
457
|
+
* @internal — exported for unit tests + production reuse.
|
|
458
|
+
*/
|
|
402
459
|
export declare function routeDispatch(args: {
|
|
403
460
|
readonly actionName: string;
|
|
404
461
|
readonly data: unknown;
|
|
405
|
-
readonly
|
|
406
|
-
readonly
|
|
407
|
-
readonly stackItemId?: string;
|
|
462
|
+
readonly meta: {
|
|
463
|
+
readonly renderId: string;
|
|
408
464
|
readonly appId: string;
|
|
409
465
|
readonly appCallableTools?: readonly string[];
|
|
410
466
|
readonly actionNextSteps?: Readonly<Record<string, string>>;
|
|
@@ -420,8 +476,7 @@ export declare function routeDispatch(args: {
|
|
|
420
476
|
export declare function openLinkInParent(args: {
|
|
421
477
|
readonly toolName: string;
|
|
422
478
|
readonly url: string;
|
|
423
|
-
readonly
|
|
424
|
-
readonly stackItemId?: string;
|
|
479
|
+
readonly renderId: string;
|
|
425
480
|
readonly appId: string;
|
|
426
481
|
}): void;
|
|
427
482
|
/**
|
|
@@ -434,8 +489,7 @@ export declare function openLinkInParent(args: {
|
|
|
434
489
|
export declare function requestDisplayModeInParent(args: {
|
|
435
490
|
readonly toolName: string;
|
|
436
491
|
readonly mode: 'fullscreen' | 'pip' | 'inline';
|
|
437
|
-
readonly
|
|
438
|
-
readonly stackItemId?: string;
|
|
492
|
+
readonly renderId: string;
|
|
439
493
|
readonly appId: string;
|
|
440
494
|
}): void;
|
|
441
495
|
/**
|
|
@@ -475,8 +529,7 @@ export declare function requestDisplayModeInParent(args: {
|
|
|
475
529
|
/** @internal — exported for unit tests. */
|
|
476
530
|
export declare function installAnchorClickInterceptor(args: {
|
|
477
531
|
readonly dispatchToolName: string;
|
|
478
|
-
readonly
|
|
479
|
-
readonly stackItemId?: string;
|
|
532
|
+
readonly renderId: string;
|
|
480
533
|
readonly appId: string;
|
|
481
534
|
}): void;
|
|
482
535
|
/**
|
|
@@ -512,13 +565,12 @@ export declare function installAnchorClickInterceptor(args: {
|
|
|
512
565
|
*
|
|
513
566
|
* Idempotent: the {@link fullscreenInterceptInstalled} guard prevents
|
|
514
567
|
* re-mounts from chaining wrappers (which would also leak the prior
|
|
515
|
-
* mount's `
|
|
568
|
+
* mount's `renderId`/`appId` if they ever differed).
|
|
516
569
|
*/
|
|
517
570
|
/** @internal — exported for unit tests. */
|
|
518
571
|
export declare function installFullscreenInterceptors(args: {
|
|
519
572
|
readonly dispatchToolName: string;
|
|
520
|
-
readonly
|
|
521
|
-
readonly stackItemId?: string;
|
|
573
|
+
readonly renderId: string;
|
|
522
574
|
readonly appId: string;
|
|
523
575
|
}): void;
|
|
524
576
|
/**
|