@ggui-ai/ui-gen 0.10.0 → 0.11.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.
@@ -2,7 +2,7 @@ import { GeneratorTier, UiGenerator } from '@ggui-ai/mcp-server-core';
2
2
  import { JsonObject } from '@ggui-ai/protocol';
3
3
  import { BehaviorFailure, PlaywrightModule } from '@ggui-ai/ui-visual-tester';
4
4
  import { C as CreateUiGeneratorOptions } from '../create-ui-generator-CF0EL0Li.js';
5
- import { R as RenderCheckIssue } from '../render-check-BNYGVDJd.js';
5
+ import { R as RenderCheckIssue } from '../render-check-BZoIE8-u.js';
6
6
  import '@ggui-ai/gadgets';
7
7
  import '../types-public-DIpjC-OA.js';
8
8
  import '../axes-CzLEMDeB.js';
@@ -3,22 +3,22 @@ import * as esbuild2 from 'esbuild';
3
3
  import { build } from 'esbuild';
4
4
  import Anthropic from '@anthropic-ai/sdk';
5
5
  import { classifyUi, MODEL_REGISTRY, DANGEROUS_PATTERNS as DANGEROUS_PATTERNS$1, listContractGadgets, HOOK_NAME_RE, STDLIB_GADGETS_PACKAGE, resolveAppGadgets } from '@ggui-ai/protocol';
6
- import fs, { mkdirSync, writeFileSync, unlinkSync, readFileSync, existsSync, rm, createReadStream, createWriteStream } from 'fs';
6
+ import fs, { mkdirSync, writeFileSync, unlinkSync, existsSync, readFileSync, rm, createReadStream, createWriteStream } from 'fs';
7
7
  import { contentHash } from '@ggui-ai/protocol/content-hash';
8
8
  import ts7 from 'typescript';
9
9
  import path, { dirname, resolve, join, basename } from 'path';
10
10
  import { createRequire } from 'module';
11
11
  import { Linter } from 'eslint';
12
+ import { fileURLToPath, pathToFileURL } from 'url';
13
+ import { runSandboxed } from '@ggui-ai/sandbox';
12
14
  import { createHash } from 'crypto';
13
15
  import 'fs/promises';
14
16
  import { tmpdir } from 'os';
15
17
  import { Readable } from 'stream';
16
18
  import { pipeline } from 'stream/promises';
17
19
  import { createBrotliDecompress, createUnzip } from 'zlib';
18
- import { fileURLToPath, pathToFileURL } from 'url';
19
20
  import { PlaywrightNotAvailableError, validateContractBehavior } from '@ggui-ai/ui-visual-tester';
20
21
  import { parseGeneratorSlug, formatGeneratorSlug, isValidGeneratorSlug } from '@ggui-ai/mcp-server-core';
21
- import { runSandboxed } from '@ggui-ai/sandbox';
22
22
  import git from 'isomorphic-git';
23
23
  import { Volume, createFsFromVolume } from 'memfs';
24
24
  import { createPatch, applyPatch } from 'diff';
@@ -5442,6 +5442,140 @@ var init_policy2 = __esm({
5442
5442
  }
5443
5443
  });
5444
5444
 
5445
+ // src/harness/check/runtime-render/render-check-host.ts
5446
+ var render_check_host_exports = {};
5447
+ __export(render_check_host_exports, {
5448
+ mapSandboxResultToCheckResult: () => mapSandboxResultToCheckResult,
5449
+ runRenderCheckViaWorker: () => runRenderCheckViaWorker
5450
+ });
5451
+ function resolveWorkerSpawn2() {
5452
+ const jsCandidates = [
5453
+ // Sibling — when import.meta.url is already .../harness/check/runtime-render/.
5454
+ new URL(`./${WORKER_BASENAME}.js`, import.meta.url),
5455
+ // From dist/index.js.
5456
+ new URL(`./harness/check/runtime-render/${WORKER_BASENAME}.js`, import.meta.url),
5457
+ // From dist/harness/index.js.
5458
+ new URL(`./check/runtime-render/${WORKER_BASENAME}.js`, import.meta.url),
5459
+ // From dist/check/index.js, dist/advanced/index.js, dist/<flat>.js.
5460
+ new URL(`../harness/check/runtime-render/${WORKER_BASENAME}.js`, import.meta.url)
5461
+ ];
5462
+ for (const jsUrl of jsCandidates) {
5463
+ const jsPath = fileURLToPath(jsUrl);
5464
+ if (existsSync(jsPath)) {
5465
+ return { command: process.execPath, args: [jsPath] };
5466
+ }
5467
+ }
5468
+ const tsCandidates = [
5469
+ new URL(`./${WORKER_BASENAME}.ts`, import.meta.url),
5470
+ new URL(`../harness/check/runtime-render/${WORKER_BASENAME}.ts`, import.meta.url)
5471
+ ];
5472
+ for (const tsUrl of tsCandidates) {
5473
+ const tsPath = fileURLToPath(tsUrl);
5474
+ if (existsSync(tsPath)) {
5475
+ const require_ = createRequire(import.meta.url);
5476
+ const tsxLoader = pathToFileURL(require_.resolve("tsx")).href;
5477
+ return { command: process.execPath, args: ["--import", tsxLoader, tsPath] };
5478
+ }
5479
+ }
5480
+ const tried = [...jsCandidates, ...tsCandidates].map((u) => fileURLToPath(u)).join(", ");
5481
+ throw new Error(
5482
+ `render-check: isolated worker not found at any of: ${tried}. Did \`pnpm build\` run?`
5483
+ );
5484
+ }
5485
+ function failed(reason, t0) {
5486
+ return {
5487
+ ok: false,
5488
+ issues: [{ check: "render-no-throw", outcome: "failed", reason }],
5489
+ stats: { actionsChecked: 0, streamsChecked: 0, renderMs: Date.now() - t0 }
5490
+ };
5491
+ }
5492
+ function unverified(reason, t0) {
5493
+ return {
5494
+ ok: false,
5495
+ issues: [{ check: "render-no-throw", outcome: "unverified", reason }],
5496
+ stats: { actionsChecked: 0, streamsChecked: 0, renderMs: Date.now() - t0 }
5497
+ };
5498
+ }
5499
+ function mapSandboxResultToCheckResult(result, t0) {
5500
+ if (result.outcome === "timeout") {
5501
+ return failed(
5502
+ `render check timed out after ${CHECK_TIMEOUT_MS}ms in the isolated worker (likely infinite loop or runaway effect in the component).`,
5503
+ t0
5504
+ );
5505
+ }
5506
+ if (result.outcome === "overflow-stdout" || result.outcome === "overflow-stderr") {
5507
+ return failed(
5508
+ `render check worker produced excessive output (${result.outcome}) \u2014 the component is likely in a pathological logging or error loop.`,
5509
+ t0
5510
+ );
5511
+ }
5512
+ if (result.outcome === "spawn-error") {
5513
+ return unverified(
5514
+ `render check worker failed to start \u2014 ${result.errorMessage}`,
5515
+ t0
5516
+ );
5517
+ }
5518
+ if (result.outcome === "canceled") {
5519
+ return unverified("render check worker was canceled before completing.", t0);
5520
+ }
5521
+ if (result.outcome !== "exit") {
5522
+ return unverified(
5523
+ `render check worker ended with unexpected sandbox outcome '${result.outcome}'.`,
5524
+ t0
5525
+ );
5526
+ }
5527
+ if (result.exitCode !== 0) {
5528
+ const tail = result.stderr.trim() || result.stdout.trim();
5529
+ return unverified(
5530
+ `render check worker exited ${result.exitCode}${tail ? ` \u2014 ${tail.slice(0, 600)}` : ""}`,
5531
+ t0
5532
+ );
5533
+ }
5534
+ const stdout = result.stdout.trim();
5535
+ if (stdout.length === 0) {
5536
+ return unverified("render check worker exited without producing a verdict.", t0);
5537
+ }
5538
+ try {
5539
+ return JSON.parse(stdout);
5540
+ } catch (err) {
5541
+ return unverified(
5542
+ `render check worker verdict was not valid JSON \u2014 ${err instanceof Error ? err.message : String(err)}`,
5543
+ t0
5544
+ );
5545
+ }
5546
+ }
5547
+ async function runRenderCheckViaWorker(input) {
5548
+ const t0 = Date.now();
5549
+ let spawn;
5550
+ try {
5551
+ spawn = resolveWorkerSpawn2();
5552
+ } catch (err) {
5553
+ return unverified(err instanceof Error ? err.message : String(err), t0);
5554
+ }
5555
+ const result = await runSandboxed({
5556
+ command: spawn.command,
5557
+ args: spawn.args,
5558
+ timeoutMs: CHECK_TIMEOUT_MS,
5559
+ maxStdoutBytes: CHECK_STDOUT_CAP,
5560
+ nodeHeapMb: CHECK_NODE_HEAP_MB,
5561
+ stdin: JSON.stringify(input),
5562
+ // NODE_ENV steers React's production vs development build — keep
5563
+ // parity with the caller; everything else stays on the sandbox's
5564
+ // default allowlist.
5565
+ env: { NODE_ENV: process.env.NODE_ENV ?? "production" }
5566
+ });
5567
+ return mapSandboxResultToCheckResult(result, t0);
5568
+ }
5569
+ var CHECK_TIMEOUT_MS, CHECK_STDOUT_CAP, CHECK_NODE_HEAP_MB, WORKER_BASENAME;
5570
+ var init_render_check_host = __esm({
5571
+ "src/harness/check/runtime-render/render-check-host.ts"() {
5572
+ CHECK_TIMEOUT_MS = 3e4;
5573
+ CHECK_STDOUT_CAP = 2 * 1024 * 1024;
5574
+ CHECK_NODE_HEAP_MB = 512;
5575
+ WORKER_BASENAME = "render-check-worker";
5576
+ }
5577
+ });
5578
+
5445
5579
  // src/harness/hashline.ts
