@ggui-ai/ui-gen 0.9.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 (87) hide show
  1. package/dist/adapters/generation-dispatch.d.ts +9 -2
  2. package/dist/adapters/generation-dispatch.js +547 -85
  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 +563 -92
  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 +14 -2
  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/{create-ui-generator-B9kV4U9h.d.ts → create-ui-generator-CF0EL0Li.d.ts} +13 -1
  17. package/dist/{dispatch-Deo9qzrG.d.ts → dispatch-D75M-OfZ.d.ts} +1 -1
  18. package/dist/evaluation/axis-checks/index.d.ts +3 -3
  19. package/dist/evaluation/axis-checks/index.js +101 -0
  20. package/dist/evaluation/axis-checks/index.js.map +1 -1
  21. package/dist/evaluation/axis-checks/registry.d.ts +1 -1
  22. package/dist/evaluation/axis-checks/registry.js +101 -0
  23. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  24. package/dist/evaluation/index.d.ts +46 -3
  25. package/dist/evaluation/index.js +358 -17
  26. package/dist/evaluation/index.js.map +1 -1
  27. package/dist/harness/check/runtime-render/index.d.ts +2 -2
  28. package/dist/harness/check/runtime-render/index.js +110 -3
  29. package/dist/harness/check/runtime-render/index.js.map +1 -1
  30. package/dist/harness/index.d.ts +2 -2
  31. package/dist/harness/index.js +263 -18
  32. package/dist/harness/index.js.map +1 -1
  33. package/dist/harness/llm-trace-sink.d.ts +1 -1
  34. package/dist/harness/llm-trace-sink.js.map +1 -1
  35. package/dist/harness/prompts.js +17 -3
  36. package/dist/harness/prompts.js.map +1 -1
  37. package/dist/harness/result-types.d.ts +1 -1
  38. package/dist/harness/runtime.d.ts +9 -2
  39. package/dist/harness/runtime.js +20 -6
  40. package/dist/harness/runtime.js.map +1 -1
  41. package/dist/harness/types-public.d.ts +1 -1
  42. package/dist/harness/types-public.js +14 -2
  43. package/dist/harness/types-public.js.map +1 -1
  44. package/dist/harness/validator-trace-sink.d.ts +1 -1
  45. package/dist/index.d.ts +5 -3
  46. package/dist/index.js +563 -92
  47. package/dist/index.js.map +1 -1
  48. package/dist/{llm-router-1TyI0_TV.d.ts → llm-router-BEVtbAb9.d.ts} +61 -4
  49. package/dist/patch.d.ts +1 -1
  50. package/dist/provider-adapter.d.ts +16 -6
  51. package/dist/provider-adapter.js.map +1 -1
  52. package/dist/providers/index.d.ts +19 -6
  53. package/dist/providers/index.js.map +1 -1
  54. package/dist/{render-check-CNZjHD5g.d.ts → render-check-BNYGVDJd.d.ts} +1 -1
  55. package/dist/{types-public-C36k1q6s.d.ts → types-public-DIpjC-OA.d.ts} +1 -1
  56. package/dist/workflows.d.ts +1 -1
  57. package/package.json +12 -12
  58. package/src/adapters/generation-dispatch.ts +9 -0
  59. package/src/adapters/openrouter/client.ts +2 -2
  60. package/src/adapters/openrouter/types.ts +10 -0
  61. package/src/boilerplate/generate.ts +10 -2
  62. package/src/boilerplate/json-schema-ts.ts +22 -2
  63. package/src/boilerplate/system-prompt.ts +1 -0
  64. package/src/compile.ts +1 -1
  65. package/src/contract-context.ts +10 -2
  66. package/src/create-ui-generator.ts +14 -0
  67. package/src/design-system-docs.ts +6 -4
  68. package/src/evaluation/axis-checks/checks/state-ui-affordance.ts +162 -0
  69. package/src/evaluation/axis-checks/registry.ts +2 -0
  70. package/src/evaluation/index.ts +11 -0
  71. package/src/evaluation/llm-evaluator.ts +14 -1
  72. package/src/evaluation/visual-evaluator.ts +44 -65
  73. package/src/harness/check/runtime-render/adapter.ts +18 -0
  74. package/src/harness/check/runtime-render/index.ts +8 -0
  75. package/src/harness/check/runtime-render/prepare-mockup.ts +14 -0
  76. package/src/harness/check/runtime-render/production-act-shim.ts +158 -0
  77. package/src/harness/check/runtime-render/render-check.ts +72 -1
  78. package/src/harness/coding/run-eval-round.ts +61 -5
  79. package/src/harness/index.ts +1 -1
  80. package/src/harness/llm-router.ts +397 -18
  81. package/src/harness/llm-trace-sink.ts +2 -1
  82. package/src/harness/runtime.ts +7 -0
  83. package/src/index.ts +5 -5
  84. package/src/provider-adapter.ts +16 -6
  85. package/src/providers/bedrock.ts +5 -4
  86. package/src/providers/index.ts +16 -4
  87. package/src/tools/render-check.ts +19 -7
