@ggui-ai/iframe-runtime 0.12.0 → 0.14.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/connection.d.ts +20 -0
- package/dist/connection.js +20 -0
- package/dist/iframe-runtime.js +93 -91
- package/dist/iframe-runtime.meta.json +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/observability.d.ts +129 -21
- package/dist/observability.js +59 -0
- package/dist/react-renderer.d.ts +2 -5
- package/dist/react-renderer.js +20 -4
- package/dist/render-item.d.ts +2 -6
- package/dist/runtime.d.ts +31 -0
- package/dist/runtime.js +266 -65
- 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 +30 -0
- package/dist/ui-feedback-chrome.js +22 -0
- package/dist/wire-config.js +9 -3
- package/package.json +15 -10
package/dist/index.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export { parseMetaFromGlobal, parseMetaFromToolResult, validateMeta, } from './m
|
|
|
37
37
|
export type { RendererBootFailureReason, RendererBootFailedMessage, } from './runtime.js';
|
|
38
38
|
export type { ProtocolError, ProtocolErrorEmitter, BootstrapFailureReason, } from './protocol-error.js';
|
|
39
39
|
export { defaultProtocolErrorEmitter, fromBootstrapFailure, fromClientContractViolation, fromTransportFailure, fromAuthFailure, fromUpgradeRequired, fromUnknown, } from './protocol-error.js';
|
|
40
|
-
export type { ObservabilityEvent, ObservabilityEmitter, ObservabilityMessage, SchemaVersionMismatchEvent, SubscribeFailedEvent, ChannelTransportPickedEvent, ChannelTransportFallbackEvent, ChannelTransportResubscribedEvent, ChannelPollDegradedEvent, ChannelPollRecoveredEvent, UiFeedbackEvent, RelayIncapabilityEvent, UnknownObservabilityEvent, } from './observability.js';
|
|
41
|
-
export { postObservabilityToParent } from './observability.js';
|
|
40
|
+
export type { ObservabilityEvent, ObservabilityEmitter, ObservabilityMessage, SchemaVersionMismatchEvent, SubscribeFailedEvent, ChannelTransportPickedEvent, ChannelTransportFallbackEvent, ChannelTransportResubscribedEvent, ChannelPollDegradedEvent, ChannelPollRecoveredEvent, UiFeedbackEvent, RelayDeadTapEvent, RelayIncapabilityEvent, RelayLatchTrigger, UnknownObservabilityEvent, } from './observability.js';
|
|
41
|
+
export { isObservabilityMessage, isRelayDeadTapEvent, isRelayIncapabilityEvent, postObservabilityToParent, } from './observability.js';
|
|
42
42
|
export type { LifecycleEmitter } from './lifecycle.js';
|
|
43
43
|
export { postLifecycleToParent, makeLifecycleEvent } from './lifecycle.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { parseMetaFromGlobal, parseMetaFromToolResult, validateMeta, } from './meta-parse.js';
|
|
2
2
|
export { defaultProtocolErrorEmitter, fromBootstrapFailure, fromClientContractViolation, fromTransportFailure, fromAuthFailure, fromUpgradeRequired, fromUnknown, } from './protocol-error.js';
|
|
3
|
-
export { postObservabilityToParent } from './observability.js';
|
|
3
|
+
export { isObservabilityMessage, isRelayDeadTapEvent, isRelayIncapabilityEvent, postObservabilityToParent, } from './observability.js';
|
|
4
4
|
export { postLifecycleToParent, makeLifecycleEvent } from './lifecycle.js';
|
package/dist/observability.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ import { MCP_APP_OBSERVE_TYPE } from '@ggui-ai/protocol/integrations/mcp-apps';
|
|
|
33
33
|
*
|
|
34
34
|
* @public
|
|
35
35
|
*/
|
|
36
|
-
export type ObservabilityEvent = SchemaVersionMismatchEvent | SubscribeFailedEvent | ChannelTransportPickedEvent | ChannelTransportFallbackEvent | ChannelTransportResubscribedEvent | ChannelPollDegradedEvent | ChannelPollRecoveredEvent | UiFeedbackEvent | RelayIncapabilityEvent | UnknownObservabilityEvent;
|
|
36
|
+
export type ObservabilityEvent = SchemaVersionMismatchEvent | SubscribeFailedEvent | ChannelTransportPickedEvent | ChannelTransportFallbackEvent | ChannelTransportResubscribedEvent | ChannelPollDegradedEvent | ChannelPollRecoveredEvent | UiFeedbackEvent | RelayIncapabilityEvent | RelayDeadTapEvent | UnknownObservabilityEvent;
|
|
37
37
|
/**
|
|
38
38
|
* Fired when the protocol-version handshake rejects the connection.
|
|
39
39
|
* Parallel to `UpgradeRequiredError` — the host can choose to render
|
|
@@ -151,10 +151,7 @@ export interface ChannelPollRecoveredEvent {
|
|
|
151
151
|
* mirror `UiFeedbackPayload` in `@ggui-ai/mcp-apps-react` / `@ggui-ai/mcp-apps-react-native`
|
|
152
152
|
* (the host-chrome twin of this affordance):
|
|
153
153
|
*
|
|
154
|
-
* - `verdict` — `'
|
|
155
|
-
* free-text flow.
|
|
156
|
-
* - `comment` — present only for `verdict: 'other'` with a non-empty
|
|
157
|
-
* trimmed comment.
|
|
154
|
+
* - `verdict` — `'up'` / `'down'` (the two thumb verdicts, #653).
|
|
158
155
|
* - `sessionId` / `toolName` — present exactly when the runtime knew
|
|
159
156
|
* them at mount time.
|
|
160
157
|
*
|
|
@@ -175,34 +172,47 @@ export interface ChannelPollRecoveredEvent {
|
|
|
175
172
|
*/
|
|
176
173
|
export interface UiFeedbackEvent {
|
|
177
174
|
readonly kind: 'ui-feedback';
|
|
178
|
-
readonly verdict: '
|
|
179
|
-
/** Trimmed free-text comment; only on `verdict: 'other'`, never empty. */
|
|
180
|
-
readonly comment?: string;
|
|
175
|
+
readonly verdict: 'up' | 'down';
|
|
181
176
|
/** GguiSession id of the render the feedback is about. */
|
|
182
177
|
readonly sessionId?: string;
|
|
183
178
|
/** Tool that produced the render (e.g. `ggui_render`). */
|
|
184
179
|
readonly toolName?: string;
|
|
185
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* The evidence that latched a relay dead zone (ggui#599 cycle-2):
|
|
183
|
+
* `'confirmed-refusal'` — the relay answered a declared refusal code
|
|
184
|
+
* (helper-minted; outranks any positive advertisement), vs
|
|
185
|
+
* `'advert-silent'` — the host never advertised `serverTools` and the
|
|
186
|
+
* attempt failed relay-shaped.
|
|
187
|
+
*
|
|
188
|
+
* @public
|
|
189
|
+
*/
|
|
190
|
+
export type RelayLatchTrigger = 'confirmed-refusal' | 'advert-silent';
|
|
186
191
|
/**
|
|
187
192
|
* Fired at the two transition edges of the renderer's
|
|
188
193
|
* relay-incapability latch — the runtime's confirmed determination
|
|
189
194
|
* that the host cannot relay `tools/call` to the MCP server:
|
|
190
195
|
*
|
|
191
|
-
* - `'latched'` — a real user gesture just failed relay-shaped
|
|
192
|
-
*
|
|
193
|
-
*
|
|
196
|
+
* - `'latched'` — a real user gesture just failed relay-shaped on a
|
|
197
|
+
* host whose captured capability handshake never advertised
|
|
198
|
+
* `serverTools`, or the relay answered a declared refusal code.
|
|
194
199
|
* The runtime now treats relay as confirmed-unavailable: it shows
|
|
195
|
-
* one persistent explanation
|
|
196
|
-
* and channel polls fail fast without a transport
|
|
200
|
+
* one persistent explanation, arms the dead-zone cue for every
|
|
201
|
+
* later gesture, and channel polls fail fast without a transport
|
|
202
|
+
* round-trip.
|
|
197
203
|
* - `'cleared'` — a later well-formed result envelope arrived
|
|
198
204
|
* (`ok:true` and `ok:false` alike — either proves the host relayed
|
|
199
|
-
* the call there and back), so the determination no longer holds
|
|
200
|
-
*
|
|
205
|
+
* the call there and back), so the determination no longer holds.
|
|
206
|
+
* Carries the dead zone's summary: how long it stood and how many
|
|
207
|
+
* gestures were attempted inside it.
|
|
201
208
|
*
|
|
202
|
-
* Emitted once per edge, never per channel poll tick
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
209
|
+
* Emitted once per edge, never per channel poll tick. Gestures
|
|
210
|
+
* attempted while latched are NOT silent on this stream: each one is a
|
|
211
|
+
* {@link RelayDeadTapEvent} (ggui#670 Phase 3) — one per real user
|
|
212
|
+
* gesture, never per tick — so a host can count dead taps and measure
|
|
213
|
+
* dead-tap-to-recovery without watching the render. A boot that finds
|
|
214
|
+
* a latch standing from a prior mount closes it with a `'cleared'`
|
|
215
|
+
* edge before the new session starts.
|
|
206
216
|
*
|
|
207
217
|
* Always emitted via the postMessage-to-parent default — the emission
|
|
208
218
|
* sites live in module-level gesture-dispatch code outside the boot
|
|
@@ -210,9 +220,61 @@ export interface UiFeedbackEvent {
|
|
|
210
220
|
*
|
|
211
221
|
* @public
|
|
212
222
|
*/
|
|
213
|
-
export
|
|
223
|
+
export type RelayIncapabilityEvent = {
|
|
214
224
|
readonly kind: 'relay-incapability';
|
|
215
|
-
readonly state: 'latched'
|
|
225
|
+
readonly state: 'latched';
|
|
226
|
+
readonly trigger: RelayLatchTrigger;
|
|
227
|
+
/** GguiSession id of the render, when the latching gesture carried one. */
|
|
228
|
+
readonly sessionId?: string;
|
|
229
|
+
/** App id of the render, when the latching gesture carried one. */
|
|
230
|
+
readonly appId?: string;
|
|
231
|
+
} | {
|
|
232
|
+
readonly kind: 'relay-incapability';
|
|
233
|
+
readonly state: 'cleared';
|
|
234
|
+
/** How long the dead zone stood, in milliseconds. */
|
|
235
|
+
readonly latchedForMs: number;
|
|
236
|
+
/**
|
|
237
|
+
* Gestures attempted inside the zone — equals the last
|
|
238
|
+
* {@link RelayDeadTapEvent} `ordinal` this edge closes (0 when
|
|
239
|
+
* none was attempted).
|
|
240
|
+
*/
|
|
241
|
+
readonly deadTaps: number;
|
|
242
|
+
readonly sessionId?: string;
|
|
243
|
+
readonly appId?: string;
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* A user gesture attempted while the relay-incapability latch stands
|
|
247
|
+
* (ggui#670 Phase 3). The runtime never suppresses the attempt — the
|
|
248
|
+
* attempt is the self-heal sensor (ggui#443) — and presents it in the
|
|
249
|
+
* document (pulse, spoken cue, fallback toast); this event makes the
|
|
250
|
+
* attempt COUNTABLE by the host.
|
|
251
|
+
*
|
|
252
|
+
* Contract: exactly one per gesture attempted while latched whose
|
|
253
|
+
* attempt comes back undelivered (relay-shaped failure or a declared
|
|
254
|
+
* refusal); never emitted off-latch, and never from the channel
|
|
255
|
+
* router's fail-fast ticks. Counted at the outcome, not the tap: the
|
|
256
|
+
* gesture that latched the zone is the `'latched'` edge and the gesture
|
|
257
|
+
* that heals it is the `'cleared'` edge — neither is a dead tap.
|
|
258
|
+
* `ordinal` counts from 1 within one dead zone; the `'cleared'` edge
|
|
259
|
+
* reports the total as `deadTaps`. `latchAgeMs` is measured when the
|
|
260
|
+
* outcome lands. Hosts MUST tolerate the event being absent (an older
|
|
261
|
+
* renderer) — absence means no attempt was observed, not that none
|
|
262
|
+
* happened.
|
|
263
|
+
*
|
|
264
|
+
* @public
|
|
265
|
+
*/
|
|
266
|
+
export interface RelayDeadTapEvent {
|
|
267
|
+
readonly kind: 'relay-dead-tap';
|
|
268
|
+
/** The gesture's intent — the action name the component dispatched. */
|
|
269
|
+
readonly intent: string;
|
|
270
|
+
/** Milliseconds since the latch set. */
|
|
271
|
+
readonly latchAgeMs: number;
|
|
272
|
+
/** 1-based position of this attempt within the current dead zone. */
|
|
273
|
+
readonly ordinal: number;
|
|
274
|
+
/** The evidence that latched the zone this attempt landed in. */
|
|
275
|
+
readonly trigger: RelayLatchTrigger;
|
|
276
|
+
readonly sessionId?: string;
|
|
277
|
+
readonly appId?: string;
|
|
216
278
|
}
|
|
217
279
|
/**
|
|
218
280
|
* Catch-all branch for event kinds the host's typings don't recognize.
|
|
@@ -250,6 +312,52 @@ export interface ObservabilityMessage {
|
|
|
250
312
|
* @public
|
|
251
313
|
*/
|
|
252
314
|
export type ObservabilityEmitter = (event: ObservabilityEvent) => void;
|
|
315
|
+
/**
|
|
316
|
+
* Type guard for the `ggui:observe` envelope as it arrives on a host's
|
|
317
|
+
* `message` listener — narrows `event.data` to {@link ObservabilityMessage}.
|
|
318
|
+
* Read fields through the per-kind guards, never through
|
|
319
|
+
* `switch (event.kind)`: the union's open tail (`kind: string & {}`)
|
|
320
|
+
* keeps TypeScript from using `kind` as a discriminant, so a `case`
|
|
321
|
+
* body sees the whole union. Unknown kinds stay in that tail: hosts
|
|
322
|
+
* MUST ignore them, never throw.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* import {
|
|
327
|
+
* isObservabilityMessage,
|
|
328
|
+
* isRelayDeadTapEvent,
|
|
329
|
+
* isRelayIncapabilityEvent,
|
|
330
|
+
* } from '@ggui-ai/iframe-runtime/observability';
|
|
331
|
+
*
|
|
332
|
+
* window.addEventListener('message', ({ data, source }) => {
|
|
333
|
+
* if (source !== iframe.contentWindow || !isObservabilityMessage(data)) return;
|
|
334
|
+
* const { event } = data;
|
|
335
|
+
* if (isRelayDeadTapEvent(event)) count(event.intent, event.latchAgeMs);
|
|
336
|
+
* else if (isRelayIncapabilityEvent(event) && event.state === 'cleared') recovered(event.deadTaps);
|
|
337
|
+
* // any other kind: ignore
|
|
338
|
+
* });
|
|
339
|
+
* ```
|
|
340
|
+
*
|
|
341
|
+
* @public
|
|
342
|
+
*/
|
|
343
|
+
export declare function isObservabilityMessage(value: unknown): value is ObservabilityMessage;
|
|
344
|
+
/**
|
|
345
|
+
* Narrows to {@link RelayDeadTapEvent}. The union's open tail
|
|
346
|
+
* (`kind: string & {}`) keeps TypeScript from using `kind` as a
|
|
347
|
+
* discriminant, so `switch (event.kind)` never narrows across
|
|
348
|
+
* {@link ObservabilityEvent} — hosts read fields through the per-kind
|
|
349
|
+
* guards (first-consumer finding, ggui#670 Phase 3).
|
|
350
|
+
*
|
|
351
|
+
* @public
|
|
352
|
+
*/
|
|
353
|
+
export declare function isRelayDeadTapEvent(event: ObservabilityEvent): event is RelayDeadTapEvent;
|
|
354
|
+
/**
|
|
355
|
+
* Narrows to {@link RelayIncapabilityEvent}; inside it `state`
|
|
356
|
+
* discriminates the `'latched'` / `'cleared'` edges normally.
|
|
357
|
+
*
|
|
358
|
+
* @public
|
|
359
|
+
*/
|
|
360
|
+
export declare function isRelayIncapabilityEvent(event: ObservabilityEvent): event is RelayIncapabilityEvent;
|
|
253
361
|
/**
|
|
254
362
|
* Default emitter — posts an {@link ObservabilityMessage} to
|
|
255
363
|
* `window.parent`. Mirrors `postBootFailure` / `postRendererReady`
|
package/dist/observability.js
CHANGED
|
@@ -1,4 +1,63 @@
|
|
|
1
1
|
import { MCP_APP_OBSERVE_TYPE } from '@ggui-ai/protocol/integrations/mcp-apps';
|
|
2
|
+
/**
|
|
3
|
+
* Type guard for the `ggui:observe` envelope as it arrives on a host's
|
|
4
|
+
* `message` listener — narrows `event.data` to {@link ObservabilityMessage}.
|
|
5
|
+
* Read fields through the per-kind guards, never through
|
|
6
|
+
* `switch (event.kind)`: the union's open tail (`kind: string & {}`)
|
|
7
|
+
* keeps TypeScript from using `kind` as a discriminant, so a `case`
|
|
8
|
+
* body sees the whole union. Unknown kinds stay in that tail: hosts
|
|
9
|
+
* MUST ignore them, never throw.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import {
|
|
14
|
+
* isObservabilityMessage,
|
|
15
|
+
* isRelayDeadTapEvent,
|
|
16
|
+
* isRelayIncapabilityEvent,
|
|
17
|
+
* } from '@ggui-ai/iframe-runtime/observability';
|
|
18
|
+
*
|
|
19
|
+
* window.addEventListener('message', ({ data, source }) => {
|
|
20
|
+
* if (source !== iframe.contentWindow || !isObservabilityMessage(data)) return;
|
|
21
|
+
* const { event } = data;
|
|
22
|
+
* if (isRelayDeadTapEvent(event)) count(event.intent, event.latchAgeMs);
|
|
23
|
+
* else if (isRelayIncapabilityEvent(event) && event.state === 'cleared') recovered(event.deadTaps);
|
|
24
|
+
* // any other kind: ignore
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export function isObservabilityMessage(value) {
|
|
31
|
+
if (typeof value !== 'object' || value === null)
|
|
32
|
+
return false;
|
|
33
|
+
const probe = value;
|
|
34
|
+
if (probe.type !== MCP_APP_OBSERVE_TYPE)
|
|
35
|
+
return false;
|
|
36
|
+
if (typeof probe.event !== 'object' || probe.event === null)
|
|
37
|
+
return false;
|
|
38
|
+
return typeof probe.event.kind === 'string';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Narrows to {@link RelayDeadTapEvent}. The union's open tail
|
|
42
|
+
* (`kind: string & {}`) keeps TypeScript from using `kind` as a
|
|
43
|
+
* discriminant, so `switch (event.kind)` never narrows across
|
|
44
|
+
* {@link ObservabilityEvent} — hosts read fields through the per-kind
|
|
45
|
+
* guards (first-consumer finding, ggui#670 Phase 3).
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export function isRelayDeadTapEvent(event) {
|
|
50
|
+
return event.kind === 'relay-dead-tap';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Narrows to {@link RelayIncapabilityEvent}; inside it `state`
|
|
54
|
+
* discriminates the `'latched'` / `'cleared'` edges normally.
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export function isRelayIncapabilityEvent(event) {
|
|
59
|
+
return event.kind === 'relay-incapability';
|
|
60
|
+
}
|
|
2
61
|
/**
|
|
3
62
|
* Default emitter — posts an {@link ObservabilityMessage} to
|
|
4
63
|
* `window.parent`. Mirrors `postBootFailure` / `postRendererReady`
|
package/dist/react-renderer.d.ts
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* TypeScript config doesn't need a JSX runtime plumbing.
|
|
31
31
|
*/
|
|
32
32
|
import React, { type ReactNode } from 'react';
|
|
33
|
+
import type { AppTheme } from '@ggui-ai/protocol';
|
|
33
34
|
export interface ReactRootMountOptions {
|
|
34
35
|
/**
|
|
35
36
|
* GguiSession whose componentCode + props drive the mount. Only
|
|
@@ -98,11 +99,7 @@ export interface ReactRootMountOptions {
|
|
|
98
99
|
* painted ladder to its registration record); the renderer
|
|
99
100
|
* carries it but exposes no observability surface for it today.
|
|
100
101
|
*/
|
|
101
|
-
readonly base?:
|
|
102
|
-
readonly documentHash: string;
|
|
103
|
-
readonly light: Readonly<Record<string, string>>;
|
|
104
|
-
readonly dark: Readonly<Record<string, string>>;
|
|
105
|
-
};
|
|
102
|
+
readonly base?: NonNullable<AppTheme['base']>;
|
|
106
103
|
};
|
|
107
104
|
/**
|
|
108
105
|
* Host-announced palette, already translated onto `--ggui-*` tokens
|
package/dist/react-renderer.js
CHANGED
|
@@ -329,7 +329,15 @@ export async function mountReactRoot(container, opts) {
|
|
|
329
329
|
// ladder gets — base inherits, derived gradient/effect tokens
|
|
330
330
|
// (color-mix fallback split), box-sizing, font-inherit — from
|
|
331
331
|
// ONE shared builder, so the two paths cannot drift.
|
|
332
|
-
assembleDeliveredThemeCss(scopeClass, opts.themeMode === 'dark' ? deliveredBase.dark : deliveredBase.light
|
|
332
|
+
assembleDeliveredThemeCss(scopeClass, opts.themeMode === 'dark' ? deliveredBase.dark : deliveredBase.light, {
|
|
333
|
+
// ggui#613 residual 2 — the two former v1 deltas ride:
|
|
334
|
+
// the active mode's keyframes block + the frameless
|
|
335
|
+
// silhouette suppression, both same-rule as compiled.
|
|
336
|
+
keyframes: opts.themeMode === 'dark'
|
|
337
|
+
? deliveredBase.keyframes?.dark
|
|
338
|
+
: deliveredBase.keyframes?.light,
|
|
339
|
+
frameless: deliveredBase.frameless,
|
|
340
|
+
})
|
|
333
341
|
: opts.themeId
|
|
334
342
|
? getScopedThemeCss(opts.themeId, scopeClass, opts.themeMode)
|
|
335
343
|
: getScopedCssTokens(scopeClass, opts.themeMode);
|
|
@@ -367,9 +375,17 @@ export async function mountReactRoot(container, opts) {
|
|
|
367
375
|
// `ThemeProvider` so a Studio/Portal context with both runtime + RP
|
|
368
376
|
// active doesn't double-stack.
|
|
369
377
|
if (typeof document !== 'undefined') {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
378
|
+
// ggui#613 residual 5: under a DELIVERED base the body-chrome
|
|
379
|
+
// ladder is the delivered set too — mirroring the scoped ternary
|
|
380
|
+
// above — so the standalone viewer's body chrome and its tree
|
|
381
|
+
// content resolve the same values. Pre-fix this started from the
|
|
382
|
+
// compiled/default ladder regardless, and body chrome painted the
|
|
383
|
+
// default brand under a registered theme.
|
|
384
|
+
let rootCss = deliveredBase !== undefined
|
|
385
|
+
? `:root{${toCssDecls(opts.themeMode === 'dark' ? deliveredBase.dark : deliveredBase.light)}}`
|
|
386
|
+
: opts.themeId
|
|
387
|
+
? getThemeCss(opts.themeId, opts.themeMode)
|
|
388
|
+
: getCssTokens(opts.themeMode);
|
|
373
389
|
if (opts.hostPalette) {
|
|
374
390
|
// BODY-CHROME ONLY, same as the appTheme `:root` append below —
|
|
375
391
|
// and beneath it, mirroring the scoped-block order (#573:
|
package/dist/render-item.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import type { GguiSession } from '@ggui-ai/protocol';
|
|
2
|
+
import type { AppTheme, GguiSession } from '@ggui-ai/protocol';
|
|
3
3
|
import type { GguiSessionSeedInput } from './types.js';
|
|
4
4
|
import { type WireConfig } from '@ggui-ai/wire';
|
|
5
5
|
import type { StreamBus } from './wire-config.js';
|
|
@@ -59,11 +59,7 @@ export interface RenderItemOptions {
|
|
|
59
59
|
readonly appTheme?: {
|
|
60
60
|
readonly mode: 'light' | 'dark';
|
|
61
61
|
readonly cssVariables: Record<string, string>;
|
|
62
|
-
readonly base?:
|
|
63
|
-
readonly documentHash: string;
|
|
64
|
-
readonly light: Readonly<Record<string, string>>;
|
|
65
|
-
readonly dark: Readonly<Record<string, string>>;
|
|
66
|
-
};
|
|
62
|
+
readonly base?: NonNullable<AppTheme['base']>;
|
|
67
63
|
};
|
|
68
64
|
/**
|
|
69
65
|
* Host-announced palette, pre-mapped onto `--ggui-*` tokens by the
|
package/dist/runtime.d.ts
CHANGED
|
@@ -56,6 +56,15 @@ import { type LifecycleEmitter } from './lifecycle.js';
|
|
|
56
56
|
*/
|
|
57
57
|
type DrainAckListener = (payload: DrainAckPayload) => boolean | void;
|
|
58
58
|
export declare function subscribeDrainAck(listener: DrainAckListener): () => void;
|
|
59
|
+
/**
|
|
60
|
+
* The `drain_ack` ingress — fans a frame out to subscribers until one
|
|
61
|
+
* claims it.
|
|
62
|
+
*
|
|
63
|
+
* @internal — exported for unit tests: a late ack for an earlier
|
|
64
|
+
* delivered gesture is the path that retires the standing relay notice
|
|
65
|
+
* without any user click (ggui#670 Phase 3, truth-2).
|
|
66
|
+
*/
|
|
67
|
+
export declare function dispatchDrainAck(payload: DrainAckPayload): void;
|
|
59
68
|
export type ConnectAppResult = {
|
|
60
69
|
readonly ok: true;
|
|
61
70
|
} | {
|
|
@@ -276,6 +285,18 @@ export interface BootSequenceOptions {
|
|
|
276
285
|
* or not this option is bound.
|
|
277
286
|
*/
|
|
278
287
|
readonly onObserve?: ObservabilityEmitter;
|
|
288
|
+
/**
|
|
289
|
+
* Opt-in knob for the in-iframe UI-feedback chrome (#653). DEFAULT
|
|
290
|
+
* OFF by founder ruling — a generated component card carries no
|
|
291
|
+
* feedback affordance unless the embedding deployment passes `true`
|
|
292
|
+
* here. Even when opted in, the #471 live-sink gate still applies
|
|
293
|
+
* (see `shouldMountUiFeedbackChrome`): hosts that drop the
|
|
294
|
+
* `ggui:observe` envelope never get the affordance. Chrome
|
|
295
|
+
* configuration, not wire data — the agent cannot observe this knob
|
|
296
|
+
* (data-vs-behavior), so it is a boot option, never a contract
|
|
297
|
+
* field.
|
|
298
|
+
*/
|
|
299
|
+
readonly uiFeedback?: boolean;
|
|
279
300
|
/**
|
|
280
301
|
* Optional {@link LifecycleEmitter} sink. Fires on every renderer
|
|
281
302
|
* mount-state transition (`mounting` → `code-ready` | `error`,
|
|
@@ -648,6 +669,16 @@ interface ToastLiveRegions {
|
|
|
648
669
|
* @internal — exported for unit tests.
|
|
649
670
|
*/
|
|
650
671
|
export declare function ensureToastAnnouncer(doc: Document): ToastLiveRegions | null;
|
|
672
|
+
/**
|
|
673
|
+
* Boot-time reset of the relay latch (ggui#670 Phase 3). A latch
|
|
674
|
+
* standing from a prior mount in a re-booted document is closed through
|
|
675
|
+
* the ONE writer — the host gets its `cleared` edge with the zone's
|
|
676
|
+
* summary — and the prior mount's standing notice is removed rather
|
|
677
|
+
* than left describing a session that no longer exists.
|
|
678
|
+
*
|
|
679
|
+
* @internal — exported for unit tests.
|
|
680
|
+
*/
|
|
681
|
+
export declare function resetRelayLatchForBoot(): void;
|
|
651
682
|
/** @internal — exported for unit tests to reset module state. */
|
|
652
683
|
export declare function __resetRelayNoticeForTest(): void;
|
|
653
684
|
/**
|