5446
5580
  var hashline_exports = {};
5447
5581
  __export(hashline_exports, {
@@ -15523,8 +15657,8 @@ ${cjsResult.code}
15523
15657
  // src/harness/check/runtime-render/load-component.ts
15524
15658
  async function loadComponent(input) {
15525
15659
  const { sourceCode, moduleResolutions = {} } = input;
15526
- const { createRequire: createRequire4 } = await import('module');
15527
- const require_ = createRequire4(import.meta.url);
15660
+ const { createRequire: createRequire5 } = await import('module');
15661
+ const require_ = createRequire5(import.meta.url);
15528
15662
  const sandboxRequire = (id) => {
15529
15663
  if (id in moduleResolutions) return moduleResolutions[id];
15530
15664
  if (id === "react/jsx-runtime" || id === "react/jsx-dev-runtime") {
@@ -15883,6 +16017,14 @@ function parentLink(node) {
15883
16017
 
15884
16018
  // src/harness/check/runtime-render/render-check.ts
15885
16019
  async function runRenderCheck(input) {
16020
+ const g = hostGlobals();
16021
+ if ("window" in g && "document" in g) {
16022
+ return runRenderCheckInProcess(input);
16023
+ }
16024
+ const { runRenderCheckViaWorker: runRenderCheckViaWorker2 } = await Promise.resolve().then(() => (init_render_check_host(), render_check_host_exports));
16025
+ return runRenderCheckViaWorker2(input);
16026
+ }
16027
+ async function runRenderCheckInProcess(input) {
15886
16028
  const t0 = Date.now();
15887
16029
  const issues = [];
15888
16030
  const teardown = await setupHappyDom();
@@ -19826,12 +19968,12 @@ async function runSlowStage(input) {
19826
19968
  };
19827
19969
  }
19828
19970
  function scoreFromRenderCheck(issues) {
19829
- const failed = issues.filter((i) => i.outcome === "failed").length;
19830
- const unverified = issues.filter((i) => i.outcome === "unverified").length;
19831
- if (failed === 0 && unverified === 0) return 1;
19832
- if (failed === 0) return 0.85;
19833
- if (failed === 1) return 0.4;
19834
- if (failed === 2) return 0.3;
19971
+ const failed2 = issues.filter((i) => i.outcome === "failed").length;
19972
+ const unverified2 = issues.filter((i) => i.outcome === "unverified").length;
19973
+ if (failed2 === 0 && unverified2 === 0) return 1;
19974
+ if (failed2 === 0) return 0.85;
19975
+ if (failed2 === 1) return 0.4;
19976
+ if (failed2 === 2) return 0.3;
19835
19977
  return 0.2;
19836
19978
  }
19837
19979
  function scoreFromSlowStage(contract, failures) {