@ggui-ai/ui-gen 0.8.0 → 0.10.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 (100) hide show
  1. package/dist/adapters/generation-dispatch.d.ts +18 -1
  2. package/dist/adapters/generation-dispatch.js +819 -1577
  3. package/dist/adapters/generation-dispatch.js.map +1 -1
  4. package/dist/adapters/index.js +28 -11
  5. package/dist/adapters/index.js.map +1 -1
  6. package/dist/advanced/index.d.ts +5 -3
  7. package/dist/advanced/index.js +838 -1579
  8. package/dist/advanced/index.js.map +1 -1
  9. package/dist/blueprint-validator.js +109 -3
  10. package/dist/blueprint-validator.js.map +1 -1
  11. package/dist/boilerplate.js +17 -4
  12. package/dist/boilerplate.js.map +1 -1
  13. package/dist/check/index.d.ts +1 -1
  14. package/dist/check/index.js +11 -1
  15. package/dist/check/index.js.map +1 -1
  16. package/dist/compose.js +5 -5
  17. package/dist/compose.js.map +1 -1
  18. package/dist/{create-ui-generator-GX7tvbyH.d.ts → create-ui-generator-CF0EL0Li.d.ts} +26 -1
  19. package/dist/{dispatch-Deo9qzrG.d.ts → dispatch-D75M-OfZ.d.ts} +1 -1
  20. package/dist/evaluation/axis-checks/index.d.ts +3 -3
  21. package/dist/evaluation/axis-checks/index.js +133 -1
  22. package/dist/evaluation/axis-checks/index.js.map +1 -1
  23. package/dist/evaluation/axis-checks/registry.d.ts +1 -1
  24. package/dist/evaluation/axis-checks/registry.js +133 -1
  25. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  26. package/dist/evaluation/index.d.ts +46 -3
  27. package/dist/evaluation/index.js +410 -24
  28. package/dist/evaluation/index.js.map +1 -1
  29. package/dist/fragments/index.js +5 -5
  30. package/dist/fragments/index.js.map +1 -1
  31. package/dist/harness/check/runtime-render/index.d.ts +2 -2
  32. package/dist/harness/check/runtime-render/index.js +110 -3
  33. package/dist/harness/check/runtime-render/index.js.map +1 -1
  34. package/dist/harness/index.d.ts +5 -126
  35. package/dist/harness/index.js +292 -32
  36. package/dist/harness/index.js.map +1 -1
  37. package/dist/harness/llm-trace-sink.d.ts +1 -1
  38. package/dist/harness/llm-trace-sink.js.map +1 -1
  39. package/dist/harness/prompts.js +17 -3
  40. package/dist/harness/prompts.js.map +1 -1
  41. package/dist/harness/result-types.d.ts +1 -1
  42. package/dist/harness/runtime.d.ts +17 -1
  43. package/dist/harness/runtime.js +23 -8
  44. package/dist/harness/runtime.js.map +1 -1
  45. package/dist/harness/types-public.d.ts +1 -1
  46. package/dist/harness/types-public.js +22 -9
  47. package/dist/harness/types-public.js.map +1 -1
  48. package/dist/harness/validator-trace-sink.d.ts +1 -1
  49. package/dist/index.d.ts +5 -3
  50. package/dist/index.js +838 -1579
  51. package/dist/index.js.map +1 -1
  52. package/dist/llm-router-BEVtbAb9.d.ts +213 -0
  53. package/dist/patch.d.ts +1 -1
  54. package/dist/provider-adapter.d.ts +16 -6
  55. package/dist/provider-adapter.js.map +1 -1
  56. package/dist/providers/index.d.ts +54 -99
  57. package/dist/providers/index.js +13 -8
  58. package/dist/providers/index.js.map +1 -1
  59. package/dist/{render-check-CNZjHD5g.d.ts → render-check-BNYGVDJd.d.ts} +1 -1
  60. package/dist/{types-public-C36k1q6s.d.ts → types-public-DIpjC-OA.d.ts} +1 -1
  61. package/dist/validation/index.js +2 -2
  62. package/dist/validation/index.js.map +1 -1
  63. package/dist/workflows.d.ts +1 -1
  64. package/package.json +18 -18
  65. package/src/adapters/generation-dispatch.ts +28 -2
  66. package/src/adapters/openrouter/client.ts +2 -2
  67. package/src/adapters/openrouter/types.ts +10 -0
  68. package/src/boilerplate/generate.ts +10 -2
  69. package/src/boilerplate/json-schema-ts.ts +22 -2
  70. package/src/boilerplate/system-prompt.ts +4 -2
  71. package/src/compile.ts +1 -1
  72. package/src/contract-context.ts +10 -2
  73. package/src/create-ui-generator.ts +58 -11
  74. package/src/design-system-docs.ts +6 -4
  75. package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
  76. package/src/evaluation/axis-checks/checks/state-ui-affordance.ts +162 -0
  77. package/src/evaluation/axis-checks/checks/universal.ts +39 -0
  78. package/src/evaluation/axis-checks/registry.ts +2 -0
  79. package/src/evaluation/index.ts +11 -0
  80. package/src/evaluation/llm-evaluator.ts +26 -3
  81. package/src/evaluation/visual-evaluator.ts +49 -66
  82. package/src/fragments/realtime.ts +3 -3
  83. package/src/fragments/state.ts +2 -2
  84. package/src/harness/check/runtime-render/adapter.ts +18 -0
  85. package/src/harness/check/runtime-render/index.ts +8 -0
  86. package/src/harness/check/runtime-render/prepare-mockup.ts +14 -0
  87. package/src/harness/check/runtime-render/production-act-shim.ts +158 -0
  88. package/src/harness/check/runtime-render/render-check.ts +72 -1
  89. package/src/harness/coding/init-session.ts +4 -1
  90. package/src/harness/coding/run-eval-round.ts +67 -5
  91. package/src/harness/index.ts +1 -1
  92. package/src/harness/llm-router.ts +451 -27
  93. package/src/harness/llm-trace-sink.ts +2 -1
  94. package/src/harness/runtime.ts +15 -0
  95. package/src/index.ts +5 -5
  96. package/src/provider-adapter.ts +16 -6
  97. package/src/providers/bedrock.ts +89 -26
  98. package/src/providers/index.ts +16 -4
  99. package/src/tools/render-check.ts +19 -7
  100. package/src/validation/ui-compiler.ts +2 -2
