@ggui-ai/iframe-runtime 0.2.0-alpha.4 → 0.4.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/channel-transport.d.ts +20 -30
  2. package/dist/channel-transport.js +24 -24
  3. package/dist/channels/data.d.ts +5 -20
  4. package/dist/channels/data.js +4 -52
  5. package/dist/channels/index.d.ts +0 -1
  6. package/dist/channels/index.js +0 -1
  7. package/dist/channels/props-update.d.ts +9 -9
  8. package/dist/channels/props-update.js +9 -9
  9. package/dist/channels/render-frame.d.ts +5 -5
  10. package/dist/channels/render-frame.js +5 -5
  11. package/dist/compiled-validators.d.ts +2 -2
  12. package/dist/compiled-validators.js +1 -1
  13. package/dist/context-observer.d.ts +4 -4
  14. package/dist/context-observer.js +3 -3
  15. package/dist/events-polling.d.ts +7 -7
  16. package/dist/events-polling.js +5 -5
  17. package/dist/globals.d.ts +1 -1
  18. package/dist/host-context-emitter.d.ts +4 -4
  19. package/dist/host-context-emitter.js +9 -9
  20. package/dist/iframe-runtime.js +68 -78
  21. package/dist/iframe-runtime.meta.json +1 -0
  22. package/dist/index.d.ts +4 -4
  23. package/dist/index.js +1 -1
  24. package/dist/lifecycle.d.ts +3 -3
  25. package/dist/lifecycle.js +29 -6
  26. package/dist/mcp-app-iframe-host.d.ts +8 -8
  27. package/dist/mcp-app-iframe-host.js +4 -4
  28. package/dist/meta-parse.d.ts +3 -4
  29. package/dist/meta-parse.js +17 -44
  30. package/dist/observability.d.ts +14 -36
  31. package/dist/observability.js +2 -1
  32. package/dist/protocol-error.d.ts +38 -48
  33. package/dist/protocol-error.js +5 -23
  34. package/dist/provisional-renderer.js +3 -3
  35. package/dist/react-renderer.d.ts +16 -6
  36. package/dist/react-renderer.js +22 -40
  37. package/dist/registry-subscribe.d.ts +7 -7
  38. package/dist/registry-subscribe.js +28 -14
  39. package/dist/render-item.d.ts +22 -15
  40. package/dist/render-item.js +7 -14
  41. package/dist/runtime.d.ts +79 -105
  42. package/dist/runtime.js +219 -269
  43. package/dist/status-dom.d.ts +12 -12
  44. package/dist/status-dom.js +11 -11
  45. package/dist/system-cards/NoCredentialsCard.d.ts +1 -1
  46. package/dist/system-cards/NoCredentialsCard.js +1 -1
  47. package/dist/system-cards/ProtocolProbeCard.d.ts +13 -17
  48. package/dist/system-cards/ProtocolProbeCard.js +21 -25
  49. package/dist/system-cards/index.d.ts +5 -5
  50. package/dist/system-cards/index.js +5 -5
  51. package/dist/types.d.ts +29 -34
  52. package/dist/validation.d.ts +4 -5
  53. package/dist/validation.js +5 -6
  54. package/dist/wire-config.d.ts +43 -106
  55. package/dist/wire-config.js +29 -195
  56. package/package.json +14 -12
  57. package/dist/channels/feedback.d.ts +0 -14
  58. package/dist/channels/feedback.js +0 -19
@@ -26,7 +26,7 @@
26
26
  * - `initializing` — legacy alias for `idle`.
27
27
  * - `connecting` — ui/initialize fired or WS handshake in flight.
28
28
  * - `connected` — first ack landed + every subsequent successful
29
- * push.
29
+ * render.
30
30
  * - `reconnecting` — WS dropped; reconnect ladder running.
31
31
  * - `disconnected` — terminal close + ladder exhausted.
32
32
  * - `upgrade-required` — version handshake failed.
@@ -41,21 +41,21 @@ export type StatusKind = 'idle' | 'initializing' | 'connecting' | 'connected' |
41
41
  * Refs handed back from {@link ensureStatusDom}. `status` is a detached
42
42
  * element kept for backward compatibility with channel handlers that
43
43
  * still pass `refs.status` through; it is NEVER appended to the
44
- * document, so production iframes carry no diagnostic banner. `stack`
45
- * is the React mount target — appended to `document.body` so renderer
46
- * wiring has a container.
44
+ * document, so production iframes carry no diagnostic banner.
45
+ * `renderRoot` is the React mount target — appended to `document.body`
46
+ * so renderer wiring has a container.
47
47
  */
48
48
  export interface StatusRefs {
49
49
  readonly status: HTMLElement;
50
- readonly stack: HTMLElement;
50
+ readonly renderRoot: HTMLElement;
51
51
  }
