@ggui-ai/ui-visual-tester 0.1.0-rc.3 → 0.2.0-alpha.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.
@@ -141,7 +141,7 @@ function mountTree(Comp) {
141
141
  */
142
142
  const wireConfig = {
143
143
  app: { appId: 'vt-app', appName: 'vt-app' },
144
- session: { sessionId: 'vt-session', isConnected: true },
144
+ render: { renderId: 'vt-render', isConnected: true },
145
145
  auth: { isAuthenticated: false },
146
146
  dispatch: (actionName, data) => {
147
147
  dispatches.push({ actionName, data, t: Date.now() });
@@ -27121,7 +27121,7 @@
27121
27121
  useAuth: () => useAuth,
27122
27122
  useContract: () => useContract,
27123
27123
  useGguiContext: () => useGguiContext,
27124
- useSession: () => useSession,
27124
+ useRender: () => useRender,
27125
27125
  useStream: () => useStream,
27126
27126
  useWireContext: () => useWireContext,
27127
27127
  validateInboundPropsPayload: () => validateInboundPropsPayload,
@@ -27264,14 +27264,14 @@
27264
27264
  return app;
27265
27265
  }
27266
27266
 
27267
- // ../wire/dist/useSession.js
27268
- function useSession() {
27269
- const { session } = useWireContext();
27270
- return session;
27267
+ // ../wire/dist/useRender.js
27268
+ function useRender() {
27269
+ const { render } = useWireContext();
27270
+ return render;
27271
27271
  }
27272
27272
 
27273
27273
  // ../protocol/dist/version.js
27274
- var PROTOCOL_VERSION = "draft-2026-05-24";
27274
+ var PROTOCOL_VERSION = "draft-2026-05-28";
27275
27275
  var PROTOCOL_SCHEMA_VERSION = PROTOCOL_VERSION;
27276
27276
  var CLIENT_SUPPORTED_VERSIONS = Object.freeze([
27277
27277
  PROTOCOL_SCHEMA_VERSION
@@ -41495,28 +41495,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41495
41495
  colorScheme: external_exports.enum(["light", "dark"]).optional(),
41496
41496
  reducedMotion: external_exports.boolean().optional()
41497
41497
  }).passthrough();
41498
- var popInputSchema = external_exports.object({
41499
- sessionId: external_exports.string().describe("Session opaque id from ggui_new_session.")
41500
- }).strict();
41501
41498
  var consumeInputSchema = external_exports.object({
41502
- stackItemId: external_exports.string().describe("Stack item opaque id (UUID) \u2014 returned by ggui_push."),
41499
+ renderId: external_exports.string().describe("Render opaque id (UUID) \u2014 returned by ggui_render."),
41503
41500
  timeout: external_exports.number().min(0).max(25).optional().describe("Long-poll timeout in seconds (default short; max 25).")
41504
41501
  }).strict();
41505
41502
  var emitInputSchema = external_exports.object({
41506
- sessionId: external_exports.string().describe("Session opaque id from ggui_new_session."),
41507
- channel: external_exports.string().describe("Channel name declared on the active stack item streamSpec."),
41503
+ renderId: external_exports.string().describe("Render opaque id (UUID) \u2014 returned by ggui_render."),
41504
+ channel: external_exports.string().describe("Channel name declared on the active render streamSpec."),
41508
41505
  payload: external_exports.unknown().describe("Payload \u2014 must match streamSpec[channel].schema."),
41509
- complete: external_exports.boolean().optional().describe("True marks the stream complete; subsequent emits on this channel reject."),
41510
- stackItemId: external_exports.string().optional().describe("Stack item to scope this emit to; defaults to session top.")
41511
- }).strict();
41512
- var getSessionInputSchema = external_exports.object({
41513
- sessionId: external_exports.string().describe("Session opaque id from ggui_new_session.")
41514
- }).strict();
41515
- var getStackInputSchema = external_exports.object({
41516
- sessionId: external_exports.string().describe("Session opaque id from ggui_new_session.")
41506
+ complete: external_exports.boolean().optional().describe("True marks the stream complete; subsequent emits on this channel reject.")
41517
41507
  }).strict();
41518
- var closeInputSchema = external_exports.object({
41519
- sessionId: external_exports.string().describe("Session opaque id from ggui_new_session.")
41508
+ var getRenderInputSchema = external_exports.object({
41509
+ renderId: external_exports.string().describe("Render opaque id (UUID) \u2014 returned by ggui_render.")
41520
41510
  }).strict();
41521
41511
  var listFeaturedBlueprintsInputSchema = external_exports.object({
41522
41512
  level: external_exports.enum(["primitive", "component", "composite", "template"]).optional(),
@@ -41536,27 +41526,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41536
41526
  var requestCredentialInputSchema = external_exports.object({
41537
41527
  serviceId: external_exports.string().describe('OAuth service ID (e.g., "bashdoor", "ubot")'),
41538
41528
  reason: external_exports.string().optional().describe("Why the agent needs this credential (shown to user)"),
41539
- sessionId: external_exports.string().optional().describe("Existing session ID to push consent UI into")
41529
+ renderId: external_exports.string().optional().describe("Existing render id to push consent UI into.")
41540
41530
  }).strict();
41541
- var newSessionInputSchema = external_exports.object({}).strict();
41542
- var newSessionOutputSchema = external_exports.object({
41543
- sessionId: external_exports.string().describe("Thread this through every subsequent ggui_handshake / ggui_update call in this chat."),
41544
- appId: external_exports.string(),
41545
- createdAt: external_exports.string().describe("ISO 8601 \u2014 creation timestamp of the freshly-minted session."),
41546
- nextStep: external_exports.object({
41547
- tool: external_exports.literal("ggui_handshake"),
41548
- description: external_exports.string(),
41549
- example: external_exports.string()
41550
- }).describe("Wire-shape recovery hint \u2014 a worked literal example of the next call.")
41551
- });
41552
41531
  var handshakeInputSchema = external_exports.object({
41553
- /**
41554
- * Required. Mint via `ggui_new_session` once per chat, then thread
41555
- * through every subsequent handshake. Server validates existence +
41556
- * tenant ownership; unknown / cross-tenant ids surface as
41557
- * session_not_found.
41558
- */
41559
- sessionId: external_exports.string().min(1).describe("Session handle minted by ggui_new_session. Required \u2014 call ggui_new_session({seed?}) first to obtain one. Reuse the same sessionId across multiple handshake/push pairs in the same chat to grow the session stack."),
41560
41532
  /**
41561
41533
  * Concise semantic identity of the UI. Same intent across calls =
41562
41534
  * same component reused. Required — drives blueprint-search keying
@@ -41576,20 +41548,20 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41576
41548
  * Skip blueprint-search on step-2 and route straight to validation
41577
41549
  * + (if validation passes) agent-mode suggestion against the draft.
41578
41550
  * Used after a prior handshake returned an unwanted cache suggestion
41579
- * and the agent wants to force a fresh-gen path on the paired push.
41551
+ * and the agent wants to force a fresh-gen path on the paired render.
41580
41552
  */
41581
41553
  forceCreate: external_exports.boolean().optional()
41582
41554
  }).strict();
41583
41555
  var handshakeOutputSchema = external_exports.object({
41584
- handshakeId: external_exports.string().describe("Stable id \u2014 pass to ggui_push / ggui_update"),
41585
- action: external_exports.enum(["create", "reuse", "update", "replace", "compose", "declined"]),
41556
+ handshakeId: external_exports.string().describe("Stable id \u2014 pass to ggui_render / ggui_update"),
41557
+ action: external_exports.enum(["create", "reuse", "update", "replace", "declined"]),
41586
41558
  /**
41587
41559
  * The handshake suggestion — see `handshakeSuggestionSchema`. The
41588
41560
  * routing discriminator is `suggestion.origin`; `blueprintMeta` is
41589
41561
  * ALWAYS present; `amendments` / `validationFindings` are
41590
41562
  * conditional on the routing outcome.
41591
41563
  */
41592
- suggestion: handshakeSuggestionSchema.describe("Server's suggestion \u2014 origin-routed (cache | agent | synth). Always carries a provisional `blueprintMeta` the agent reuses by sending `decision: 'accept'` on push."),
41564
+ suggestion: handshakeSuggestionSchema.describe("Server's suggestion \u2014 origin-routed (cache | agent | synth). Always carries a provisional `blueprintMeta` the agent reuses by sending `decision: 'accept'` on render."),
41593
41565
  /**
41594
41566
  * Truncated human-readable rationale for the `action` value. Helps
41595
41567
  * the agent and the operator narrate why the server chose to reuse a cached
@@ -41599,19 +41571,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41599
41571
  */
41600
41572
  reason: external_exports.string().max(280).optional().describe("Short rationale (\u2264280 chars) for the `action` value. Surfaced for agent + operator visibility; truncated to keep the structuredContent payload predictable."),
41601
41573
  nextStep: external_exports.object({
41602
- tool: external_exports.literal("ggui_push"),
41574
+ tool: external_exports.literal("ggui_render"),
41603
41575
  description: external_exports.string(),
41604
41576
  example: external_exports.string()
41605
- }).optional().describe("Wire-shape recovery hint. A worked literal example of the next ggui_push call the agent should emit \u2014 the example string can be copied verbatim and tweaked (e.g. fill in `props` placeholders). Top-level field so a skimming agent finds it immediately.")
41577
+ }).optional().describe("Wire-shape recovery hint. A worked literal example of the next ggui_render call the agent should emit \u2014 the example string can be copied verbatim and tweaked (e.g. fill in `props` placeholders). Top-level field so a skimming agent finds it immediately.")
41606
41578
  });
41607
- var pushInputSchema = external_exports.object({
41579
+ var renderInputSchema = external_exports.object({
41608
41580
  handshakeId: external_exports.string({
41609
- message: "ggui_push: handshakeId is REQUIRED. Call ggui_handshake({sessionId, intent, blueprintDraft}) first to negotiate \u2014 handshake returns a handshakeId + suggestion. Then push with {handshakeId, decision: {kind: 'accept'}} (accept the suggestion) or {handshakeId, decision: {kind: 'override', blueprintDraft: {...}}} (override with a fresh draft). Direct-push without a handshakeId is not supported."
41610
- }).min(1, "ggui_push: handshakeId must be a non-empty string from a prior ggui_handshake call."),
41581
+ message: "ggui_render: handshakeId is REQUIRED. Call ggui_handshake({intent, blueprintDraft}) first to negotiate \u2014 handshake returns a handshakeId + suggestion. Then render with {handshakeId, decision: {kind: 'accept'}} (accept the suggestion) or {handshakeId, decision: {kind: 'override', blueprintDraft: {...}}} (override with a fresh draft). Direct-render without a handshakeId is not supported."
41582
+ }).min(1, "ggui_render: handshakeId must be a non-empty string from a prior ggui_handshake call."),
41611
41583
  /**
41612
41584
  * Runtime prop values for THIS render. Validated against the
41613
41585
  * effective contract's `propsSpec` — required-field checks + type
41614
- * checks per spec entry. Validation failures fail the push with a
41586
+ * checks per spec entry. Validation failures fail the render with a
41615
41587
  * recoverable `ContractViolationError`.
41616
41588
  */
41617
41589
  props: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
@@ -41629,20 +41601,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41629
41601
  */
41630
41602
  decision: pushDecisionSchema.describe("Accept the handshake suggestion (use provisional blueprintId verbatim) or override with a fresh draft (mint new blueprintId).")
41631
41603
  }).strict();
41632
- var pushOutputSchema = external_exports.object({
41633
- stackItemId: external_exports.string(),
41634
- url: external_exports.string().url(),
41635
- action: external_exports.enum(["create", "reuse", "update", "replace", "compose", "declined"]),
41604
+ var renderOutputSchema = external_exports.object({
41605
+ renderId: external_exports.string(),
41606
+ /**
41607
+ * Spec-canonical MCP-Apps entry-point — same `ui://ggui/render/{id}`
41608
+ * URI surfaced on `_meta.ui.resourceUri`. Surfacing it on the LLM-
41609
+ * visible structuredContent too lets SDKs that strip `_meta` from
41610
+ * tool_results (OpenAI Agents SDK, Google ADK) reach the mount URI;
41611
+ * SDKs that preserve `_meta` see the same value on both fields.
41612
+ * Mirrors the `resourceUri` field on `ggui_update`'s output.
41613
+ */
41614
+ resourceUri: external_exports.string(),
41615
+ action: external_exports.enum(["create", "reuse", "update", "replace", "declined"]),
41636
41616
  /**
41637
41617
  * Wire-shape recovery hint for the next call. Emitted ONLY when the
41638
- * pushed contract has a non-empty `actionSpec` — i.e. the agent will
41639
- * receive user-action events on this stack item. Pure-display pushes
41618
+ * rendered contract has a non-empty `actionSpec` — i.e. the agent will
41619
+ * receive user-action events on this render. Pure-display renders
41640
41620
  * (props only) get no `nextStep` because there is nothing to consume.
41641
41621
  *
41642
- * Mirrors the chain at `new_session.nextStep` (→ handshake) and
41643
- * `handshake.nextStep` (→ push). Closes the loop with consume.
41622
+ * Mirrors the chain at `handshake.nextStep` (→ render). Closes the loop
41623
+ * with consume.
41644
41624
  *
41645
- * `args.stackItemId` is the literal value the agent passes to
41625
+ * `args.renderId` is the literal value the agent passes to
41646
41626
  * `ggui_consume` — copy-paste shape.
41647
41627
  */
41648
41628
  nextStep: external_exports.object({
@@ -41650,24 +41630,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
41650
41630
  description: external_exports.string(),
41651
41631
  example: external_exports.string(),
41652
41632
  args: external_exports.object({
41653
- stackItemId: external_exports.string()
41633
+ renderId: external_exports.string()
41654
41634
  })
41655
- }).optional().describe("Recovery hint \u2014 when the pushed contract has actions, points the agent at ggui_consume({stackItemId}) for the inbound action loop. Absent for pure-display pushes.")
41635
+ }).optional().describe("Recovery hint \u2014 when the rendered contract has actions, points the agent at ggui_consume({renderId}) for the inbound action loop. Absent for pure-display renders.")
41656
41636
  });
41657
41637
  var updateInputSchema = external_exports.discriminatedUnion("kind", [
41658
41638
  external_exports.object({
41659
- stackItemId: external_exports.string().describe("Stack item opaque id (UUID) \u2014 returned by ggui_push."),
41639
+ renderId: external_exports.string().describe("Render opaque id (UUID) \u2014 returned by ggui_render."),
41660
41640
  kind: external_exports.literal("replace"),
41661
41641
  props: external_exports.record(external_exports.string(), external_exports.unknown()).describe("Full replacement props map. New map IS the new state.")
41662
41642
  }).strict(),
41663
41643
  external_exports.object({
41664
- stackItemId: external_exports.string().describe("Stack item opaque id (UUID) \u2014 returned by ggui_push."),
41644
+ renderId: external_exports.string().describe("Render opaque id (UUID) \u2014 returned by ggui_render."),
41665
41645
  kind: external_exports.literal("merge"),
41666
41646
  patch: external_exports.record(external_exports.string(), external_exports.unknown()).describe("RFC 7396 JSON Merge Patch \u2014 null deletes a key; arrays fully replace.")
41667
41647
  }).strict()
41668
41648
  ]);
41669
41649
  var updateOutputSchema = external_exports.object({
41670
- stackItemId: external_exports.string(),
41650
+ renderId: external_exports.string(),
41671
41651
  updated: external_exports.boolean()
41672
41652
  });
41673
41653
 
@@ -46731,15 +46711,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
46731
46711
  }
46732
46712
  function makeActionEnvelope(parts) {
46733
46713
  const envelope = {
46734
- sessionId: parts.sessionId,
46714
+ renderId: parts.renderId,
46735
46715
  type: parts.type
46736
46716
  };
46737
46717
  if (parts.payload !== void 0)
46738
46718
  envelope.payload = parts.payload;
46739
- if (parts.stackIndex !== void 0)
46740
- envelope.stackIndex = parts.stackIndex;
46741
- if (parts.stackItemId !== void 0)
46742
- envelope.stackItemId = parts.stackItemId;
46743
46719
  if (parts.clientSeq !== void 0)
46744
46720
  envelope.clientSeq = parts.clientSeq;
46745
46721
  const stamp = resolveSchemaVersion(parts);
@@ -47158,12 +47134,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
47158
47134
  });
47159
47135
  }
47160
47136
  break;
47161
- case "push_started":
47162
- requireString("stackItemId");
47137
+ case "render_started":
47138
+ requireString("renderId");
47163
47139
  requireString("intent");
47164
47140
  break;
47165
47141
  case "consume_polling":
47166
- requireString("stackItemId");
47142
+ requireString("renderId");
47167
47143
  if (p.state !== "open") {
47168
47144
  violations.push({
47169
47145
  field: "state",
@@ -47177,7 +47153,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
47177
47153
  violations.push({
47178
47154
  field: "kind",
47179
47155
  message: `Unknown lifecycle kind '${p.kind}'. Closed union; new kinds bump protocol version.`,
47180
- expected: "'handshake_started' | 'handshake_completed' | 'push_started' | 'consume_polling'",
47156
+ expected: "'handshake_started' | 'handshake_completed' | 'render_started' | 'consume_polling'",
47181
47157
  received: p.kind
47182
47158
  });
47183
47159
  }
@@ -47295,7 +47271,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
47295
47271
 
47296
47272
  // ../protocol/dist/bridge/invoke-agent.js
47297
47273
  var agentResponseSchema = external_exports.object({
47298
- sessionId: external_exports.string().optional(),
47274
+ hostSessionId: external_exports.string().optional(),
47299
47275
  text: external_exports.string().optional(),
47300
47276
  events: external_exports.array(external_exports.object({
47301
47277
  type: external_exports.string(),
@@ -50217,7 +50193,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50217
50193
  "useStream",
50218
50194
  "useAuth",
50219
50195
  "useApp",
50220
- "useSession",
50196
+ "useRender",
50221
50197
  // `useGguiContext` is the contextSpec hook every generated
50222
50198
  // component imports for declared context slots.
50223
50199
  "useGguiContext",
@@ -50650,7 +50626,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
50650
50626
  window.__ggui_test_dispatches__ = dispatches;
50651
50627
  const wireConfig = {
50652
50628
  app: { appId: "vt-app", appName: "vt-app" },
50653
- session: { sessionId: "vt-session", isConnected: true },
50629
+ render: { renderId: "vt-render", isConnected: true },
50654
50630
  auth: { isAuthenticated: false },
50655
50631
  dispatch: (actionName, data) => {
50656
50632
  dispatches.push({ actionName, data, t: Date.now() });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/ui-visual-tester",
3
- "version": "0.1.0-rc.3",
3
+ "version": "0.2.0-alpha.1",
4
4
  "description": "Behavioral validator for ggui-generated component code. Renders a component in real Chromium via Playwright, clicks each action declared in its contract, and verifies the action actually does something — mutating bound state or dispatching to the agent. Catches buttons wired to no-op handlers that structural validators miss. Playwright is an optional peer dependency, injected by the caller.",
5
5
  "keywords": [
6
6
  "ggui",
@@ -48,9 +48,9 @@
48
48
  "dependencies": {
49
49
  "react": "^19.0.0",
50
50
  "react-dom": "^19.0.0",
51
- "@ggui-ai/design": "0.1.0-rc.3",
52
- "@ggui-ai/protocol": "0.1.0-rc.3",
53
- "@ggui-ai/wire": "0.1.0-rc.3"
51
+ "@ggui-ai/design": "0.2.0-alpha.1",
52
+ "@ggui-ai/wire": "0.2.0-alpha.1",
53
+ "@ggui-ai/protocol": "0.2.0-alpha.1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@playwright/test": "^1.58.0",