@@ -1,4 +1,4 @@
1
- import { A as AxisCheck } from '../../types-public-C36k1q6s.js';
1
+ import { A as AxisCheck } from '../../types-public-DIpjC-OA.js';
2
2
  import '@ggui-ai/protocol';
3
3
  import '../../axes-CzLEMDeB.js';
4
4
  import '../../types-BOvHNG7K.js';
@@ -235,6 +235,31 @@ function runNoPhantomUseState(input) {
235
235
  }
236
236
  return issues;
237
237
  }
238
+ function runPropSeedNoResync(input) {
239
+ if (input.compiledCode === null) return [];
240
+ const src = input.sourceCode;
241
+ const issues = [];
242
+ const re = /const\s*\[\s*(\w+)\s*,\s*(\w+)\s*\]\s*=\s*useState(?:<[^>]*>)?\s*\(\s*props\??\.(\w+)/g;
243
+ for (const m of src.matchAll(re)) {
244
+ const [full, stateVar, setter, propName] = m;
245
+ const idx = m.index ?? 0;
246
+ const after = src.slice(idx + full.length);
247
+ if (!new RegExp(`\\b${setter}\\s*\\(`).test(after)) continue;
248
+ const resync = new RegExp(
249
+ `\\[[^\\[\\]]*props\\??\\.${propName}\\b[^\\[\\]]*\\]`
250
+ );
251
+ if (resync.test(src)) continue;
252
+ issues.push(
253
+ mkIssue(
254
+ "universal.prop_seed_no_resync",
255
+ `useState(props.${propName}) seeds "${stateVar}" and mutates it, but no effect depends on [props.${propName}] \u2014 a ggui_amend repaint pushes new props that never reach this display (#480).`,
256
+ `Add \`useEffect(() => ${setter}(props.${propName}), [props.${propName}]);\` so agent repaints re-seed the state, or derive the display directly from props.${propName}.`,
257
+ "warn"
258
+ )
259
+ );
260
+ }
261
+ return issues;
262
+ }
238
263
  var UNIVERSAL_CHECKS = [
239
264
  {
240
265
  id: "universal.prop_coverage",
@@ -253,6 +278,12 @@ var UNIVERSAL_CHECKS = [
253
278
  axis: "render",
254
279
  values: ALL_RENDER_VALUES,
255
280
  run: runNoPhantomUseState
281
+ },
282
+ {
283
+ id: "universal.prop_seed_no_resync",
284
+ axis: "render",
285
+ values: ALL_RENDER_VALUES,
286
+ run: runPropSeedNoResync
256
287
  }
257
288
  ];
258
289
 
@@ -272,7 +303,7 @@ function runStateSeededFromProps(input) {
272
303
  mkIssue(
273
304
  "state.merge.seeded_from_props",
274
305
  `Entity collection "${e.name}" is not seeded from props \u2014 no useState initializer reads props.${e.name}.`,
275
- `Add \`const [${e.name}, set${cap(e.name)}] = useState(props.${e.name});\` so stream/action updates can merge into live state.`
306
+ `Add \`const [${e.name}, set${cap(e.name)}] = useState(props.${e.name});\` paired with \`useEffect(() => set${cap(e.name)}(props.${e.name}), [props.${e.name}]);\` so stream/action updates merge into live state AND agent repaints (ggui_amend) re-seed it (#480).`
276
307
  )
277
308
  );
278
309
  }
@@ -376,6 +407,106 @@ var STATE_MERGE_CHECKS = [
376
407
  }
377
408
  ];
378
409
 
410
+ // src/evaluation/axis-checks/checks/state-ui-affordance.ts
411
+ var STATE_ARIA_OR_ROLE = /aria-(checked|pressed|selected|expanded|current)\s*=|role\s*=/;
412
+ var STATE_PRIMITIVE_IN_SUBTREE = /<(Checkbox|Toggle|Tabs|Accordion)[\s/>]/;
413
+ var SEMANTIC_PRIMITIVES = /* @__PURE__ */ new Set(["Button", "Checkbox", "Toggle", "Link", "MenuItem"]);
414
+ function collectSetters(src) {
415
+ const setters = /* @__PURE__ */ new Set();
416
+ for (const m of src.matchAll(/const\s*\[\s*\w+\s*,\s*(set\w+)\s*\]\s*=\s*useState/g)) {
417
+ setters.add(m[1]);
418
+ }
419
+ return setters;
420
+ }
421
+ function collectHandlers(src, setters) {
422
+ const handlers = /* @__PURE__ */ new Set();
423
+ for (const m of src.matchAll(/const\s+(\w+)\s*=\s*(?:\([^)]*\)|\w+)\s*=>\s*\{?/g)) {
424
+ const body = src.slice(m.index + m[0].length, m.index + m[0].length + 400);
425
+ for (const s of setters) {
426
+ if (body.includes(s)) {
427
+ handlers.add(m[1]);
428
+ break;
429
+ }
430
+ }
431
+ }
432
+ return handlers;
433
+ }
434
+ function attrBlock(src, start) {
435
+ let depth = 0;
436
+ for (let i = start; i < src.length; i++) {
437
+ const c = src[i];
438
+ if (c === "{") depth++;
439
+ else if (c === "}") depth--;
440
+ else if (c === ">" && depth === 0) return { block: src.slice(start, i), end: i };
441
+ }
442
+ return { block: src.slice(start, start + 900), end: start + 900 };
443
+ }
444
+ function onClickValue(block) {
445
+ const m = block.match(/onClick\s*=\s*\{/);
446
+ if (!m || m.index === void 0) return null;
447
+ const open = m.index + m[0].length - 1;
448
+ let depth = 0;
449
+ for (let i = open; i < block.length; i++) {
450
+ if (block[i] === "{") depth++;
451
+ else if (block[i] === "}") {
452
+ depth--;
453
+ if (depth === 0) return block.slice(open + 1, i);
454
+ }
455
+ }
456
+ return block.slice(open + 1);
457
+ }
458
+ function subtree(src, pos, tag) {
459
+ const close = src.indexOf(`</${tag}>`, pos);
460
+ return src.slice(pos, close === -1 ? pos + 700 : close);
461
+ }
462
+ function runStateAriaPresent(input) {
463
+ if (input.compiledCode === null) return [];
464
+ const src = input.sourceCode;
465
+ const setters = collectSetters(src);
466
+ const handlers = collectHandlers(src, setters);
467
+ const issues = [];
468
+ const flaggedLines = /* @__PURE__ */ new Set();
469
+ const localComponents = /* @__PURE__ */ new Set();
470
+ for (const m of src.matchAll(/(?:function\s+([A-Z]\w*)\s*\(|const\s+([A-Z]\w*)\s*=)/g)) {
471
+ localComponents.add(m[1] ?? m[2]);
472
+ }
473
+ for (const m of src.matchAll(/<([A-Za-z][A-Za-z0-9]*)\b/g)) {
474
+ const tag = m[1];
475
+ if (m.index === void 0) continue;
476
+ if (localComponents.has(tag)) continue;
477
+ const { block, end } = attrBlock(src, m.index + m[0].length);
478
+ const clickValue = onClickValue(block);
479
+ if (clickValue === null) continue;
480
+ const mutatesAffordance = [...setters].some((s) => clickValue.includes(s)) || [...handlers].some((h) => new RegExp(`\\b${h}\\b`).test(clickValue)) || // Extracted-subcomponent shape: the toggle handler arrives as an
481
+ // `on[A-Z]…` callback prop and is invoked from onClick — inside a
482
+ // ui-affordance component that IS the affordance mutation.
483
+ /\bon[A-Z]\w*\b/.test(clickValue);
484
+ if (!mutatesAffordance) continue;
485
+ if (SEMANTIC_PRIMITIVES.has(tag)) continue;
486
+ if (STATE_ARIA_OR_ROLE.test(block)) continue;
487
+ if (STATE_PRIMITIVE_IN_SUBTREE.test(subtree(src, end, tag))) continue;
488
+ const line = src.slice(0, m.index).split("\n").length;
489
+ if (flaggedLines.has(line)) continue;
490
+ flaggedLines.add(line);
491
+ issues.push(
492
+ mkIssue(
493
+ "state.ui_affordance.state_aria_present",
494
+ `Line ${line}: <${tag}> toggles the UI affordance from its onClick but exposes no state ARIA \u2014 its checked/selected/expanded state is invisible to assistive technology (styling is the only carrier).`,
495
+ `Add the matching state attribute to the SAME element that carries the onClick: \`role="checkbox"\` + \`aria-checked={\u2026}\` for a toggle row, \`aria-pressed\` for a toggle button, \`aria-selected\` for a selection, \`aria-expanded\` for an open/close affordance \u2014 or replace the hand-rolled control with the state-carrying primitive (Checkbox / Toggle / Tabs / Accordion). \`as={Clickable}\` adds button + keyboard semantics but NOT state.`
496
+ )
497
+ );
498
+ }
499
+ return issues;
500
+ }
501
+ var STATE_UI_AFFORDANCE_CHECKS = [
502
+ {
503
+ id: "state.ui_affordance.state_aria_present",
504
+ axis: "state",
505
+ values: ["ui-affordance"],
506
+ run: runStateAriaPresent
507
+ }
508
+ ];
509
+
379
510
  // src/evaluation/axis-checks/checks/realtime.ts
380
511
  var REALTIME_ACTIVE = ["merge", "append", "status", "presence", "mixed"];
381
512
  function runStreamHandlerPerEvent(input) {
@@ -1065,6 +1196,7 @@ var EXTRA_CHECKS = [
1065
1196
  var REGISTRY = [
1066
1197
  ...UNIVERSAL_CHECKS,
1067
1198
  ...STATE_MERGE_CHECKS,
1199
+ ...STATE_UI_AFFORDANCE_CHECKS,
1068
1200
  ...REALTIME_CHECKS,
1069
1201
  ...WRITES_CHECKS,
1070
1202
  ...STATE_PAYLOAD_CHECKS,