52
52
  /**
53
- * Build the React mount target. Reuses pre-existing `[data-ggui-stack]`
54
- * if the shell already wrote one (cf. `buildSelfContainedShell`); else
55
- * creates a fresh `<ul data-ggui-stack>` and appends it to `<body>`.
56
- * The companion `status` element is created detached and never
57
- * appended — consumers that still pass it through `StatusRefs` see no
58
- * visible effect.
53
+ * Build the React mount target. Reuses a pre-existing
54
+ * `[data-ggui-session-root]` if one was already written; else creates a
55
+ * fresh `<ul data-ggui-session-root>` and appends it to `<body>`. The
56
+ * companion `status` element is created detached and never appended —
57
+ * consumers that still pass it through `StatusRefs` see no visible
58
+ * effect.
59
59
  *
60
60
  * The `<ul>` element name is preserved (legacy from the stack-of-N
61
61
  * placeholder render path) but only ever holds a single React mount
@@ -72,6 +72,6 @@ export declare function setStatus(refs: StatusRefs, text: string, state: StatusK
72
72
  * Log the "connected" transition. Post-stack-removal the iframe always
73
73
  * holds exactly one item; the message stays bare ("Connected.") since
74
74
  * there's no count to surface. Consumers (devtools, e2e specs
75
- * intercepting `console.log`) get a stable string on every push.
75
+ * intercepting `console.log`) get a stable string on every render.
76
76
  */
77
77
  export declare function setConnectedStatus(refs: StatusRefs): void;
@@ -18,23 +18,23 @@
18
18
  * shape.
19
19
  */
20
20
  /**
21
- * Build the React mount target. Reuses pre-existing `[data-ggui-stack]`
22
- * if the shell already wrote one (cf. `buildSelfContainedShell`); else
23
- * creates a fresh `<ul data-ggui-stack>` and appends it to `<body>`.
24
- * The companion `status` element is created detached and never
25
- * appended — consumers that still pass it through `StatusRefs` see no
26
- * visible effect.
21
+ * Build the React mount target. Reuses a pre-existing
22
+ * `[data-ggui-session-root]` if one was already written; else creates a
23
+ * fresh `<ul data-ggui-session-root>` and appends it to `<body>`. The
24
+ * companion `status` element is created detached and never appended —
25
+ * consumers that still pass it through `StatusRefs` see no visible
26
+ * effect.
27
27
  *
28
28
  * The `<ul>` element name is preserved (legacy from the stack-of-N
29
29
  * placeholder render path) but only ever holds a single React mount
30
30
  * subtree post-stack-removal.
31
31
  */