@@ -1,9 +1,9 @@
1
- export { R as RenderCheckIssue, a as RenderCheckResult, r as runRenderCheck } from '../../../render-check-CNZjHD5g.js';
1
+ export { R as RenderCheckIssue, a as RenderCheckResult, r as runRenderCheck } from '../../../render-check-BNYGVDJd.js';
2
2
  import { WireConfig } from '@ggui-ai/wire';
3
3
  import { JsonObject, DataContract } from '@ggui-ai/protocol';
4
4
  import { RuntimeRenderCheck } from '../../types-public.js';
5
5
  import '../../../axes-CzLEMDeB.js';
6
- import '../../../types-public-C36k1q6s.js';
6
+ import '../../../types-public-DIpjC-OA.js';
7
7
  import '../../../types-BOvHNG7K.js';
8
8
  import '../../../llm.js';
9
9
  import '../../../policy.js';
@@ -1,7 +1,49 @@
1
+ import { createRequire } from 'module';
1
2
  import { listContractGadgets, HOOK_NAME_RE } from '@ggui-ai/protocol';
2
3
  import ts from 'typescript';
3
4
 
4
- // src/harness/check/runtime-render/render-check.ts
5
+ // src/harness/check/runtime-render/production-act-shim.ts
6
+ var installed = false;
7
+ function installProductionActShim() {
8
+ if (installed) return;
9
+ installed = true;
10
+ const require_ = createRequire(import.meta.url);
11
+ let reactCjs;
12
+ try {
13
+ reactCjs = require_("react");
14
+ } catch {
15
+ return;
16
+ }
17
+ if (typeof reactCjs.act === "function") {
18
+ return;
19
+ }
20
+ try {
21
+ const testUtils = require_("react-dom/test-utils");
22
+ const reactDom = require_("react-dom");
23
+ testUtils.act = createFlushSyncAct(reactDom.flushSync);
24
+ } catch {
25
+ }
26
+ }
27
+ function createFlushSyncAct(flushSync) {
28
+ return (callback) => {
29
+ let callbackResult;
30
+ flushSync(() => {
31
+ callbackResult = callback();
32
+ });
33
+ if (isThenable(callbackResult)) {
34
+ const pending = callbackResult;
35
+ return new Promise((resolve, reject) => {
36
+ pending.then(() => resolve(), reject);
37
+ });
38
+ }
39
+ return new Promise((resolve) => {
40
+ queueMicrotask(resolve);
41
+ });
42
+ };
43
+ }
44
+ function isThenable(value) {
45
+ return typeof value === "object" && value !== null && typeof value.then === "function";
46
+ }
5
47
 
6
48
  // src/harness/check/runtime-render/probe.ts
7
49
  function makeInternals() {
@@ -163,8 +205,8 @@ ${cjsResult.code}
163
205
  // src/harness/check/runtime-render/load-component.ts
164
206
  async function loadComponent(input) {
165
207
  const { sourceCode, moduleResolutions = {} } = input;
166
- const { createRequire } = await import('module');
167
- const require_ = createRequire(import.meta.url);
208
+ const { createRequire: createRequire2 } = await import('module');
209
+ const require_ = createRequire2(import.meta.url);
168
210
  const sandboxRequire = (id) => {
169
211
  if (id in moduleResolutions) return moduleResolutions[id];
170
212
  if (id === "react/jsx-runtime" || id === "react/jsx-dev-runtime") {
@@ -537,6 +579,7 @@ async function runRenderCheck(input) {
537
579
  const probe = createProbe();
538
580
  const wireConfig = createProbeWireConfig(probe);
539
581
  uninstallSpy = probe.installPostMessageSpy();
582
+ installProductionActShim();
540
583
  const { render, cleanup } = await import('@testing-library/react');
541
584
  const userEventModule = await import('@testing-library/user-event');
542
585
  const userEvent = userEventModule.default ?? userEventModule;
@@ -692,6 +735,50 @@ async function runRenderCheck(input) {
692
735
  if (issue) issues.push(issue);
693
736
  }
694
737
  }
738
+ const declaredProps = input.contract?.propsSpec?.properties;
739
+ if (declaredProps) {
740
+ const optionalFilled = Object.entries(declaredProps).filter(
741
+ ([name, entry]) => entry.required !== true && input.mockupProps[name] !== void 0
742
+ ).map(([name]) => name);
743
+ if (optionalFilled.length > 0) {
744
+ const requiredOnlyProps = { ...input.mockupProps };
745
+ for (const name of optionalFilled) delete requiredOnlyProps[name];
746
+ const omitBoundaryRef = {};
747
+ class OmitErrorBoundary extends React.Component {
748
+ state = { caught: false };
749
+ static getDerivedStateFromError() {
750
+ return { caught: true };
751
+ }
752
+ componentDidCatch(error) {
753
+ omitBoundaryRef.error ??= error;
754
+ }
755
+ render() {
756
+ if (this.state.caught) return null;
757
+ return this.props.children;
758
+ }
759
+ }
760
+ try {
761
+ render(
762
+ React.createElement(GguiWireProvider, {
763
+ config: wireConfig,
764
+ children: React.createElement(OmitErrorBoundary, {
765
+ children: React.createElement(Component, requiredOnlyProps)
766
+ })
767
+ })
768
+ );
769
+ } catch (e) {
770
+ omitBoundaryRef.error ??= e instanceof Error ? e : new Error(String(e));
771
+ }
772
+ if (omitBoundaryRef.error) {
773
+ issues.push({
774
+ check: "optional-props-omitted",
775
+ outcome: "failed",
776
+ subject: optionalFilled.join(", "),
777
+ reason: `Render crashed when the optional prop(s) ${optionalFilled.map((n) => `'${n}'`).join(", ")} were omitted: ${omitBoundaryRef.error.message}. The contract marks them optional (no \`required: true\`), so a legitimate render may leave them out.`
778
+ });
779
+ }
780
+ }
781
+ }
695
782
  } finally {
696
783
  cleanup();
697
784
  }
@@ -1263,6 +1350,15 @@ function synthesizeFromSchema(schema, hint, warnings, depth) {
1263
1350
  if (schema.anyOf && schema.anyOf.length > 0) {
1264
1351
  return synthesizeFromSchema(schema.anyOf[0], hint, warnings, depth + 1);
1265
1352
  }
1353
+ if (Array.isArray(schema.type)) {
1354
+ const primary = schema.type.find((t) => t !== "null") ?? "null";
1355
+ return synthesizeFromSchema(
1356
+ { ...schema, type: primary },
1357
+ hint,
1358
+ warnings,
1359
+ depth + 1
1360
+ );
1361
+ }
1266
1362
  switch (schema.type) {
1267
1363
  case "string": {
1268
1364
  switch (schema.format) {
@@ -1433,6 +1529,16 @@ function toEvalIssue(issue) {
1433
1529
  description: `Component crashed at runtime: ${issue.reason}`,
1434
1530
  fix: classifyRenderCrashFix(issue.reason)
1435
1531
  };
1532
+ case "optional-props-omitted":
1533
+ return {
1534
+ tier: 0,
1535
+ result,
1536
+ category: "crash",
1537
+ subcategory,
1538
+ severity: "critical",
1539
+ description: `Component crashed when optional props were omitted: ${issue.reason}`,
1540
+ fix: `Guard every optional prop before member access (props.${subject.split(",")[0]?.trim() ?? "x"}?.map(...), a default via destructuring, or an early empty-state return). Optional props (no \`required: true\` in the contract) may be absent at runtime even though the harness fills them.`
1541
+ };
1436
1542
  case "action-wiring": {
1437
1543
  const fix = issue.outcome === "unverified" ? `Source shows the action callback flowing into a non-native or custom-component prop. If wiring is intentional (e.g., Dropdown.onChange, drag-drop), this warn is informational \u2014 manual/browser verification is required to confirm. Otherwise wire to a native onClick={() => ${subject}(payload)} on <button> or design-system <Button>.` : `Wire ${subject}() to a native event prop. Common fix: <Button onClick={() => ${subject}(payload)}>Label</Button>. Source-AST analysis didn't find this wiring in your JSX.`;
1438
1544
  return {
@@ -1479,6 +1585,7 @@ async function warmupRuntimeRenderProbe() {
1479
1585
  missing += 1;
1480
1586
  }
1481
1587
  };
1588
+ installProductionActShim();
1482
1589
  await Promise.all([
1483
1590
  tryLoad("happy-dom"),
1484
1591
  tryLoad("@testing-library/react"),