@ggui-ai/iframe-runtime 0.11.0 → 0.13.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.
- package/dist/host-capabilities.d.ts +6 -4
- package/dist/iframe-runtime.js +70 -60
- package/dist/iframe-runtime.meta.json +1 -1
- package/dist/mcp-app-iframe-host.js +7 -2
- package/dist/observability.d.ts +2 -7
- package/dist/react-renderer.d.ts +22 -0
- package/dist/react-renderer.js +20 -4
- package/dist/render-item.d.ts +9 -0
- package/dist/runtime.d.ts +12 -0
- package/dist/runtime.js +78 -30
- package/dist/status-dom.d.ts +9 -0
- package/dist/status-dom.js +11 -0
- package/dist/system-cards/UiFeedbackCard.d.ts +13 -8
- package/dist/system-cards/UiFeedbackCard.js +32 -41
- package/dist/ui-feedback-chrome.d.ts +46 -0
- package/dist/ui-feedback-chrome.js +42 -0
- package/dist/wire-config.d.ts +7 -3
- package/package.json +8 -8
|
@@ -36,6 +36,44 @@
|
|
|
36
36
|
* gate passes.
|
|
37
37
|
*/
|
|
38
38
|
import { createElement } from 'react';
|
|
39
|
+
/**
|
|
40
|
+
* Stacking contract between the two body-appended runtime layers
|
|
41
|
+
* (ggui#603): the feedback chrome must sit strictly ABOVE the action
|
|
42
|
+
* toast. The persistent `action_required` toast parks
|
|
43
|
+
* `pointer-events:auto` at fixed bottom-center — the same region this
|
|
44
|
+
* chrome occupies — and is re-armed per gesture; without this order an
|
|
45
|
+
* armed toast eats every tap aimed at the feedback controls. The toast
|
|
46
|
+
* remains dismissable on its own uncovered area (it accepts the click
|
|
47
|
+
* anywhere on itself), so partial occlusion costs it nothing.
|
|
48
|
+
*
|
|
49
|
+
* Single source: `runtime.ts`'s toast reads {@link ACTION_TOAST_Z_INDEX};
|
|
50
|
+
* this module applies {@link UI_FEEDBACK_CHROME_Z_INDEX} to the chrome
|
|
51
|
+
* container. The test suite pins the relationship, not the numbers.
|
|
52
|
+
*/
|
|
53
|
+
export const UI_FEEDBACK_CHROME_Z_INDEX = 2147483647;
|
|
54
|
+
export const ACTION_TOAST_Z_INDEX = 2147483646;
|
|
55
|
+
/**
|
|
56
|
+
* Pure mount decision the boot path consults before touching the DOM.
|
|
57
|
+
* Two independent gates compose:
|
|
58
|
+
*
|
|
59
|
+
* 1. **The #653 opt-in knob** — the founder's default-off ruling:
|
|
60
|
+
* generated-component cards carry NO feedback chrome unless the
|
|
61
|
+
* embedding deployment explicitly opts in (`uiFeedback: true` on
|
|
62
|
+
* the boot options). Absent or `false` ⇒ never mount, regardless
|
|
63
|
+
* of sink state.
|
|
64
|
+
* 2. **The #471 live-sink gate** — even opted in, only a parent that
|
|
65
|
+
* actually consumes the `ggui:observe` envelope gets the
|
|
66
|
+
* affordance: a bound `onObserve` emitter, or the first-party
|
|
67
|
+
* embed host. Third-party MCP-Apps hosts drop the envelope, and a
|
|
68
|
+
* feedback control that can never deliver feedback is worse than
|
|
69
|
+
* none.
|
|
70
|
+
*/
|
|
71
|
+
export function shouldMountUiFeedbackChrome(input) {
|
|
72
|
+
if (input.uiFeedback !== true)
|
|
73
|
+
return false;
|
|
74
|
+
return (input.onObserveBound ||
|
|
75
|
+
input.hostName === 'ggui-iframe-runtime-embed-host');
|
|
76
|
+
}
|
|
39
77
|
/**
|
|
40
78
|
* Mount the in-iframe UI-feedback affordance, or do nothing.
|
|
41
79
|
*
|
|
@@ -69,6 +107,10 @@ export async function mountUiFeedbackChrome(doc, opts) {
|
|
|
69
107
|
doc.querySelector('[data-ggui-ui-feedback-chrome]')?.remove();
|
|
70
108
|
const container = doc.createElement('div');
|
|
71
109
|
container.setAttribute('data-ggui-ui-feedback-chrome', '');
|
|
110
|
+
// Win the stacking race against the action toast (ggui#603 — see
|
|
111
|
+
// the constants' docblock above).
|
|
112
|
+
container.style.position = 'relative';
|
|
113
|
+
container.style.zIndex = String(UI_FEEDBACK_CHROME_Z_INDEX);
|
|
72
114
|
doc.body.appendChild(container);
|
|
73
115
|
const root = reactDomClient.createRoot(container);
|
|
74
116
|
root.render(createElement(cardMod.UiFeedbackCard, {
|
package/dist/wire-config.d.ts
CHANGED
|
@@ -95,9 +95,13 @@ export interface BuildRootWireConfigOptions {
|
|
|
95
95
|
*
|
|
96
96
|
* The default WS-frame send reaches the agent only on servers whose
|
|
97
97
|
* live channel bridges WS `data:submit` actions onto the same
|
|
98
|
-
* pending-events pipe
|
|
99
|
-
* `
|
|
100
|
-
*
|
|
98
|
+
* pending-events pipe. First-party `createGguiServer` bridges it
|
|
99
|
+
* ONLY when composed with DEFAULT handlers (`opts.handlers`
|
|
100
|
+
* undefined); a custom `handlers` list drains its own pipe, so the
|
|
101
|
+
* channel deliberately does not bridge — the hosted pod is such a
|
|
102
|
+
* caller, and on it a WS gesture lands on the retained ledger only.
|
|
103
|
+
* See `GguiSessionChannelOptions.pendingEventConsumer`. The default
|
|
104
|
+
* send remains the seam tests and direct-WS callers exercise.
|
|
101
105
|
*
|
|
102
106
|
* Called AFTER outbound validation passes. Receives the validated
|
|
103
107
|
* {@link ActionEnvelope}; caller extracts payload.action +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/iframe-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "The iframe-local ggui runtime: a self-contained ESM bundle that boots inside an MCP Apps host iframe, runs the protocol-version handshake, opens the live-channel WebSocket, and mounts the rendered UI. Bundles React, ReactDOM, and the ggui design system so generated component code has a single seam to read from.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ggui",
|
|
@@ -36,12 +36,12 @@
|
|
|
36
36
|
"react": "^19.0.0",
|
|
37
37
|
"react-dom": "^19.0.0",
|
|
38
38
|
"zod": "^4.3.6",
|
|
39
|
-
"@ggui-ai/
|
|
40
|
-
"@ggui-ai/
|
|
41
|
-
"@ggui-ai/gadgets": "0.
|
|
42
|
-
"@ggui-ai/
|
|
43
|
-
"@ggui-ai/
|
|
44
|
-
"@ggui-ai/
|
|
39
|
+
"@ggui-ai/design": "0.13.0",
|
|
40
|
+
"@ggui-ai/preview-a2ui": "0.13.0",
|
|
41
|
+
"@ggui-ai/gadgets": "0.13.0",
|
|
42
|
+
"@ggui-ai/protocol": "0.13.0",
|
|
43
|
+
"@ggui-ai/wire": "0.13.0",
|
|
44
|
+
"@ggui-ai/live-channel": "0.13.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@modelcontextprotocol/sdk": "^1.27.0"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
"author": "ggui contributors <hello@ggui.ai>",
|
|
77
77
|
"scripts": {
|
|
78
|
-
"build": "rm -rf dist && node esbuild.config.mjs &&
|
|
78
|
+
"build": "rm -rf dist.staging && tsc -p tsconfig.types.json --outDir dist.staging && GGUI_ESBUILD_OUT_DIR=dist.staging node esbuild.config.mjs && node ../scripts/atomic-swap.mjs dist.staging dist && pnpm run check:bundle-size",
|
|
79
79
|
"check:bundle-size": "tsx scripts/check-bundle-size.ts",
|
|
80
80
|
"check:bundle-size:self-test": "tsx scripts/check-bundle-size.ts --self-test",
|
|
81
81
|
"typecheck": "tsc --noEmit",
|