32
32
  export function ensureStatusDom(doc) {
33
- const existingStack = doc.querySelector('[data-ggui-stack]');
34
- const stack = existingStack ??
33
+ const existingRoot = doc.querySelector('[data-ggui-session-root]');
34
+ const renderRoot = existingRoot ??
35
35
  (() => {
36
36
  const el = doc.createElement('ul');
37
- el.setAttribute('data-ggui-stack', '');
37
+ el.setAttribute('data-ggui-session-root', '');
38
38
  doc.body.appendChild(el);
39
39
  return el;
40
40
  })();
@@ -44,7 +44,7 @@ export function ensureStatusDom(doc) {
44
44
  const status = doc.createElement('div');
45
45
  status.setAttribute('data-ggui-status', 'idle');
46
46
  status.setAttribute('aria-hidden', 'true');
47
- return { status, stack };
47
+ return { status, renderRoot };
48
48
  }
49
49
  /**
50
50
  * Log a status transition. The element is mutated for backward compat
@@ -61,7 +61,7 @@ export function setStatus(refs, text, state) {
61
61
  * Log the "connected" transition. Post-stack-removal the iframe always
62
62
  * holds exactly one item; the message stays bare ("Connected.") since
63
63
  * there's no count to surface. Consumers (devtools, e2e specs
64
- * intercepting `console.log`) get a stable string on every push.
64
+ * intercepting `console.log`) get a stable string on every render.
65
65
  */
66
66
  export function setConnectedStatus(refs) {
67
67
  setStatus(refs, 'Connected.', 'connected');
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * No-credentials system card.
3
3
  *
4
- * Rendered when the server processed a `ggui_render` for a session whose
4
+ * Rendered when the server processed a `ggui_render` for a render whose
5
5
  * LLM credentials are missing or unresolvable. The user needs to open
6
6
  * the server's `/settings` page in a real browser tab to paste an API
7
7
  * key.
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * No-credentials system card.
4
4
  *
5
- * Rendered when the server processed a `ggui_render` for a session whose
5
+ * Rendered when the server processed a `ggui_render` for a render whose
6
6
  * LLM credentials are missing or unresolvable. The user needs to open
7
7
  * the server's `/settings` page in a real browser tab to paste an API
8
8
  * key.
@@ -4,24 +4,20 @@
4
4
  * Diagnostic + regression fixture exercising every gesture surface
5
5
  * the iframe runtime routes:
6
6
  *
7
- * 1. **Pattern β bridge** — `tools/call ggui_runtime_submit_action` (audit) +
8
- * `ui/update-model-context` (silent context) + `ui/message`
9
- * (consent prompt). Fires for cross-server / non-app-visible
10
- * `actionSpec[name].dispatch.tool` targets, OR any
11
- * `dispatch.kind === 'agent'` entry. Empirical-first reproduction
12
- * of the production `dispatchWiredAction` path.
13
- * 2. **Pattern α direct fire** — `tools/call ggui_runtime_submit_action`
14
- * (audit) + `tools/call <T>` (direct, no consent prompt). Fires
15
- * for same-server, app-visible target tools. Probes against
16
- * `ggui_runtime_submit_action` itself (the only universally-app-visible
17
- * tool the iframe can be sure exists).
18
- * 3. **Native-idiom: anchor click** — `ui/open-link` paired with
7
+ * 1. **Submit-action bridge** — `tools/call ggui_runtime_submit_action`
8
+ * (audit) + `ui/update-model-context` (silent context) +
9
+ * `ui/message` (consent prompt). Fires for every
10
+ * `actionSpec[name]` dispatch — the gesture queues on the
11
+ * render's consume pipe for the agent (`nextStep` is an advisory
12
+ * hint, never a client-side route). Empirical-first reproduction
13
+ * of the production `dispatchSubmitAction` path.
14
+ * 2. **Native-idiom: anchor click** — `ui/open-link` paired with
19
15
  * `kind: 'openLink'` audit. Triggered by the runtime's
20
16
  * capture-phase `<a href>` interceptor (cross-origin or
21
17
  * `target="_blank"`). The probe row simulates the postMessage
22
18
  * directly so the operator sees the envelope without needing to
23
19
  * click an anchor.
24
- * 4. **Native-idiom: fullscreen** — `ui/request-display-mode` +
20
+ * 3. **Native-idiom: fullscreen** — `ui/request-display-mode` +
25
21
  * `kind: 'requestDisplayMode'` audit. Triggered by the runtime's
26
22
  * `Element.prototype.requestFullscreen` /
27
23
  * `Document.prototype.exitFullscreen` overrides. The probe row
@@ -35,8 +31,8 @@
35
31
  * host-issued request seen while the card is mounted.
36
32
  *
37
33
  * Why this lives outside the wire-context: system cards (`kind:
38
- * 'mcp-apps-probe'`, `'no-credentials'`, …) mount in a render-only
39
- * branch of `bootSelfContained` that does NOT install
34
+ * 'mcp-apps-probe'`, `'no-credentials'`, …) mount in render-item's
35
+ * `kind === 'system'` branch, which does NOT install
40
36
  * `<GguiWireProvider>` — they exist precisely to surface protocol
41
37
  * state when the wire-context might not be live (auth missing,
42
38
  * compile failed, etc.). The probe card mirrors the postMessage
@@ -50,12 +46,12 @@
50
46
  * reject `tools/call` from views for tools without `'app'` in
51
47
  * visibility — claude.ai silently dropped the call. The original
52
48
  * probe diagnosed the gap; the routing simplification work landed
53
- * Pattern α / Pattern β / native idioms in response.
49
+ * the submit-action bridge + native idioms in response.
54
50
  */
55
51
  import * as React from 'react';
56
52
  export interface ProtocolProbeCardProps {
57
53
  /**
58
- * Optional: the original prompt that triggered the probe push.
54
+ * Optional: the original prompt that triggered the probe render.
59
55
  * Surfaced as a footnote so the card matches the framing of other
60
56
  * system cards (`NoCredentialsCard`).
61
57
  */
@@ -5,24 +5,20 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  * Diagnostic + regression fixture exercising every gesture surface
6
6
  * the iframe runtime routes:
7
7
  *
8
- * 1. **Pattern β bridge** — `tools/call ggui_runtime_submit_action` (audit) +
9
- * `ui/update-model-context` (silent context) + `ui/message`
10
- * (consent prompt). Fires for cross-server / non-app-visible
11
- * `actionSpec[name].dispatch.tool` targets, OR any
12
- * `dispatch.kind === 'agent'` entry. Empirical-first reproduction
13
- * of the production `dispatchWiredAction` path.
14
- * 2. **Pattern α direct fire** — `tools/call ggui_runtime_submit_action`
15
- * (audit) + `tools/call <T>` (direct, no consent prompt). Fires
16
- * for same-server, app-visible target tools. Probes against
17
- * `ggui_runtime_submit_action` itself (the only universally-app-visible
18
- * tool the iframe can be sure exists).
19
- * 3. **Native-idiom: anchor click** — `ui/open-link` paired with
8
+ * 1. **Submit-action bridge** — `tools/call ggui_runtime_submit_action`
9
+ * (audit) + `ui/update-model-context` (silent context) +
10
+ * `ui/message` (consent prompt). Fires for every
11
+ * `actionSpec[name]` dispatch — the gesture queues on the
12
+ * render's consume pipe for the agent (`nextStep` is an advisory
13
+ * hint, never a client-side route). Empirical-first reproduction
14
+ * of the production `dispatchSubmitAction` path.
15
+ * 2. **Native-idiom: anchor click** — `ui/open-link` paired with
20
16
  * `kind: 'openLink'` audit. Triggered by the runtime's
21
17
  * capture-phase `<a href>` interceptor (cross-origin or
22
18
  * `target="_blank"`). The probe row simulates the postMessage
23
19
  * directly so the operator sees the envelope without needing to
24
20
  * click an anchor.
25
- * 4. **Native-idiom: fullscreen** — `ui/request-display-mode` +
21
+ * 3. **Native-idiom: fullscreen** — `ui/request-display-mode` +
26
22
  * `kind: 'requestDisplayMode'` audit. Triggered by the runtime's
27
23
  * `Element.prototype.requestFullscreen` /
28
24
  * `Document.prototype.exitFullscreen` overrides. The probe row
@@ -36,8 +32,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
36
32
  * host-issued request seen while the card is mounted.
37
33
  *
38
34
  * Why this lives outside the wire-context: system cards (`kind:
39
- * 'mcp-apps-probe'`, `'no-credentials'`, …) mount in a render-only
40
- * branch of `bootSelfContained` that does NOT install
35
+ * 'mcp-apps-probe'`, `'no-credentials'`, …) mount in render-item's
36
+ * `kind === 'system'` branch, which does NOT install
41
37
  * `<GguiWireProvider>` — they exist precisely to surface protocol
