@ggui-ai/ui-gen 0.23.0 → 0.24.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.
- package/dist/adapter-Du7P_5Fx.d.ts +201 -0
- package/dist/adapters/generation-dispatch.d.ts +33 -12
- package/dist/adapters/generation-dispatch.js +510 -128
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/advanced/index.d.ts +5 -3
- package/dist/advanced/index.js +551 -142
- package/dist/advanced/index.js.map +1 -1
- package/dist/blueprint-validator.js +153 -59
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +2 -1
- package/dist/check/index.js +47 -1
- package/dist/check/index.js.map +1 -1
- package/dist/{create-ui-generator-D0kbWwln.d.ts → create-ui-generator-GIhzx08x.d.ts} +34 -10
- package/dist/{dispatch-wxaIMwZt.d.ts → dispatch-BnAH56p4.d.ts} +1 -1
- package/dist/evaluation/axis-checks/index.d.ts +4 -3
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +2 -1
- package/dist/evaluation/index.d.ts +4 -3
- package/dist/evaluation/index.js.map +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +29 -10
- package/dist/harness/check/runtime-render/index.js +203 -60
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/check/runtime-render/render-check-worker.d.ts +8 -1
- package/dist/harness/check/runtime-render/render-check-worker.js +72 -32
- package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
- package/dist/harness/index.d.ts +2 -1
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +2 -1
- package/dist/harness/runtime.d.ts +2 -1
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +11 -2
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +2 -1
- package/dist/index.d.ts +38 -3
- package/dist/index.js +553 -143
- package/dist/index.js.map +1 -1
- package/dist/patch.d.ts +2 -1
- package/dist/policy.d.ts +7 -4
- package/dist/policy.js.map +1 -1
- package/dist/tools/render-check-worker.d.ts +7 -1
- package/dist/tools/render-check-worker.js +55 -23
- package/dist/tools/render-check-worker.js.map +1 -1
- package/dist/{types-public-Ow-tNtFE.d.ts → types-public-Bk6d1WLN.d.ts} +77 -11
- package/dist/workflows.d.ts +2 -1
- package/package.json +12 -12
- package/src/adapters/generation-dispatch.ts +137 -96
- package/src/check/run-tier0.ts +80 -1
- package/src/create-ui-generator.ts +185 -95
- package/src/evaluation/types-public.ts +73 -11
- package/src/harness/check/runtime-render/adapter.ts +221 -75
- package/src/harness/check/runtime-render/index.ts +75 -2
- package/src/harness/check/runtime-render/render-check-host.ts +82 -19
- package/src/harness/check/runtime-render/render-check-worker.ts +83 -29
- package/src/harness/check/runtime-render/render-check.ts +154 -117
- package/src/harness/coding/generate-task-runner.ts +57 -4
- package/src/harness/coding/init-session.ts +13 -0
- package/src/harness/coding/run-eval-round.ts +238 -15
- package/src/harness/policy.ts +11 -0
- package/src/harness/primitive-slice.ts +104 -0
- package/src/harness/types-public.ts +9 -1
- package/src/index.ts +4 -0
- package/src/policy.ts +7 -4
- package/src/tools/render-check-worker.ts +74 -23
- package/dist/render-check-Blwj8gB6.d.ts +0 -105
|
@@ -20,9 +20,25 @@ var __export = (target, all) => {
|
|
|
20
20
|
// src/harness/check/runtime-render/render-check-host.ts
|
|
21
21
|
var render_check_host_exports = {};
|
|
22
22
|
__export(render_check_host_exports, {
|
|
23
|
+
DEFAULT_RENDER_CHECK_HOST_BOUNDS: () => DEFAULT_RENDER_CHECK_HOST_BOUNDS,
|
|
23
24
|
mapSandboxResultToCheckResult: () => mapSandboxResultToCheckResult,
|
|
25
|
+
resolveRenderCheckHostBounds: () => resolveRenderCheckHostBounds,
|
|
26
|
+
resolveWorkerSpawn: () => resolveWorkerSpawn,
|
|
24
27
|
runRenderCheckViaWorker: () => runRenderCheckViaWorker
|
|
25
28
|
});
|
|
29
|
+
function resolveRenderCheckHostBounds(bounds = {}) {
|
|
30
|
+
const timeoutMs = bounds.timeoutMs ?? DEFAULT_RENDER_CHECK_HOST_BOUNDS.timeoutMs;
|
|
31
|
+
const heapMb = bounds.heapMb ?? DEFAULT_RENDER_CHECK_HOST_BOUNDS.heapMb;
|
|
32
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs < 2) {
|
|
33
|
+
throw new RangeError(`render-check: timeoutMs must be an integer \u2265 2, got ${timeoutMs}`);
|
|
34
|
+
}
|
|
35
|
+
if (!Number.isInteger(heapMb) || heapMb < 1) {
|
|
36
|
+
throw new RangeError(`render-check: heapMb must be a positive integer, got ${heapMb}`);
|
|
37
|
+
}
|
|
38
|
+
const requestedGrace = bounds.gracePeriodMs ?? DEFAULT_RENDER_CHECK_HOST_BOUNDS.gracePeriodMs;
|
|
39
|
+
const gracePeriodMs = Math.max(1, Math.min(requestedGrace, Math.floor(timeoutMs / 2)));
|
|
40
|
+
return { timeoutMs, heapMb, gracePeriodMs };
|
|
41
|
+
}
|
|
26
42
|
function resolveWorkerSpawn() {
|
|
27
43
|
const jsCandidates = [
|
|
28
44
|
// Sibling — when import.meta.url is already .../harness/check/runtime-render/.
|
|
@@ -71,12 +87,12 @@ function unverified(reason, t0) {
|
|
|
71
87
|
stats: { actionsChecked: 0, streamsChecked: 0, renderMs: Date.now() - t0 }
|
|
72
88
|
};
|
|
73
89
|
}
|
|
74
|
-
function mapSandboxResultToCheckResult(result, t0) {
|
|
90
|
+
function mapSandboxResultToCheckResult(result, t0, boundMs = DEFAULT_RENDER_CHECK_HOST_BOUNDS.timeoutMs) {
|
|
75
91
|
if (result.outcome === "timeout") {
|
|
76
92
|
return {
|
|
77
93
|
ok: false,
|
|
78
94
|
issues: [],
|
|
79
|
-
incomplete: { kind: "timeout", elapsedMs: result.durationMs, boundMs
|
|
95
|
+
incomplete: { kind: "timeout", elapsedMs: result.durationMs, boundMs },
|
|
80
96
|
stats: { actionsChecked: 0, streamsChecked: 0, renderMs: Date.now() - t0 }
|
|
81
97
|
};
|
|
82
98
|
}
|
|
@@ -121,8 +137,9 @@ function mapSandboxResultToCheckResult(result, t0) {
|
|
|
121
137
|
);
|
|
122
138
|
}
|
|
123
139
|
}
|
|
124
|
-
async function runRenderCheckViaWorker(input) {
|
|
140
|
+
async function runRenderCheckViaWorker(input, options = {}) {
|
|
125
141
|
const t0 = Date.now();
|
|
142
|
+
const bounds = resolveRenderCheckHostBounds(options.bounds);
|
|
126
143
|
let spawn;
|
|
127
144
|
try {
|
|
128
145
|
spawn = resolveWorkerSpawn();
|
|
@@ -133,9 +150,10 @@ async function runRenderCheckViaWorker(input) {
|
|
|
133
150
|
const result = await runSandboxed({
|
|
134
151
|
command: spawn.command,
|
|
135
152
|
args: spawn.args,
|
|
136
|
-
timeoutMs:
|
|
153
|
+
timeoutMs: bounds.timeoutMs,
|
|
154
|
+
gracePeriodMs: bounds.gracePeriodMs,
|
|
137
155
|
maxStdoutBytes: CHECK_STDOUT_CAP,
|
|
138
|
-
nodeHeapMb:
|
|
156
|
+
nodeHeapMb: bounds.heapMb,
|
|
139
157
|
stdin: JSON.stringify(input),
|
|
140
158
|
// NODE_ENV steers React's production vs development build — keep
|
|
141
159
|
// parity with the caller; everything else stays on the sandbox's
|
|
@@ -147,15 +165,18 @@ async function runRenderCheckViaWorker(input) {
|
|
|
147
165
|
end: loadavg()[0] ?? 0,
|
|
148
166
|
cores: availableParallelism()
|
|
149
167
|
};
|
|
150
|
-
const mapped = mapSandboxResultToCheckResult(result, t0);
|
|
168
|
+
const mapped = mapSandboxResultToCheckResult(result, t0, bounds.timeoutMs);
|
|
151
169
|
return { ...mapped, stats: { ...mapped.stats, hostLoad } };
|
|
152
170
|
}
|
|
153
|
-
var
|
|
171
|
+
var DEFAULT_RENDER_CHECK_HOST_BOUNDS, CHECK_STDOUT_CAP, WORKER_BASENAME;
|
|
154
172
|
var init_render_check_host = __esm({
|
|
155
173
|
"src/harness/check/runtime-render/render-check-host.ts"() {
|
|
156
|
-
|
|
174
|
+
DEFAULT_RENDER_CHECK_HOST_BOUNDS = {
|
|
175
|
+
timeoutMs: 3e4,
|
|
176
|
+
heapMb: 512,
|
|
177
|
+
gracePeriodMs: 2e3
|
|
178
|
+
};
|
|
157
179
|
CHECK_STDOUT_CAP = 2 * 1024 * 1024;
|
|
158
|
-
CHECK_NODE_HEAP_MB = 512;
|
|
159
180
|
WORKER_BASENAME = "render-check-worker";
|
|
160
181
|
}
|
|
161
182
|
});
|
|
@@ -677,13 +698,13 @@ function editableSurface(el) {
|
|
|
677
698
|
function parentLink(node) {
|
|
678
699
|
return node;
|
|
679
700
|
}
|
|
680
|
-
async function runRenderCheck(input) {
|
|
701
|
+
async function runRenderCheck(input, options = {}) {
|
|
681
702
|
const g = hostGlobals();
|
|
682
703
|
if ("window" in g && "document" in g) {
|
|
683
704
|
return runRenderCheckInProcess(input);
|
|
684
705
|
}
|
|
685
706
|
const { runRenderCheckViaWorker: runRenderCheckViaWorker2 } = await Promise.resolve().then(() => (init_render_check_host(), render_check_host_exports));
|
|
686
|
-
return runRenderCheckViaWorker2(input);
|
|
707
|
+
return runRenderCheckViaWorker2(input, options);
|
|
687
708
|
}
|
|
688
709
|
async function runRenderCheckInProcess(input) {
|
|
689
710
|
const t0 = Date.now();
|
|
@@ -697,7 +718,7 @@ async function runRenderCheckInProcess(input) {
|
|
|
697
718
|
const Wire = await import('@ggui-ai/wire');
|
|
698
719
|
const { GguiWireProvider } = Wire;
|
|
699
720
|
const moduleResolutions = {
|
|
700
|
-
|
|
721
|
+
react: React,
|
|
701
722
|
"react/jsx-runtime": ReactJsxRuntime,
|
|
702
723
|
"@ggui-ai/wire": Wire
|
|
703
724
|
};
|
|
@@ -813,14 +834,23 @@ async function runRenderCheckInProcess(input) {
|
|
|
813
834
|
)
|
|
814
835
|
);
|
|
815
836
|
const timeoutPromise = new Promise((_, reject) => {
|
|
816
|
-
setTimeout(
|
|
837
|
+
setTimeout(
|
|
838
|
+
() => reject(
|
|
839
|
+
new Error(
|
|
840
|
+
`[runtime-render] render exceeded ${RENDER_TIMEOUT_MS}ms \u2014 classified as runtime-hang`
|
|
841
|
+
)
|
|
842
|
+
),
|
|
843
|
+
RENDER_TIMEOUT_MS
|
|
844
|
+
).unref?.();
|
|
817
845
|
});
|
|
818
846
|
renderResult = await Promise.race([renderPromise, timeoutPromise]);
|
|
819
847
|
} catch (e) {
|
|
820
848
|
const msg = e instanceof Error ? e.message : String(e);
|
|
821
849
|
const errStack = e instanceof Error ? e.stack ?? "" : "";
|
|
822
850
|
const baseReason = loopSignature ? `Infinite render loop (${loopSignature}) \u2014 likely setState/dispatch inside useEffect with missing or unstable dependency` : /runtime-hang/.test(msg) ? `Render wall-clock exceeded ${RENDER_TIMEOUT_MS}ms \u2014 likely async effect loop or unresolved promise` : `Render threw: ${msg}`;
|
|
823
|
-
const userFrames = errStack.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("at ")).filter(
|
|
851
|
+
const userFrames = errStack.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("at ")).filter(
|
|
852
|
+
(l) => !/(node_modules|happy-dom|@testing-library|react-dom|node:internal|node:async)/.test(l)
|
|
853
|
+
).slice(0, 5);
|
|
824
854
|
const stackSource = boundaryRef.stack ?? capturedComponentStack ?? "";
|
|
825
855
|
const componentFrames = stackSource.split("\n").map((l) => l.trim()).filter((l) => l.startsWith("at ")).slice(0, 4);
|
|
826
856
|
const stackBlock = userFrames.length ? `
|
|
@@ -1285,9 +1315,7 @@ function idLikeRequiredStringField(schema) {
|
|
|
1285
1315
|
const required = schema["required"];
|
|
1286
1316
|
if (properties === null || typeof properties !== "object") return null;
|
|
1287
1317
|
if (!Array.isArray(required)) return null;
|
|
1288
|
-
for (const [propName, propSchema] of Object.entries(
|
|
1289
|
-
properties
|
|
1290
|
-
)) {
|
|
1318
|
+
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
1291
1319
|
if (!/id$/i.test(propName)) continue;
|
|
1292
1320
|
if (!required.includes(propName)) continue;
|
|
1293
1321
|
const t = propSchema !== null && typeof propSchema === "object" ? propSchema["type"] : void 0;
|
|
@@ -1318,9 +1346,7 @@ async function checkSelectionIdentity(input) {
|
|
|
1318
1346
|
return void 0;
|
|
1319
1347
|
}
|
|
1320
1348
|
await flushPromises();
|
|
1321
|
-
const events = probe.getFireLog().slice(before).filter(
|
|
1322
|
-
(e) => e.kind === "action.fired" && e.name === actionName
|
|
1323
|
-
);
|
|
1349
|
+
const events = probe.getFireLog().slice(before).filter((e) => e.kind === "action.fired" && e.name === actionName);
|
|
1324
1350
|
return events.length > 0 ? events[events.length - 1].payload : void 0;
|
|
1325
1351
|
};
|
|
1326
1352
|
const first = await payloadFor(group[0]);
|
|
@@ -1381,7 +1407,10 @@ async function dispatchTrigger(el, kind, user) {
|
|
|
1381
1407
|
case "submit": {
|
|
1382
1408
|
const form = closestForm(el);
|
|
1383
1409
|
if (!form) return;
|
|
1384
|
-
const ev = new globalThis.Event("submit", {
|
|
1410
|
+
const ev = new globalThis.Event("submit", {
|
|
1411
|
+
bubbles: true,
|
|
1412
|
+
cancelable: true
|
|
1413
|
+
});
|
|
1385
1414
|
toEventDispatcher(form).dispatchEvent(ev);
|
|
1386
1415
|
return;
|
|
1387
1416
|
}
|
|
@@ -1718,47 +1747,112 @@ function synthesizeFromSchema(schema, hint, warnings, depth, ordinal) {
|
|
|
1718
1747
|
}
|
|
1719
1748
|
|
|
1720
1749
|
// src/harness/check/runtime-render/adapter.ts
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1750
|
+
init_render_check_host();
|
|
1751
|
+
function createSlotLimiter(maxConcurrent) {
|
|
1752
|
+
if (maxConcurrent === void 0) return (task) => task(0);
|
|
1753
|
+
if (!Number.isInteger(maxConcurrent) || maxConcurrent < 1) {
|
|
1754
|
+
throw new RangeError(
|
|
1755
|
+
`createRuntimeRenderCheck: maxConcurrent must be a positive integer, got ${maxConcurrent}`
|
|
1756
|
+
);
|
|
1757
|
+
}
|
|
1758
|
+
let active = 0;
|
|
1759
|
+
const waiting = [];
|
|
1760
|
+
const acquire = () => {
|
|
1761
|
+
if (active < maxConcurrent) {
|
|
1762
|
+
active += 1;
|
|
1763
|
+
return Promise.resolve(0);
|
|
1764
|
+
}
|
|
1765
|
+
const enqueuedAt = Date.now();
|
|
1766
|
+
return new Promise((resolve) => {
|
|
1767
|
+
waiting.push(() => {
|
|
1768
|
+
active += 1;
|
|
1769
|
+
resolve(Date.now() - enqueuedAt);
|
|
1738
1770
|
});
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1771
|
+
});
|
|
1772
|
+
};
|
|
1773
|
+
const release = () => {
|
|
1774
|
+
active -= 1;
|
|
1775
|
+
const next = waiting.shift();
|
|
1776
|
+
if (next !== void 0) next();
|
|
1777
|
+
};
|
|
1778
|
+
return async (task) => {
|
|
1779
|
+
const waitedMs = await acquire();
|
|
1780
|
+
try {
|
|
1781
|
+
return await task(waitedMs);
|
|
1782
|
+
} finally {
|
|
1783
|
+
release();
|
|
1745
1784
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
function queuedField(queuedMs) {
|
|
1788
|
+
return queuedMs > 0 ? { queuedMs } : {};
|
|
1789
|
+
}
|
|
1790
|
+
function toRenderCheckOptions(config) {
|
|
1791
|
+
if (config.timeoutMs === void 0 && config.heapMb === void 0) return void 0;
|
|
1792
|
+
return {
|
|
1793
|
+
bounds: {
|
|
1794
|
+
...config.timeoutMs !== void 0 ? { timeoutMs: config.timeoutMs } : {},
|
|
1795
|
+
...config.heapMb !== void 0 ? { heapMb: config.heapMb } : {}
|
|
1754
1796
|
}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1797
|
+
};
|
|
1798
|
+
}
|
|
1799
|
+
function createRuntimeRenderCheck(config = {}) {
|
|
1800
|
+
const limit = createSlotLimiter(config.maxConcurrent);
|
|
1801
|
+
const options = toRenderCheckOptions(config);
|
|
1802
|
+
if (options !== void 0) resolveRenderCheckHostBounds(options.bounds);
|
|
1803
|
+
return {
|
|
1804
|
+
id: "runtime-render",
|
|
1805
|
+
run: async (input) => {
|
|
1806
|
+
const { sourceCode, compiledCode, contract, fixtureProps } = input;
|
|
1807
|
+
if (compiledCode === null) {
|
|
1808
|
+
return { status: "not-applicable", issues: [], reason: "no compiled code" };
|
|
1809
|
+
}
|
|
1810
|
+
if (!contract) {
|
|
1811
|
+
return { status: "not-applicable", issues: [], reason: "no contract surface" };
|
|
1812
|
+
}
|
|
1813
|
+
const mockup = prepareMockupProps({ contract, fixtureProps });
|
|
1814
|
+
let queuedMs = 0;
|
|
1815
|
+
let t0 = Date.now();
|
|
1816
|
+
let result;
|
|
1817
|
+
try {
|
|
1818
|
+
result = await limit((waitedMs) => {
|
|
1819
|
+
queuedMs = waitedMs;
|
|
1820
|
+
t0 = Date.now();
|
|
1821
|
+
return runRenderCheck(
|
|
1822
|
+
{
|
|
1823
|
+
sourceCode,
|
|
1824
|
+
mockupProps: mockup.props,
|
|
1825
|
+
contract
|
|
1826
|
+
},
|
|
1827
|
+
options
|
|
1828
|
+
);
|
|
1829
|
+
});
|
|
1830
|
+
} catch (e) {
|
|
1831
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
1832
|
+
console.warn(`[runtime-render] probe skipped \u2014 infra failure: ${message}`);
|
|
1833
|
+
return { status: "infra-skipped", issues: [], reason: message, elapsedMs: Date.now() - t0, ...queuedField(queuedMs) };
|
|
1834
|
+
}
|
|
1835
|
+
const hostLoad = result.stats.hostLoad;
|
|
1836
|
+
const load = hostLoad !== void 0 ? { hostLoad } : {};
|
|
1837
|
+
if (result.incomplete !== void 0) {
|
|
1838
|
+
const { elapsedMs, boundMs } = result.incomplete;
|
|
1839
|
+
const loadNote = hostLoad !== void 0 ? `; host load ${hostLoad.start.toFixed(1)} \u2192 ${hostLoad.end.toFixed(1)} on ${hostLoad.cores} CPUs` : "";
|
|
1840
|
+
const reason = `render check did not finish within ${boundMs} ms (stopped at ${elapsedMs} ms)${loadNote}`;
|
|
1841
|
+
console.warn(`[runtime-render] probe timed out \u2014 ${reason}`);
|
|
1842
|
+
return { status: "timed-out", issues: [], reason, elapsedMs: Date.now() - t0, ...queuedField(queuedMs), ...load };
|
|
1843
|
+
}
|
|
1844
|
+
return {
|
|
1845
|
+
status: "ran",
|
|
1846
|
+
issues: result.issues.map(toEvalIssue).filter((x) => x !== null),
|
|
1847
|
+
elapsedMs: Date.now() - t0,
|
|
1848
|
+
...queuedField(queuedMs),
|
|
1849
|
+
renderMs: result.stats.renderMs,
|
|
1850
|
+
...load
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
var DEFAULT_RUNTIME_RENDER_CHECK = createRuntimeRenderCheck();
|
|
1762
1856
|
function classifyRenderCrashFix(reason) {
|
|
1763
1857
|
const r = reason.toLowerCase();
|
|
1764
1858
|
if (r.includes("too many re-renders") || r.includes("maximum update depth") || r.includes("infinite render loop")) {
|