@ggui-ai/protocol 0.7.0 → 0.9.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 (42) hide show
  1. package/dist/gadgets/stdlib-gadgets.d.ts +1 -1
  2. package/dist/gadgets/stdlib-gadgets.js +1 -1
  3. package/dist/integrations/epoch-uri.d.ts +42 -0
  4. package/dist/integrations/epoch-uri.d.ts.map +1 -0
  5. package/dist/integrations/epoch-uri.js +48 -0
  6. package/dist/integrations/mcp-apps.d.ts +140 -10
  7. package/dist/integrations/mcp-apps.d.ts.map +1 -1
  8. package/dist/integrations/mcp-apps.js +94 -6
  9. package/dist/schemas/data-contract.d.ts +4 -2
  10. package/dist/schemas/data-contract.d.ts.map +1 -1
  11. package/dist/schemas/data-contract.js +4 -2
  12. package/dist/schemas/invoke.d.ts +1 -1
  13. package/dist/schemas/invoke.js +1 -1
  14. package/dist/schemas/mcp.d.ts +222 -6
  15. package/dist/schemas/mcp.d.ts.map +1 -1
  16. package/dist/schemas/mcp.js +285 -13
  17. package/dist/types/data-contract.d.ts +8 -4
  18. package/dist/types/data-contract.d.ts.map +1 -1
  19. package/dist/types/ggui-session-event.d.ts +42 -1
  20. package/dist/types/ggui-session-event.d.ts.map +1 -1
  21. package/dist/types/ggui-session-event.js +16 -1
  22. package/dist/types/live-channel.d.ts +8 -0
  23. package/dist/types/live-channel.d.ts.map +1 -1
  24. package/dist/types/llm-route.d.ts +2 -2
  25. package/dist/types/llm-route.d.ts.map +1 -1
  26. package/dist/types/llm-route.js +26 -8
  27. package/dist/types/mcp.d.ts +51 -1
  28. package/dist/types/mcp.d.ts.map +1 -1
  29. package/dist/types/render.d.ts +12 -0
  30. package/dist/types/render.d.ts.map +1 -1
  31. package/dist/types/ui-generator.d.ts +20 -3
  32. package/dist/types/ui-generator.d.ts.map +1 -1
  33. package/dist/validation/contract-validator.d.ts +2 -2
  34. package/dist/validation/contract-validator.d.ts.map +1 -1
  35. package/dist/validation/resolve-stream-channel.d.ts +2 -2
  36. package/dist/validation/resolve-stream-channel.js +2 -2
  37. package/dist/validation/ui-security.d.ts +2 -2
  38. package/dist/validation/ui-security.js +2 -2
  39. package/dist/version.d.ts +245 -0
  40. package/dist/version.d.ts.map +1 -1
  41. package/dist/version.js +245 -0
  42. package/package.json +1 -1
package/dist/version.js CHANGED
@@ -6,6 +6,69 @@
6
6
  * schema change; the most recent change anchors {@link PROTOCOL_VERSION}.
7
7
  *
8
8
  * --------------------------------------------------------------------