42
38
  * state when the wire-context might not be live (auth missing,
43
39
  * compile failed, etc.). The probe card mirrors the postMessage
@@ -51,7 +47,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
51
47
  * reject `tools/call` from views for tools without `'app'` in
52
48
  * visibility — claude.ai silently dropped the call. The original
53
49
  * probe diagnosed the gap; the routing simplification work landed
54
- * Pattern α / Pattern β / native idioms in response.
50
+ * the submit-action bridge + native idioms in response.
55
51
  */
56
52
  import * as React from 'react';
57
53
  import { Card, Stack, Heading, Text, Button, Badge, } from '@ggui-ai/design/primitives';
@@ -190,7 +186,7 @@ function defaultParams(method) {
190
186
  case 'ui/request-display-mode':
191
187
  return { mode: 'fullscreen' };
192
188
  case 'tools/call':
193
- // Mirror `runtime.ts::emitAudit` + `runtime.ts::dispatchWiredAction`
189
+ // Mirror `runtime.ts::emitAudit` + `runtime.ts::dispatchSubmitAction`
194
190
  // so this probe empirically validates the canonical
195
191
  // `GguiUserActionInput` envelope (SPEC §4.6, see
196
192
  // `@ggui-ai/protocol/integrations/mcp-apps`). `ggui_runtime_submit_action`
@@ -200,9 +196,9 @@ function defaultParams(method) {
200
196
  // a tool result; the host forwards that result to this iframe
201
197
  // via the JSON-RPC response matching our outbound id.
202
198
  //
203
- // The probe uses `kind: 'dispatch'` so the chained Pattern β
204
- // 3-message follow-up (`ui/update-model-context` + `ui/message`)
205
- // semantically matches a real wired-action click.
199
+ // The probe uses `kind: 'dispatch'` so the chained 3-message
200
+ // follow-up (`ui/update-model-context` + `ui/message`)
201
+ // semantically matches a real submit-action click.
206
202
  return {
207
203
  name: 'ggui_runtime_submit_action',
208
204
  arguments: {
@@ -211,7 +207,7 @@ function defaultParams(method) {
211
207
  intent: 'probe-click',
212
208
  data: { note: 'hello from the protocol probe' },
213
209
  },
214
- renderId: 'probe-render',
210
+ sessionId: 'probe-render',
215
211
  appId: 'probe-app',
216
212
  actionId: '00000000', // overwritten in onClick with real FNV-1a
217
213
  firedAt: new Date().toISOString(),
@@ -222,7 +218,7 @@ function defaultParams(method) {
222
218
  /**
223
219
  * Compute a short deterministic action-id from an action payload.
224
220
  * FNV-1a 32-bit, 8 hex chars — not cryptographically strong, just
225
- * collision-resistant enough for in-flight wired-action correlation.
221
+ * collision-resistant enough for in-flight submit-action correlation.
226
222
  *
227
223
  * Why hash (vs. random UUID): the id reproduces from
228
224
  * `{intent, data, firedAt}` so both the silent context-update AND
@@ -312,8 +308,8 @@ function ProbeButtonRow({ method, description, call, }) {
312
308
  const args = params
313
309
  .arguments ?? {};
314
310
  // New gesture-envelope shape (SPEC §4.6): `{kind, payload,
315
- // renderId, appId, actionId, firedAt}`. For Pattern β the
316
- // `payload` carries `{intent, data}`.
311
+ // sessionId, appId, actionId, firedAt}`. For dispatch
312
+ // gestures the `payload` carries `{intent, data}`.
317
313
  const payload = args['payload'] ?? {};
318
314
  const intent = String(payload['intent'] ?? '?');
319
315
  const data = payload['data'];
@@ -420,7 +416,7 @@ export function ProtocolProbeCard({ intent, }) {
420
416
  }, children: [_jsx(Heading, { level: 3, children: "MCP Apps protocol probe" }), _jsx(Badge, { variant: "info", children: "diagnostic" })] }), _jsxs(Text, { style: {
421
417
  color: 'var(--ggui-color-onSurfaceVariant, #52525b)',
422
418
  lineHeight: '1.55',
423
- }, children: ["One button per primary host effect emitted by the iframe runtime's gesture surfaces (Pattern \u03B1 / Pattern \u03B2 / native- idiom interceptors). Click each to verify which methods this host honors. The", _jsx("code", { children: "tools/call" }), " row chains the full Pattern \u03B2 bridge (audit + context + consent), reproducing the production", _jsx("code", { children: "dispatchWiredAction" }), " envelope shape verbatim. The receive log below captures every notification the host emits while this card is mounted."] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(ProbeButtonRow, { method: "ui/message", description: "Pattern \u03B2 step 3 \u2014 consent-gated user authorization. Host pre-fills + waits for user confirm before the LLM acts on the paired pending-action context.", call: call }), _jsx(ProbeButtonRow, { method: "ui/update-model-context", description: "Pattern \u03B2 step 2 \u2014 silent structured `[ggui:pending-action]` context drop. LLM honors on next turn. No immediate UI.", call: call }), _jsx(ProbeButtonRow, { method: "ui/open-link", description: "Native-idiom anchor click interceptor primary effect. Opens ggui.ai in the host's browser / new tab. Real iframe code triggers via `<a href target='_blank'>` or cross-origin href.", call: call }), _jsx(ProbeButtonRow, { method: "ui/request-display-mode", description: "Native-idiom fullscreen interceptor primary effect. Request fullscreen \u2014 real iframe code calls `el.requestFullscreen()`; the runtime overrides the prototype to route through here.", call: call }), _jsx(ProbeButtonRow, { method: "tools/call", description: "Pattern \u03B2 full bridge: `tools/call ggui_runtime_submit_action` (audit, kind:'dispatch') + `ui/update-model-context` + `ui/message`. Spec \u00A7401 requires `_meta.ui.visibility:['app']` on the receiving tool. Pattern \u03B1 (direct fire to a same-server app-visible target) would skip steps 2+3 and add a second `tools/call` to the target tool instead.", call: call })] }), _jsxs(Stack, { gap: "sm", children: [_jsxs("div", { style: {
419
+ }, children: ["One button per primary host effect emitted by the iframe runtime's gesture surfaces (submit-action bridge / native- idiom interceptors). Click each to verify which methods this host honors. The", _jsx("code", { children: "tools/call" }), " row chains the full submit-action bridge (audit + context + consent), reproducing the production ", _jsx("code", { children: "dispatchSubmitAction" }), " envelope shape verbatim. The receive log below captures every notification the host emits while this card is mounted."] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(ProbeButtonRow, { method: "ui/message", description: "Submit-action bridge step 3 \u2014 consent-gated user authorization. Host pre-fills + waits for user confirm before the LLM acts on the paired pending-action context.", call: call }), _jsx(ProbeButtonRow, { method: "ui/update-model-context", description: "Submit-action bridge step 2 \u2014 silent structured `[ggui:pending-action]` context drop. LLM honors on next turn. No immediate UI.", call: call }), _jsx(ProbeButtonRow, { method: "ui/open-link", description: "Native-idiom anchor click interceptor primary effect. Opens ggui.ai in the host's browser / new tab. Real iframe code triggers via `<a href target='_blank'>` or cross-origin href.", call: call }), _jsx(ProbeButtonRow, { method: "ui/request-display-mode", description: "Native-idiom fullscreen interceptor primary effect. Request fullscreen \u2014 real iframe code calls `el.requestFullscreen()`; the runtime overrides the prototype to route through here.", call: call }), _jsx(ProbeButtonRow, { method: "tools/call", description: "Full submit-action bridge: `tools/call ggui_runtime_submit_action` (audit, kind:'dispatch') + `ui/update-model-context` + `ui/message`. Spec \u00A7401 requires `_meta.ui.visibility:['app']` on the receiving tool.", call: call })] }), _jsxs(Stack, { gap: "sm", children: [_jsxs("div", { style: {
424
420
  display: 'flex',
425
421
  alignItems: 'baseline',
426
422
  justifyContent: 'space-between',
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * System-card registry.
3
3
  *
4
- * Central mapping from `SystemRender.kind` (a stable wire string)
4
+ * Central mapping from `SystemGguiSession.kind` (a stable wire string)
5
5
  * to a real React component bundled inside the iframe-runtime. The
6
6
  * runtime's self-contained boot path looks up the kind here when it
7
7
  * sees a render with `type: 'system'`. Unknown kinds fall through
@@ -13,7 +13,7 @@
13
13
  * 1. Author `MyNewCard.tsx` in this directory.
14
14
  * 2. Add an entry to {@link SYSTEM_CARD_REGISTRY} below.
15
15
  * 3. (Optional) Add the new kind string to
16
- * `SystemRenderKind` in `@ggui-ai/protocol` for IDE autocomplete.
16
+ * `SystemGguiSessionKind` in `@ggui-ai/protocol` for IDE autocomplete.
17
17
  */
18
18
  import * as React from 'react';
19
19
  import { NoCredentialsCard, type NoCredentialsCardProps } from './NoCredentialsCard.js';
@@ -28,7 +28,7 @@ import { ProtocolProbeCard, type ProtocolProbeCardProps } from './ProtocolProbeC
28
28
  export type SystemCardComponent = React.ComponentType<Record<string, unknown>>;
29
29
  /**
30
30
  * Registered system-card kinds. Keep keys aligned with
31
- * `SystemRenderKind` in `@ggui-ai/protocol` so wire + bundle stay
31
+ * `SystemGguiSessionKind` in `@ggui-ai/protocol` so wire + bundle stay
32
32
  * in sync. New kinds added without a registry entry render as
33
33
  * {@link UnknownSystemCard}.
34
34
  */
@@ -39,8 +39,8 @@ export declare const SYSTEM_CARD_REGISTRY: Record<string, SystemCardComponent>;
39
39
  */
40
40
  export declare function renderSystemCard(kind: string, props: Record<string, unknown>): React.ReactElement;
41
41
  /**
42
- * Top-level mount component the runtime renders for system stack
43
- * items. Wraps the resolved card in a {@link ThemeProvider} so design
42
+ * Top-level mount component the runtime renders for system
43
+ * renders. Wraps the resolved card in a {@link ThemeProvider} so design
44
44
  * tokens (`var(--ggui-*)`) resolve at `:root` even though the host's
45
45
  * shell HTML doesn't pre-stamp them. Idempotent across remounts —
46
46
  * shares the `ggui-theme-vars` style id with the rest of the design
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * System-card registry.
3
3
  *
4
- * Central mapping from `SystemRender.kind` (a stable wire string)
4
+ * Central mapping from `SystemGguiSession.kind` (a stable wire string)
5
5
  * to a real React component bundled inside the iframe-runtime. The
6
6
  * runtime's self-contained boot path looks up the kind here when it
7
7
  * sees a render with `type: 'system'`. Unknown kinds fall through
@@ -13,7 +13,7 @@
13
13
  * 1. Author `MyNewCard.tsx` in this directory.
14
14
  * 2. Add an entry to {@link SYSTEM_CARD_REGISTRY} below.
15
15
  * 3. (Optional) Add the new kind string to
16
- * `SystemRenderKind` in `@ggui-ai/protocol` for IDE autocomplete.
16
+ * `SystemGguiSessionKind` in `@ggui-ai/protocol` for IDE autocomplete.
17
17
  */
18
18
  import * as React from 'react';
19
19
  import { ThemeProvider, lightTheme, darkTheme } from '@ggui-ai/design/themes';
@@ -64,7 +64,7 @@ function UnknownSystemCard({ kind, props, }) {
64
64
  }
65
65
  /**
66
66
  * Registered system-card kinds. Keep keys aligned with
67
- * `SystemRenderKind` in `@ggui-ai/protocol` so wire + bundle stay
67
+ * `SystemGguiSessionKind` in `@ggui-ai/protocol` so wire + bundle stay
68
68
  * in sync. New kinds added without a registry entry render as
69
69
  * {@link UnknownSystemCard}.
70
70
  */
@@ -96,8 +96,8 @@ export function renderSystemCard(kind, props) {
96
96
  return React.createElement(UnknownSystemCard, { kind, props });
97
97
  }
98
98
  /**
99
- * Top-level mount component the runtime renders for system stack
100
- * items. Wraps the resolved card in a {@link ThemeProvider} so design
99
+ * Top-level mount component the runtime renders for system
100
+ * renders. Wraps the resolved card in a {@link ThemeProvider} so design
101
101
  * tokens (`var(--ggui-*)`) resolve at `:root` even though the host's
102
102
  * shell HTML doesn't pre-stamp them. Idempotent across remounts —
103
103
  * shares the `ggui-theme-vars` style id with the rest of the design
package/dist/types.d.ts CHANGED
@@ -15,42 +15,33 @@
15
15
  * declared the manager's constructor bag has been retired.
16
16
  */
17
17
  import type { McpAppAiGguiRenderMeta } from '@ggui-ai/protocol/integrations/mcp-apps';
18
- import type { HostContextProjection, ComponentRender, SystemRender } from '@ggui-ai/protocol';
19
- /**
20
- * Post-Phase-B alias kept for ergonomic call sites — the wire-side
21
- * `McpAppAiGguiRenderMeta` is the single source of truth, and the
22
- * "validated" qualifier is a no-op now (no nested-optional-session
23
- * narrowing left after the slice merge). Future callers SHOULD prefer
24
- * `McpAppAiGguiRenderMeta` directly; the alias persists so the rename
25
- * sweep can land incrementally without churn at every call site.
26
- */
27
- export type ValidatedMcpAppAiGguiMeta = McpAppAiGguiRenderMeta;
18
+ import type { HostContextProjection, ComponentGguiSession, SystemGguiSession } from '@ggui-ai/protocol';
28
19
  /**
29
20
  * The four server-assigned ledger fields on every wire-delivered
30
- * {@link Render}. They're stamped by the server's per-render event
21
+ * {@link GguiSession}. They're stamped by the server's per-render event
31
22
  * ledger — NOT derivable from the inline `__GGUI_META__` bootstrap.
32
23
  */
33
- type RenderLedgerFields = 'eventSequence' | 'createdAt' | 'lastActivityAt' | 'expiresAt';
24
+ type GguiSessionLedgerFields = 'eventSequence' | 'createdAt' | 'lastActivityAt' | 'expiresAt';
34
25
  /**
35
26
  * The mount surface's INPUT contract — what `mountRender` / `applyRender`
36
- * accept. It is a {@link Render} minus the four server-assigned ledger
37
- * fields ({@link RenderLedgerFields}), so the runtime can mount the
27
+ * accept. It is a {@link GguiSession} minus the four server-assigned ledger
28
+ * fields ({@link GguiSessionLedgerFields}), so the runtime can mount the
38
29
  * compiled component (or system card) carried inline by the resource
39
- * shell BEFORE the authoritative wire `Render` arrives over the WS.
30
+ * shell BEFORE the authoritative wire `GguiSession` arrives over the WS.
40
31
  *
41
- * A full `Render` is assignable to `RenderSeedInput` (it carries every
32
+ * A full `GguiSession` is assignable to `GguiSessionSeedInput` (it carries every
42
33
  * field plus the ledger), so the WS-ack reconcile path passes a real
43
- * `Render` here unchanged; the inline-seed path passes the projection
44
- * built by `buildRenderSeedInput`. We do NOT fabricate the ledger fields
34
+ * `GguiSession` here unchanged; the inline-seed path passes the projection
35
+ * built by `buildGguiSessionSeedInput`. We do NOT fabricate the ledger fields
45
36
  * (Strict-Typing-First / no-type-laundering) — the first ack replaces
46
- * the seed with the authoritative `Render`.
37
+ * the seed with the authoritative `GguiSession`.
47
38
  *
48
- * Carries the SAME contract-spec fields a full `ComponentRender` does
39
+ * Carries the SAME contract-spec fields a full `ComponentGguiSession` does
49
40
  * (`propsSpec` / `streamSpec` / `actionSpec`), as `undefined` on a
50
41
  * seed — so the channel handlers that read those after the
51
42
  * `type !== 'mcpApps' && type !== 'system'` narrowing stay type-clean.
52
43
  */
53
- export type RenderSeedInput = Omit<ComponentRender, RenderLedgerFields> | Omit<SystemRender, RenderLedgerFields>;
44
+ export type GguiSessionSeedInput = Omit<ComponentGguiSession, GguiSessionLedgerFields> | Omit<SystemGguiSession, GguiSessionLedgerFields>;
54
45
  /**
55
46
  * Why a slice-meta parse can fail. Closed union — every value is a
56
47
  * canonical reason the renderer surfaces to the host via postMessage.
@@ -60,13 +51,16 @@ export type RenderSeedInput = Omit<ComponentRender, RenderLedgerFields> | Omit<S
60
51
  * `CSP_VIOLATION`, etc) live on the broader `BootstrapFailureReason`
61
52
  * union in `protocol-error.ts`. The four parse-time outcomes:
62
53
  *
63
- * - `MISSING_TOOL_OUTPUT` — host echoed `ui/initialize` without a
64
- * `result.toolOutput` object at all.
65
- * - `MISSING_META_GGUI_BOOTSTRAP` — `result.toolOutput` exists but
66
- * `_meta["ai.ggui/render"]` is absent. The on-wire synonym is
67
- * `BOOTSTRAP_META_MISSING`. (Name retained pre-R4 for the
68
- * observability + host-postMessage protocol; cosmetic rename is
54
+ * - `MISSING_TOOL_OUTPUT` — the tool-result notification's `params`
55
+ * was not an object (no `CallToolResult` to read). (Name predates
56
+ * the spec-canonical top-level `_meta` reading; retained for the
57
+ * observability + host-postMessage protocol — cosmetic rename is
69
58
  * deferred.)
59
+ * - `MISSING_META_GGUI_BOOTSTRAP` — `params` is an object but
60
+ * `params._meta` is absent or carries no `ai.ggui/render` slice.
61
+ * The on-wire synonym is `BOOTSTRAP_META_MISSING`. (Name retained
62
+ * pre-R4 for the observability + host-postMessage protocol;
63
+ * cosmetic rename is deferred.)
70
64
  * - `MALFORMED_BOOTSTRAP` — slice is present but fails business
71
65
  * rules (no live mode and no static content, mode discriminators
72
66
  * mutually exclusive, structural rejection by the combiner).
@@ -81,17 +75,18 @@ export type McpAppAiGguiMetaParseFailureReason = 'MISSING_TOOL_OUTPUT' | 'MISSIN
81
75
  * bundle).
82
76
  *
83
77
  * The `ok: true` arm carries the validated {@link McpAppAiGguiRenderMeta}
84
- * slice and optionally a `hostContext: HostContextProjection`. When the
85
- * meta is extracted from the `ui/initialize` response (Reading-A path),
86
- * the parser opportunistically projects the surrounding
87
- * `McpUiHostContext` into this field so the runtime can:
88
- * - drive canvas-mode display-mode escalation
78
+ * slice and optionally a `hostContext: HostContextProjection`. The
79
+ * producer is the boot path in `runtime.ts`, which projects
80
+ * `app.getHostContext()` (the App class's spec-canonical
81
+ * `ui/initialize` capture plus its `hostcontextchanged` listener)
82
+ * into this field so the runtime can:
83
+ * - drive display-mode escalation (MCP Apps inline/fullscreen/pip)
89
84
  * - echo to the server (live-channel `host_context_observed` envelope)
90
85
  * - feed the agent on next handshake/consume
91
86
  *
92
87
  * Capture is best-effort: a malformed `HostContext` never blocks the
93
- * slice parse. Absent for the other extraction paths
94
- * (`__GGUI_META__` global, `ui/notifications/tool-result`) — those
88
+ * slice parse. The envelope extractors themselves (`__GGUI_META__`
89
+ * global, `ui/notifications/tool-result`) never populate it — those
95
90
  * envelopes don't carry HostContext.
96
91
  */
97
92
  export type McpAppAiGguiMetaParseResult = {
@@ -30,9 +30,8 @@ import type { ActionSpec, ActionEnvelope, ContextSpec, JsonObject, PropsSpec, Re
30
30
  import type { CompiledValidatorSet } from './compiled-validators.js';
31
31
  /**
32
32
  * Install the precompiled validators loaded from the bootstrap. Called
33
- * once per boot (both `bootProduction` and `bootSelfContained`), after
34
- * the bootstrap is parsed. A single set per iframe document — one
35
- * session, one active contract.
33
+ * once per boot (by `bootSequence`), after the bootstrap is parsed. A
34
+ * single set per iframe document — one render, one active contract.
36
35
  */
37
36
  export declare function setActiveValidatorSet(set: CompiledValidatorSet | undefined): void;
38
37
  /**
@@ -69,8 +68,8 @@ export declare function validateOutboundActionEnvelope(actionSpec: ActionSpec |
69
68
  */
70
69
  export declare function validateInboundStreamPayload(streamSpec: StreamSpec | undefined, channelName: string, payload: unknown, ctx: RendererValidatorContext): ValidationResult;
71
70
  /**
72
- * Validate an inbound `props_update` payload before patching a stack
73
- * item's props. Server already runs `assertPropsContract` on the emit
71
+ * Validate an inbound `props_update` payload before patching a
72
+ * render's props. Server already runs `assertPropsContract` on the emit
74
73
  * path; this client-side revalidation is defense-in-depth for
75
74
  * spec-versioning drift (server snapshot ≠ client cached spec).
76
75
  */
@@ -3,16 +3,15 @@ import { isKnownReservedChannel, validateActionEnvelope, validateContextData, va
3
3
  // Active precompiled-validator set
4
4
  // =============================================================================
5
5
  /**
6
- * Boot-installed precompiled validators for the active stack item's
6
+ * Boot-installed precompiled validators for the active render's
7
7
  * contract. `undefined` until {@link setActiveValidatorSet} runs (and
8
8
  * in unit tests, which exercise the in-iframe compilation fallback).
9
9
  */
10
10
  let activeValidatorSet;
11
11
  /**
12
12
  * Install the precompiled validators loaded from the bootstrap. Called
13
- * once per boot (both `bootProduction` and `bootSelfContained`), after
14
- * the bootstrap is parsed. A single set per iframe document — one
15
- * session, one active contract.
13
+ * once per boot (by `bootSequence`), after the bootstrap is parsed. A
14
+ * single set per iframe document — one render, one active contract.
16
15
  */
17
16
  export function setActiveValidatorSet(set) {
18
17
  activeValidatorSet = set;
@@ -86,8 +85,8 @@ export function validateInboundStreamPayload(streamSpec, channelName, payload, c
86
85
  });
87
86
  }
88
87
  /**
89
- * Validate an inbound `props_update` payload before patching a stack
90
- * item's props. Server already runs `assertPropsContract` on the emit
88
+ * Validate an inbound `props_update` payload before patching a
89
+ * render's props. Server already runs `assertPropsContract` on the emit
91
90
  * path; this client-side revalidation is defense-in-depth for
92
91
  * spec-versioning drift (server snapshot ≠ client cached spec).
93
92
  */