@ggui-ai/iframe-runtime 0.1.0-rc.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.
Files changed (92) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +33 -0
  3. package/dist/bootstrap.d.ts +72 -0
  4. package/dist/bootstrap.js +500 -0
  5. package/dist/canvas/animator/animator-host.d.ts +63 -0
  6. package/dist/canvas/animator/animator-host.js +105 -0
  7. package/dist/canvas/animator/animator-pill.d.ts +42 -0
  8. package/dist/canvas/animator/animator-pill.js +119 -0
  9. package/dist/canvas/animator/state-machine.d.ts +106 -0
  10. package/dist/canvas/animator/state-machine.js +150 -0
  11. package/dist/canvas/canvas-shell.d.ts +77 -0
  12. package/dist/canvas/canvas-shell.js +117 -0
  13. package/dist/canvas/display-mode-policy.d.ts +104 -0
  14. package/dist/canvas/display-mode-policy.js +98 -0
  15. package/dist/canvas/mount.d.ts +150 -0
  16. package/dist/canvas/mount.js +202 -0
  17. package/dist/canvas/nav-stack.d.ts +133 -0
  18. package/dist/canvas/nav-stack.js +172 -0
  19. package/dist/channel-transport.d.ts +182 -0
  20. package/dist/channel-transport.js +344 -0
  21. package/dist/channels/channel-payload.d.ts +20 -0
  22. package/dist/channels/channel-payload.js +34 -0
  23. package/dist/channels/data.d.ts +48 -0
  24. package/dist/channels/data.js +103 -0
  25. package/dist/channels/drain-ack.d.ts +13 -0
  26. package/dist/channels/drain-ack.js +15 -0
  27. package/dist/channels/feedback.d.ts +14 -0
  28. package/dist/channels/feedback.js +19 -0
  29. package/dist/channels/index.d.ts +7 -0
  30. package/dist/channels/index.js +7 -0
  31. package/dist/channels/props-update.d.ts +53 -0
  32. package/dist/channels/props-update.js +130 -0
  33. package/dist/channels/push.d.ts +47 -0
  34. package/dist/channels/push.js +54 -0
  35. package/dist/channels/system.d.ts +26 -0
  36. package/dist/channels/system.js +44 -0
  37. package/dist/compiled-validators.d.ts +40 -0
  38. package/dist/compiled-validators.js +74 -0
  39. package/dist/context-observer.d.ts +205 -0
  40. package/dist/context-observer.js +312 -0
  41. package/dist/gadget-loader.d.ts +118 -0
  42. package/dist/gadget-loader.js +136 -0
  43. package/dist/globals.d.ts +234 -0
  44. package/dist/globals.js +101 -0
  45. package/dist/host-context-emitter.d.ts +91 -0
  46. package/dist/host-context-emitter.js +213 -0
  47. package/dist/iframe-runtime.js +261 -0
  48. package/dist/index.d.ts +38 -0
  49. package/dist/index.js +4 -0
  50. package/dist/lifecycle.d.ts +66 -0
  51. package/dist/lifecycle.js +49 -0
  52. package/dist/mcp-app-iframe-host.d.ts +69 -0
  53. package/dist/mcp-app-iframe-host.js +214 -0
  54. package/dist/observability.d.ts +225 -0
  55. package/dist/observability.js +28 -0
  56. package/dist/protocol-error.d.ts +199 -0
  57. package/dist/protocol-error.js +116 -0
  58. package/dist/provisional-renderer.d.ts +62 -0
  59. package/dist/provisional-renderer.js +323 -0
  60. package/dist/react-renderer.d.ts +95 -0
  61. package/dist/react-renderer.js +343 -0
  62. package/dist/registry-subscribe.d.ts +102 -0
  63. package/dist/registry-subscribe.js +319 -0
  64. package/dist/runtime.d.ts +531 -0
  65. package/dist/runtime.js +2623 -0
  66. package/dist/server.d.ts +36 -0
  67. package/dist/server.js +72 -0
  68. package/dist/stack-item-renderer.d.ts +103 -0
  69. package/dist/stack-item-renderer.js +270 -0
  70. package/dist/stack.d.ts +90 -0
  71. package/dist/stack.js +118 -0
  72. package/dist/status-dom.d.ts +72 -0
  73. package/dist/status-dom.js +51 -0
  74. package/dist/system-cards/NoCredentialsCard.d.ts +33 -0
  75. package/dist/system-cards/NoCredentialsCard.js +189 -0
  76. package/dist/system-cards/ProtocolProbeCard.d.ts +64 -0
  77. package/dist/system-cards/ProtocolProbeCard.js +463 -0
  78. package/dist/system-cards/QrCode.d.ts +46 -0
  79. package/dist/system-cards/QrCode.js +55 -0
  80. package/dist/system-cards/host-detect.d.ts +31 -0
  81. package/dist/system-cards/host-detect.js +108 -0
  82. package/dist/system-cards/host-intents.d.ts +85 -0
  83. package/dist/system-cards/host-intents.js +170 -0
  84. package/dist/system-cards/index.d.ts +70 -0
  85. package/dist/system-cards/index.js +134 -0
  86. package/dist/types.d.ts +69 -0
  87. package/dist/types.js +3 -0
  88. package/dist/validation.d.ts +83 -0
  89. package/dist/validation.js +106 -0
  90. package/dist/wire-config.d.ts +214 -0
  91. package/dist/wire-config.js +290 -0
  92. package/package.json +81 -0
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Default emitter — posts an {@link ObservabilityMessage} to
3
+ * `window.parent`. Mirrors `postBootFailure` / `postRendererReady`
4
+ * posture in `runtime.ts`: swallows postMessage failure so a detached
5
+ * parent doesn't crash the iframe.
6
+ *
7
+ * Lives here (not in `runtime.ts`) so tests exercising individual
8
+ * emission sites can import the same default without dragging in the
9
+ * runtime's module side-effects.
10
+ *
11
+ * @public
12
+ */
13
+ export function postObservabilityToParent(event) {
14
+ // A non-browser import graph (vitest + jsdom before a window is
15
+ // mocked in) has no `window.parent` — guard for that environment
16
+ // so tests importing this helper never throw before their mocks
17
+ // install.
18
+ if (typeof window === 'undefined' || window.parent === null)
19
+ return;
20
+ const message = { type: 'ggui:observe', event };
21
+ try {
22
+ window.parent.postMessage(message, '*');
23
+ }
24
+ catch {
25
+ // Parent unreachable (detached window). Best-effort fire-and-
26
+ // forget — matches postBootFailure's swallow posture.
27
+ }
28
+ }
@@ -0,0 +1,199 @@
1
+ /**
2
+ * `ProtocolError` typed union — canonical shape for every error the
3
+ * renderer surfaces OUTWARD: to the host page via postMessage, to the
4
+ * session via the `_ggui:contract-error` channel, and to the
5
+ * in-iframe status DOM.
6
+ *
7
+ * The transport wiring around this union:
8
+ *
9
+ * - `postMessage({type:'ggui:protocol-error', error})` for every
10
+ * boot-path failure; the `_ggui:contract-error` envelope on the
11
+ * live channel for session-bound failures.
12
+ * - `<McpAppIframe onError={(err: ProtocolError) => …}>` surfaces
13
+ * these to embedding apps.
14
+ *
15
+ * The union is the failure-mode axis of `WireConfig`'s contract:
16
+ * named parties = renderer ↔ host; obligation = the renderer emits a
17
+ * ProtocolError for every failure class; failure mode = exhaustive
18
+ * on `kind`; observable = hosts can pattern-match `err.kind`.
19
+ *
20
+ * Extensibly-closed discipline: `kind: 'protocol'`'s `code` and the
21
+ * `BootstrapFailureReason` union both accept `(string & {})` so
22
+ * servers can introduce new codes without a client bump while IDE
23
+ * autocomplete still lists the canonical set. Every OTHER
24
+ * discriminator (`kind` itself, transport codes, auth codes, version
25
+ * fields) is fully closed — drift there is a real shape change, not
26
+ * a new code.
27
+ */
28
+ import type { ContractErrorPayload } from '@ggui-ai/protocol';
29
+ import { ClientContractViolationError } from '@ggui-ai/wire';
30
+ /**
31
+ * Closed-or-extensibly-closed union of bootstrap-failure reasons.
32
+ *
33
+ * Consolidates three sources:
34
+ *
35
+ * 1. **Parse-time failures** — every member of
36
+ * `BootstrapParseFailureReason` (`MISSING_TOOL_OUTPUT` /
37
+ * `MISSING_META_GGUI_BOOTSTRAP` / `MALFORMED_BOOTSTRAP` /
38
+ * `EXPIRED_BOOTSTRAP`). `MISSING_META_GGUI_BOOTSTRAP` and
39
+ * `BOOTSTRAP_META_MISSING` are synonyms — the latter is the
40
+ * on-wire name, the former the parse-internal name.
41
+ *
42
+ * 2. **Post-parse orchestration failures** — `UI_INITIALIZE_FAILED`
43
+ * / `WS_HANDSHAKE_FAILED`. Matches `RendererBootFailureReason`.
44
+ *
45
+ * 3. **Transport-observable failures** — `BUNDLE_FETCH_FAILED` /
46
+ * `CSP_VIOLATION` / `SESSION_NOT_FOUND` / `AUTH_REJECTED`. These
47
+ * fire before the renderer parse path runs, so they're authored
48
+ * here rather than inside `BootstrapParseFailureReason`.
49
+ *
50
+ * `(string & {})` tail keeps the union extensibly-closed — new wire
51
+ * codes can land without a client bump, while IDE autocomplete
52
+ * surfaces the canonical set.
53
+ */
54
+ export type BootstrapFailureReason = 'MISSING_TOOL_OUTPUT' | 'MISSING_META_GGUI_BOOTSTRAP' | 'BOOTSTRAP_META_MISSING' | 'MALFORMED_BOOTSTRAP' | 'EXPIRED_BOOTSTRAP' | 'UI_INITIALIZE_FAILED' | 'WS_HANDSHAKE_FAILED' | 'UPGRADE_REQUIRED' | 'BUNDLE_FETCH_FAILED' | 'CSP_VIOLATION' | 'SESSION_NOT_FOUND' | 'AUTH_REJECTED' | (string & {});
55
+ /**
56
+ * Every error the renderer surfaces outward flows through this union.
57
+ *
58
+ * Discriminated on `kind`:
59
+ *
60
+ * - `transport` — WebSocket-level failure (DISCONNECTED / TIMEOUT).
61
+ * Includes `retryable` so hosts can decide to reconnect
62
+ * vs. give up.
63
+ * - `auth` — session / token rejection pre-handshake.
64
+ * `SESSION_NOT_FOUND` / `TOKEN_EXPIRED` /
65
+ * `AUTH_REJECTED` — all terminal; hosts typically
66
+ * escalate to a login flow.
67
+ * - `protocol` — envelope / session-mismatch failures post-handshake.
68
+ * Extensibly-closed on `code` because servers may
69
+ * introduce new codes without a client bump.
70
+ * `details` carries opaque structured context.
71
+ * - `contract` — client-contract violation. Payload matches the
72
+ * protocol-owned `ContractErrorPayload` so the
73
+ * `_ggui:contract-error` envelope shape flows
74
+ * unchanged through this variant.
75
+ * - `bootstrap` — anything in {@link BootstrapFailureReason}.
76
+ * - `version` — `UPGRADE_REQUIRED` path (handshake rejection).
77
+ * `serverVersion` may be absent on the wire; callers
78
+ * tolerate `undefined` for legacy servers.
79
+ * - `unknown` — fallback for anything the renderer failed to
80
+ * classify. Always carries the raw value so hosts
81
+ * can at least log it.
82
+ */
83
+ export type ProtocolError = {
84
+ readonly kind: 'transport';
85
+ readonly code: 'DISCONNECTED' | 'TIMEOUT';
86
+ readonly retryable: boolean;
87
+ readonly message?: string;
88
+ } | {
89
+ readonly kind: 'auth';
90
+ readonly code: 'SESSION_NOT_FOUND' | 'TOKEN_EXPIRED' | 'AUTH_REJECTED';
91
+ readonly message?: string;
92
+ } | {
93
+ readonly kind: 'protocol';
94
+ readonly code: 'SESSION_MISMATCH' | 'APP_MISMATCH' | 'MALFORMED_ENVELOPE' | (string & {});
95
+ readonly message?: string;
96
+ readonly details?: unknown;
97
+ } | {
98
+ readonly kind: 'contract';
99
+ readonly payload: ContractErrorPayload;
100
+ } | {
101
+ readonly kind: 'bootstrap';
102
+ readonly reason: BootstrapFailureReason;
103
+ readonly message: string;
104
+ } | {
105
+ readonly kind: 'version';
106
+ readonly serverVersion?: string;
107
+ readonly clientSupports: readonly string[];
108
+ readonly message?: string;
109
+ } | {
110
+ readonly kind: 'unknown';
111
+ readonly raw: unknown;
112
+ };
113
+ /**
114
+ * Caller sink for every `ProtocolError` the renderer classifies.
115
+ *
116
+ * This is OPTIONAL on every emitter site — the default is a tagged
117
+ * `console.warn` so operators see the error in dev. The
118
+ * `<McpAppIframe>` host wrapper bridges this to its `onError` prop;
119
+ * session-bound variants are ALSO routed to the
120
+ * `_ggui:contract-error` envelope over the WebSocket.
121
+ *
122
+ * Handlers MUST NOT throw — the emitter already fired the renderer's
123
+ * own fallback path; a throwing handler would mask the real error.
124
+ * Implementations that want to re-surface (e.g. console inspector)
125
+ * should `queueMicrotask(() => …)` before any heavier work.
126
+ */
127
+ export type ProtocolErrorEmitter = (err: ProtocolError) => void;
128
+ /**
129
+ * Default emitter — operator-visible `console.warn` with a grep-
130
+ * friendly tag. Identical posture to `GguiSession.surfaceContractViolation`'s
131
+ * console.warn fallback. Callers override by injecting their own.
132
+ */
133
+ export declare function defaultProtocolErrorEmitter(err: ProtocolError): void;
134
+ /**
135
+ * Map a client-side `ClientContractViolationError` (from
136
+ * `@ggui-ai/wire`, fired when a pre-dispatch validator rejects an
137
+ * outbound action, or when an inbound stream / props payload fails the
138
+ * local validator) onto a `ProtocolError`.
139
+ *
140
+ * Client-side violations do NOT ride the server-emitted
141
+ * `_ggui:contract-error` envelope — that shape (`ContractErrorPayload`)
142
+ * is tool-failure-scoped and authored by the session-channel router.
143
+ * A client-side violation is a DIFFERENT category: nothing reached the
144
+ * tool. We surface it as `{kind: 'protocol'; code:
145
+ * 'CLIENT_CONTRACT_VIOLATION'}` with structured `details` so hosts can
146
+ * render the same summary that `console.warn` would have produced.
147
+ *
148
+ * Server-emitted `ContractErrorPayload` landing on
149
+ * `_ggui:contract-error` rides the separate `{kind: 'contract'}`
150
+ * variant — that path activates when the renderer observes the
151
+ * reserved channel.
152
+ */
153
+ export declare function fromClientContractViolation(err: ClientContractViolationError): ProtocolError;
154
+ /**
155
+ * Wrap a server-emitted `ContractErrorPayload` (received over the
156
+ * reserved `_ggui:contract-error` channel) as the 'contract' variant.
157
+ * Trivial wrapper — exists so call sites produce the union via a
158
+ * factory rather than an object literal (keeps emission uniform and
159
+ * makes grep for creation sites exact).
160
+ */
161
+ export declare function fromContractErrorPayload(payload: ContractErrorPayload): ProtocolError;
162
+ /**
163
+ * Build a `ProtocolError` of kind 'version' from the existing
164
+ * `UpgradeRequiredError` class. Matches the `liftUpgradeRequiredFromError`
165
+ * shape already plumbed through `subscribe.ts`.
166
+ *
167
+ * `UpgradeRequiredError.observedVersion` can be `string` (one version)
168
+ * OR `readonly string[]` (the server advertised a set). We collapse
169
+ * the array form to a comma-separated string to keep the 'version'
170
+ * variant shape a single optional string — hosts render the observed
171
+ * set uniformly.
172
+ */
173
+ export declare function fromUpgradeRequired(err: {
174
+ readonly observedVersion?: string | readonly string[];
175
+ readonly acceptedVersions: readonly string[];
176
+ readonly message: string;
177
+ }): ProtocolError;
178
+ /**
179
+ * Build a `ProtocolError` of kind 'bootstrap' — closed-or-extensibly-
180
+ * closed reason + operator-visible message.
181
+ */
182
+ export declare function fromBootstrapFailure(reason: BootstrapFailureReason, message: string): ProtocolError;
183
+ /**
184
+ * Fallback constructor — wraps any raw value we can't classify.
185
+ * Keeps the emitter union total.
186
+ */
187
+ export declare function fromUnknown(raw: unknown): ProtocolError;
188
+ /**
189
+ * Build a `ProtocolError` of kind 'transport' — disconnection /
190
+ * timeout paths. `retryable` differentiates the reconnection-eligible
191
+ * `DISCONNECTED` from terminal `TIMEOUT` states; hosts pattern-match
192
+ * on the flag.
193
+ */
194
+ export declare function fromTransportFailure(code: 'DISCONNECTED' | 'TIMEOUT', retryable: boolean, message?: string): ProtocolError;
195
+ /**
196
+ * Build a `ProtocolError` of kind 'auth' — session / token rejection
197
+ * pre-handshake.
198
+ */
199
+ export declare function fromAuthFailure(code: 'SESSION_NOT_FOUND' | 'TOKEN_EXPIRED' | 'AUTH_REJECTED', message?: string): ProtocolError;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Default emitter — operator-visible `console.warn` with a grep-
3
+ * friendly tag. Identical posture to `GguiSession.surfaceContractViolation`'s
4
+ * console.warn fallback. Callers override by injecting their own.
5
+ */
6
+ export function defaultProtocolErrorEmitter(err) {
7
+ // eslint-disable-next-line no-console -- dev-visible signal; mirrors
8
+ // the pre-ProtocolError console.warn fallbacks across renderer paths.
9
+ console.warn('[ggui:protocol-error]', err);
10
+ }
11
+ // =============================================================================
12
+ // Constructors — keep creation sites honest
13
+ // =============================================================================
14
+ /**
15
+ * Map a client-side `ClientContractViolationError` (from
16
+ * `@ggui-ai/wire`, fired when a pre-dispatch validator rejects an
17
+ * outbound action, or when an inbound stream / props payload fails the
18
+ * local validator) onto a `ProtocolError`.
19
+ *
20
+ * Client-side violations do NOT ride the server-emitted
21
+ * `_ggui:contract-error` envelope — that shape (`ContractErrorPayload`)
22
+ * is tool-failure-scoped and authored by the session-channel router.
23
+ * A client-side violation is a DIFFERENT category: nothing reached the
24
+ * tool. We surface it as `{kind: 'protocol'; code:
25
+ * 'CLIENT_CONTRACT_VIOLATION'}` with structured `details` so hosts can
26
+ * render the same summary that `console.warn` would have produced.
27
+ *
28
+ * Server-emitted `ContractErrorPayload` landing on
29
+ * `_ggui:contract-error` rides the separate `{kind: 'contract'}`
30
+ * variant — that path activates when the renderer observes the
31
+ * reserved channel.
32
+ */
33
+ export function fromClientContractViolation(err) {
34
+ return {
35
+ kind: 'protocol',
36
+ code: 'CLIENT_CONTRACT_VIOLATION',
37
+ message: err.message,
38
+ details: {
39
+ direction: err.direction,
40
+ violations: err.violations,
41
+ },
42
+ };
43
+ }
44
+ /**
45
+ * Wrap a server-emitted `ContractErrorPayload` (received over the
46
+ * reserved `_ggui:contract-error` channel) as the 'contract' variant.
47
+ * Trivial wrapper — exists so call sites produce the union via a
48
+ * factory rather than an object literal (keeps emission uniform and
49
+ * makes grep for creation sites exact).
50
+ */
51
+ export function fromContractErrorPayload(payload) {
52
+ return { kind: 'contract', payload };
53
+ }
54
+ /**
55
+ * Build a `ProtocolError` of kind 'version' from the existing
56
+ * `UpgradeRequiredError` class. Matches the `liftUpgradeRequiredFromError`
57
+ * shape already plumbed through `subscribe.ts`.
58
+ *
59
+ * `UpgradeRequiredError.observedVersion` can be `string` (one version)
60
+ * OR `readonly string[]` (the server advertised a set). We collapse
61
+ * the array form to a comma-separated string to keep the 'version'
62
+ * variant shape a single optional string — hosts render the observed
63
+ * set uniformly.
64
+ */
65
+ export function fromUpgradeRequired(err) {
66
+ const serverVersion = err.observedVersion === undefined
67
+ ? undefined
68
+ : typeof err.observedVersion === 'string'
69
+ ? err.observedVersion
70
+ : err.observedVersion.join(', ');
71
+ return {
72
+ kind: 'version',
73
+ ...(serverVersion !== undefined ? { serverVersion } : {}),
74
+ clientSupports: err.acceptedVersions,
75
+ message: err.message,
76
+ };
77
+ }
78
+ /**
79
+ * Build a `ProtocolError` of kind 'bootstrap' — closed-or-extensibly-
80
+ * closed reason + operator-visible message.
81
+ */
82
+ export function fromBootstrapFailure(reason, message) {
83
+ return { kind: 'bootstrap', reason, message };
84
+ }
85
+ /**
86
+ * Fallback constructor — wraps any raw value we can't classify.
87
+ * Keeps the emitter union total.
88
+ */
89
+ export function fromUnknown(raw) {
90
+ return { kind: 'unknown', raw };
91
+ }
92
+ /**
93
+ * Build a `ProtocolError` of kind 'transport' — disconnection /
94
+ * timeout paths. `retryable` differentiates the reconnection-eligible
95
+ * `DISCONNECTED` from terminal `TIMEOUT` states; hosts pattern-match
96
+ * on the flag.
97
+ */
98
+ export function fromTransportFailure(code, retryable, message) {
99
+ return {
100
+ kind: 'transport',
101
+ code,
102
+ retryable,
103
+ ...(message !== undefined ? { message } : {}),
104
+ };
105
+ }
106
+ /**
107
+ * Build a `ProtocolError` of kind 'auth' — session / token rejection
108
+ * pre-handshake.
109
+ */
110
+ export function fromAuthFailure(code, message) {
111
+ return {
112
+ kind: 'auth',
113
+ code,
114
+ ...(message !== undefined ? { message } : {}),
115
+ };
116
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Provisional (A2UI preview) renderer for the iframe runtime.
3
+ *
4
+ * Port of `@ggui-ai/react::components/ProvisionalRenderer.tsx` with
5
+ * the React-hook consumer stripped. The A2UI reduce + adjacency-list
6
+ * render is preserved verbatim; the inputs + mount lifecycle differ:
7
+ *
8
+ * - Host-SDK version reads via `useChannelStream(PREVIEW_CHANNEL)`
9
+ * (a React hook subscribed to a live-channel bridge event).
10
+ * - Iframe-renderer version is driven by an explicit
11
+ * `pushEnvelope(env)` entry point invoked by `subscribe.ts` on
12
+ * every validated inbound `data` envelope whose channel is
13
+ * `_ggui:preview`. The caller (runtime.ts) forwards envelopes
14
+ * after the reserved-channel A2UI validator has accepted them.
15
+ *
16
+ * Visual language: `PreviewSurface` / `PreviewFragmentEnter` /
17
+ * `StreamingText` from `@ggui-ai/design/preview`; primitive mapping
18
+ * from `@ggui-ai/design/primitives`. Matches the host-SDK output
19
+ * 1:1 — operator-visible preview DOM is identical on both paths.
20
+ *
21
+ * Lifecycle:
22
+ *
23
+ * - `mountProvisional(container)` → `{pushEnvelope, suspend,
24
+ * resume, unmount}` handle. The container renders the default
25
+ * loading fallback until A2UI's `root` fragment arrives; then
26
+ * the adjacency tree paints.
27
+ * - `suspend()` hides the surface (used when the authoritative
28
+ * render takes over — the stack-item dispatcher in Commit 4
29
+ * toggles this on ReactComponentRenderer mount).
30
+ * - `resume()` re-shows. Envelopes keep accumulating in state
31
+ * while suspended, matching host-SDK behavior.
32
+ */
33
+ import React, { type ReactNode } from 'react';
34
+ import type { StreamEnvelope } from '@ggui-ai/protocol';
35
+ export interface ProvisionalMount {
36
+ /**
37
+ * Feed a stream envelope. Ignores non-PREVIEW_CHANNEL envelopes
38
+ * silently so callers can forward their full inbound stream
39
+ * without filtering first. Caller MUST run reserved-channel
40
+ * validation before pushing — the provisional renderer treats the
41
+ * payload as trusted.
42
+ */
43
+ pushEnvelope(envelope: StreamEnvelope): void;
44
+ /** Hide the surface (authoritative render takes over). */
45
+ suspend(): void;
46
+ /** Re-show the surface. */
47
+ resume(): void;
48
+ /** Tear down the React root + release retained state. */
49
+ unmount(): void;
50
+ }
51
+ /**
52
+ * Mount the provisional surface into `container`. Returns a handle
53
+ * callers use to push envelopes + suspend/resume + unmount.
54
+ *
55
+ * Synchronous-ish — the React root renders on next microtask, so
56
+ * the `controlRef` is populated by the time the caller's next
57
+ * microtask runs. Tests use `await Promise.resolve()` to sync.
58
+ */
59
+ export declare function mountProvisional(container: HTMLElement, opts?: {
60
+ fallback?: ReactNode;
61
+ }): ProvisionalMount;
62
+ export { React };