9
+ * MCP tool bindings & discovery (2026-08-10, additive, pre-launch,
10
+ * ggui#259). Artifacts gain an optional MCP tool-binding list and
11
+ * registry search gains a tool dimension, connecting the two
12
+ * namespaces the registry serves: signed UI artifacts and the MCP
13
+ * tools they render. SPEC §7.7.4.1 is the normative home.
14
+ *
15
+ * tb1. **`mcpTools` on both manifest kinds**
16
+ * (`@ggui-ai/artifact-manifest`): 1–16 `{server?, tool}`
17
+ * entries, charset `/^[A-Za-z0-9_.-]{1,128}$/`,
18
+ * exact-duplicate `(server, tool)` pairs rejected with the
19
+ * existing `manifest_invalid` code. Declared wins entirely;
20
+ * a blueprint without the field derives bare `{tool}` entries
21
+ * from the union of its contract's per-prop `sourceTool` and
22
+ * `streamSpec` `source.tool` names (`resolveMcpToolBindings`,
23
+ * marked `derived`). Bindings are search metadata only — they
24
+ * never enter contract canonicalization or `blueprintKey`.
25
+ * NOTE: manifest schemas are strict-rooted, so an OLDER
26
+ * manifest parser REJECTS a manifest file carrying the field —
27
+ * the optionality guarantee below is wire-response-scoped
28
+ * (search/read), not manifest-file-scoped.
29
+ *
30
+ * tb2. **Registry wire additions** (`@ggui-ai/registry-core`),
31
+ * all optional: `SearchResultEntry` += `mcpTools?`,
32
+ * `mcpToolsSource?: 'declared' | 'derived'`,
33
+ * `scopeVerification?: 'verified' | 'unverified'`,
34
+ * `verifiedDomain?`; the single-version read response += the
35
+ * same two verification fields; search input += `tool?` /
36
+ * `server?` exact filters (AND-composed with the existing
37
+ * filters, `matchesMcpToolFilters` semantics; an invalid
38
+ * charset value is the existing `invalid_request` 400).
39
+ * Pre-existing consumers see `undefined` and behave as before.
40
+ *
41
+ * tb3. **Agent surface** (`@ggui-ai/mcp-server-handlers`):
42
+ * `ggui_search_blueprints` gains an opt-in `registry` source
43
+ * merged after the local sources; unreachable / timeout /
44
+ * unparseable-body answers degrade typed —
45
+ * `degradedSources: [{source: 'registry', reason:
46
+ * 'unreachable' | 'timeout' | 'invalid_response'}]` — never a
47
+ * tool failure, never a thrown error.
48
+ *
49
+ * Conformance-kit verdict: additive, minor-intent while `draft-`,
50
+ * so PROTOCOL_VERSION is unchanged — no WS envelope moved; the
51
+ * change is confined to the manifest, registry HTTP, and MCP
52
+ * tool-result surfaces. The new `binding-conformance` catalog in
53
+ * `@ggui-ai/protocol-conformance` (`runBindingResolutionCases` /
54
+ * `runBindingFilterCases`) arbitrates resolution precedence and
55
+ * filter semantics; search/read response optionality is pinned by
56
+ * registry-core unit tests, because the strict-rooted manifest
57
+ * schema makes a manifest-file optionality fixture false (tb1).
58
+ *
59
+ * Package version — the classification is MADE here, not deferred:
60
+ * MINOR for the `@ggui-ai/*` wave, additive under the version
61
+ * policy's minor rule (every fixture that passed against the
62
+ * current wave still passes; the delta is new surface), pre-1.0
63
+ * and pre-launch. FOUR packages carry minor-class changes into
64
+ * that wave — `@ggui-ai/artifact-manifest` (the field + resolver),
65
+ * `@ggui-ai/registry-core` (wire + filters),
66
+ * `@ggui-ai/mcp-server-handlers` (the registry source), and
67
+ * `@ggui-ai/protocol-conformance` (the catalog that decides them).
68
+ * Only the mechanical write is deferred: every `@ggui-ai/*`
69
+ * package carries ONE wave version, so the release owner takes all
70
+ * four bumps together at the next wave cut.
71
+ * --------------------------------------------------------------------
9
72
  * Typed `resources/read` failures (2026-08-09, additive, pre-launch,
10
73
  * ggui#430). A read of a render locator
11
74
  * (`ui://ggui/render/{sessionId}/{blueprintKey}`) gains a closed failure
@@ -141,6 +204,188 @@
141
204
  * extending it over the existing fixture catalog would be a MAJOR, not
142
205
  * a minor, and must be adjudicated as one.
143
206
  *
207
+ * #471 (2026-08-10): the fetch-free delivery surface — a MINOR for the
208
+ * `@ggui-ai/protocol` wave, deferred to the next cut under the same
209
+ * one-wave-version rule as above. Three additive pieces, one shared
210
+ * motivation (hosts whose iframe CSP forbids every URL-scheme load
211
+ * while permitting inline scripts):
212
+ *
213
+ * if1. **`McpAppAiGguiRenderMeta.codeB64`** — optional base64
214
+ * compiled component source, the fetch-free twin of `codeUrl`
215
+ * (coexists with it; exclusive with `kind`). Every envelope that
216
+ * parsed before parses identically; the parser's new rejection
217
+ * arm (`codeB64` + `kind` both set) rejects a shape no producer
218
+ * ever emitted. `hasMountModeDiscriminator` widens PERMISSIVELY
219
+ * (a codeB64-only slice becomes mountable — previously
220
+ * undefined, not different).
221
+ *
222
+ * if2. **`GguiShellHtmlOptions.runtimeInlineSource` +
223
+ * `escapeInlineScript`** — host-helper additions; the default
224
+ * (external `<script src>`) emission is byte-unchanged.
225
+ *
226
+ * if3. Consumer-side: `@ggui-ai/design` gains the inline-exec
227
+ * module (new exports only); `@ggui-ai/mcp-server` gains the
228
+ * `mcpApps.inlineRuntimeShell` opt-in (default OFF — the served
229
+ * static shell is byte-unchanged for every existing mount) and
230
+ * `registerGguiRenderResource` gains a trailing optional
231
+ * CSP-fallback parameter (existing positional calls unchanged).
232
+ *
233
+ * Conformance-kit verdict: no fixture pins the render slice's closed
234
+ * field set (the slice is verbatim-carry by design — the host-helper
235
+ * suite's "unknown future fields ride along" case is the governing
236
+ * posture), so the additive field breaks nothing. PROTOCOL_VERSION
237
+ * unchanged — no wire frame changed shape.
238
+ *
239
+ * SSE middle rung (2026-08-11): the failover-ladder stream surface — a
240
+ * MINOR for the `@ggui-ai/protocol` wave, deferred to the next cut
241
+ * (≥ 0.9.0) under the same one-wave-version rule as above. Two
242
+ * additive pieces, one motivation (hosts whose CSP blocks WebSocket
243
+ * but permits `EventSource`, giving the ladder a live middle rung
244
+ * between WS and cursor polling):
245
+ *
246
+ * sm1. **`McpAppAiGguiRenderMeta.sseUrl`** — optional server-stamped
247
+ * `/api/sessions/<sessionId>/stream?wsToken=<token>` URL beside
248
+ * `pollingUrl`. Every envelope that parsed before parses
249
+ * identically (tolerant scalar posture, no pairing invariant —
250
+ * the URL is self-authorizing via its embedded token). Absent ⇒
251
+ * no SSE rung; the ladder is WS → polling. The stream contract
252
+ * the URL points at (ChannelFrame-per-`data:`-line byte-same as
253
+ * the WS push, `id:` = ledger seq on replay frames only,
254
+ * `: hb` comment heartbeat ≤ ~25s, `retry: 3000` first write,
255
+ * `Last-Event-ID` over `?sinceSequence=`, 401/404/410 mirroring
256
+ * `/events`) is pinned on the interface docstring.
257
+ *
258
+ * sm2. **`composeSessionApiUrls` + `SessionApiUrls`** — the ONE
259
+ * pure composer every stamping surface (render/update resultMeta,
260
+ * self-contained shell, `/state` bootstrap) routes both URLs
261
+ * through — the `deriveRenderMeta` move applied to channel URLs.
262
+ * New exports only. This REPAIRS a confirmed drift: `/state` used
263
+ * to stamp an unconditional token-less `/state`-shaped
264
+ * pollingUrl that could only 401 through the events composer;
265
+ * both URLs now stamp ONLY when the live trio is minted, and
266
+ * omission is the honest no-HTTP-fallback signal.
267
+ *
268
+ * Conformance-kit verdict: same posture as if1 — no fixture pins the
269
+ * render slice's closed field set (verbatim-carry by design), so the
270
+ * additive field breaks nothing. Full SSE endpoint conformance cases
271
+ * are a FLAGGED follow-up (unit tests ride this slice; conformance
272
+ * ticket after launch — No Silent Block). PROTOCOL_VERSION unchanged —
273
+ * no WS envelope moved; the SSE `data:` line reuses the ChannelFrame
274
+ * shape byte for byte.
275
+ *
276
+ * --------------------------------------------------------------------
277
+ * Bridge-pull terminal rung (2026-08-11): `ggui_runtime_pull` — a
278
+ * MINOR for the `@ggui-ai/protocol` wave, riding the same next cut
279
+ * (≥ 0.9.0) as the SSE entry above. One motivation: hosts whose CSP
280
+ * blocks EVERY network API from the iframe (claude.ai's srcdoc
281
+ * sandbox) can still pull the event ledger over the host's
282
+ * `tools/call` postMessage bridge — the fourth and terminal rung of
283
+ * the failover ladder (WS → SSE → HTTP polling → bridge-pull).
284
+ *
285
+ * bp1. **`runtimePullInput/OutputSchema` + `GguiRuntimePullInput/
286
+ * Output`** — new tool contract, output byte-parity with the
287
+ * `/events` route (`EventsResponse` page arm |
288
+ * `REPLAY_HORIZON_PASSED` arm as a NORMAL result) so ONE client
289
+ * parse core serves both carriers. `_meta.ui.visibility: ['app']`
290
+ * restricts callers to MCP Apps views per spec §401.
291
+ *
292
+ * bp2. **`wait` + `RUNTIME_PULL_MAX_WAIT_SECONDS`** — the
293
+ * subscription-mode hold: an empty cursor page holds the call
294
+ * server-side (≤ 20s, under `ggui_consume`'s proven 25s host
295
+ * tolerance) until an event lands. Back-to-back held single-shots
296
+ * emulate push through a request/response-only bridge; clients
297
+ * demote to sparse un-held pulls after consecutive empty holds.
298
+ *
299
+ * Conformance-kit verdict: additive tool, no existing fixture touches
300
+ * it; bridge-carrier conformance cases join the SSE follow-up ticket
301
+ * (No Silent Block). PROTOCOL_VERSION unchanged — no WS envelope
302
+ * moved; the ledger event vocabulary gained active use of the
303
+ * existing `'ui.updated'` taxonomy member (`ggui_update` now appends
304
+ * it), not a new member.
305
+ *
306
+ * --------------------------------------------------------------------
307
+ * React/RN SDK-surface retirement (2026-08-13, owner ruling; rides
308
+ * the same next cut ≥ 0.9.0): `@ggui-ai/react` + `@ggui-ai/react-
309
+ * native` are MCP Apps HOST-HELPER libraries, not SDKs — embeds mount
310
+ * views via the spec path (`AppRenderer` / RN `McpAppIframe`) and get
311
+ * runtime semantics (freeze latch, crash card, epochs) from the
312
+ * mounted iframe itself. Deleted from `@ggui-ai/react`: `GguiRender`
313
+ * + its WS stack (`useWebSocket`, `WebSocketManager`, `EventBuffer`,
314
+ * reserved-validators), local `ThemeProvider`, `SelfRepairBoundary`
315
+ * family, `AgentBrowsePanel`, the dead wire-type re-exports, the
316
+ * public `useGguiContext`/`useAdapter`/`AdapterRegistry` barrel
317
+ * entries (impls stay internal), and `chat-thread/**` (both
318
+ * packages — third-party chat framework, zero consumers; guuey built
319
+ * `@guuey/threads` instead). RN's direct-render family was already
320
+ * deleted pre-ruling (#425, 7d5c6955b). Zero-consumer adversarially
321
+ * traced per export before deletion; guuey pins both packages at
322
+ * 0.6.3 (npm-immutable — installs unaffected; handoff note per the
323
+ * deletion discipline). Breaking TS-API shrink, 0.x MINOR carries it.
324
+ * SAME-DAY RENAME RULING: the packages republish at this cut as
325
+ * `@ggui-ai/mcp-apps-react` / `@ggui-ai/mcp-apps-react-native` —
326
+ * the names must say "MCP Apps bindings," not "SDK." Old names get
327
+ * `npm deprecate` + pointer at cut time (owner click, OTP; new names
328
+ * need Trusted Publishing setup — see release:cut).
329
+ *
330
+ * --------------------------------------------------------------------
331
+ * Mutation tool split + epoch history (2026-08-13, ggui#481→#483,
332
+ * SUPERSEDES the same-night renderAsNew param design, which never
333
+ * reached a cut): a MINOR for the `@ggui-ai/protocol` wave, riding
334
+ * the same next cut (≥ 0.9.0). One motivation arc: hosts mint
335
+ * per-result views from result shape, so mutation results must be
336
+ * either complete mount packages or carry nothing — and once every
337
+ * update result is a durable record, the records ARE a history.
338
+ *
339
+ * ts1. **`ggui_amend`** — new tool: in-place mutation of the
340
+ * mounted card. Same replace/merge grammar as update
341
+ * (`amendInputSchema`/`amendOutputSchema` + inferred types); NOT
342
+ * UI-bound, results carry NO `_meta` under any outcome; the
343
+ * history epoch is untouched by construction. Additive.
344
+ *
345
+ * ts2. **`ggui_update` semantics change, stated plainly:** every
346
+ * real update now mints a NEW history record — output gains
347
+ * mandatory `epoch` and its `resourceUri` is the epoch-PINNED
348
+ * URI (`…#N`); the result `_meta` is unconditionally the full
349
+ * bootable mount package (#481). `renderAsNew` is deleted from
350
+ * both arms. A consumer that treated update results as in-place
351
+ * acknowledgements sees new cards; the in-place path moved to
352
+ * ggui_amend. Pre-launch no-compat; the kit is the arbiter and
353
+ * update-family conformance cases ship IN THIS SLICE (epoch
354
+ * immutability, head aliasing, amend-mints-nothing), closing the
355
+ * previously flagged gap.
356
+ *
357
+ * ts3. **Epoch surfaces:** `GguiSessionBase.epoch` +
358
+ * `McpAppsGguiSession.epoch` (optional, absent ⇒ 0 — the row is
359
+ * the authority; the ledger is horizon-bounded); `'ui.reminted'`
360
+ * joins the ledger taxonomy with `UiRemintedEventData`;
361
+ * `UiUpdatedEventData` types the props event (now epoch-stamped);
362
+ * `composeEpochUri`/`parseEpochUri` (the ONE encoding seam —
363
+ * fragment today, flippable post-host-probe);
364
+ * `deriveEpochFromEvents` (in-horizon reconstruction only).
365
+ * SPEC §7.1.2/§7.1.2.1/§7.1.2.2 are the normative text.
366
+ *
367
+ * ts4. **Live-fan epoch obligation (2026-08-13 follow-up, same
368
+ * wave):** `PropsUpdatePayload.epoch` (`@ggui-ai/protocol`
369
+ * live-channel, optional on the wire) is the freeze-latch signal,
370
+ * and servers MUST stamp live `props_update` frames with the
371
+ * COMMIT-TIME epoch (SPEC §7.1.2.2). TS API surfaces moved with
372
+ * it: `PropsUpdateNotifier.sendPropsUpdate` gains a required
373
+ * `epoch` third param (`@ggui-ai/mcp-server-handlers`), as does
374
+ * `GguiSessionChannelServer.sendPropsUpdate`
375
+ * (`@ggui-ai/mcp-server`) — 2-arg callers break at compile time
376
+ * (pre-launch no-compat; 0.x MINOR carries it). Motivating
377
+ * incident: a second notifier impl (cloud pod) omitted the then-
378
+ * optional field and shipped epoch-less frames — the latch
379
+ * degraded to legacy-apply exactly as designed for skew, which
380
+ * is also the compat story: old runtime × new server ignores the
381
+ * extra field; new runtime × old server sees no epoch and
382
+ * applies as before. Graceful both directions.
383
+ *
384
+ * PROTOCOL_VERSION unchanged — no WS frame changed shape; the
385
+ * `ai.ggui/render` slice's field set was never closed, and the
386
+ * `ui.updated` / `props_update` payloads gained an optional field on
387
+ * open payload surfaces.
388
+ *
144
389
  * --------------------------------------------------------------------
145
390
  * Credential-broker surface retired (2026-08-08, BREAKING, pre-launch,
146
391
  * ggui#436). The `system` frame's auth vocabulary and the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/protocol",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "ggui protocol types — events, renders, WebSocket, MCP, LLM models",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [