@ggui-ai/ui-gen 0.17.0 → 0.19.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/adapters/generation-dispatch.d.ts +1 -1
- package/dist/adapters/generation-dispatch.js +449 -194
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.js +4 -6
- package/dist/adapters/index.js.map +1 -1
- package/dist/advanced/index.d.ts +2 -2
- package/dist/advanced/index.js +391 -134
- package/dist/advanced/index.js.map +1 -1
- package/dist/boilerplate.js +29 -5
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +1 -1
- package/dist/check/index.js +70 -0
- package/dist/check/index.js.map +1 -1
- package/dist/{create-ui-generator-C8Ki9Wz1.d.ts → create-ui-generator-CxPvudbs.d.ts} +1 -1
- package/dist/{dispatch-D2htzi9h.d.ts → dispatch-N8wdNOX-.d.ts} +4 -2
- package/dist/evaluation/axis-checks/index.d.ts +3 -3
- package/dist/evaluation/axis-checks/index.js +147 -3
- package/dist/evaluation/axis-checks/index.js.map +1 -1
- package/dist/evaluation/axis-checks/registry.d.ts +1 -1
- package/dist/evaluation/axis-checks/registry.js +142 -1
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.d.ts +3 -3
- package/dist/evaluation/index.js +217 -84
- package/dist/evaluation/index.js.map +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +1 -1
- package/dist/harness/index.d.ts +1 -1
- package/dist/harness/index.js +91 -64
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/prompts.js +4 -0
- package/dist/harness/prompts.js.map +1 -1
- package/dist/harness/result-types.d.ts +1 -1
- package/dist/harness/runtime.d.ts +1 -1
- package/dist/harness/runtime.js +31 -7
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +8 -1
- package/dist/harness/types-public.js +91 -64
- package/dist/harness/types-public.js.map +1 -1
- package/dist/harness/validator-trace-sink.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +391 -134
- package/dist/index.js.map +1 -1
- package/dist/patch.d.ts +1 -1
- package/dist/{types-public-DVSssdc-.d.ts → types-public-DKR_h70H.d.ts} +9 -0
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/workflows.d.ts +1 -1
- package/package.json +12 -12
- package/src/adapters/google/sdk.ts +11 -7
- package/src/boilerplate/free-design-prompt.ts +2 -0
- package/src/boilerplate/generate.ts +8 -1
- package/src/boilerplate/hard-sections.ts +32 -3
- package/src/boilerplate/system-prompt.ts +3 -1
- package/src/boilerplate/templates/layouts/fullscreen-desktop.tsx.tmpl +5 -3
- package/src/boilerplate/templates/layouts/fullscreen-mobile.tsx.tmpl +3 -3
- package/src/boilerplate/templates/layouts/fullscreen-universal.tsx.tmpl +5 -3
- package/src/check/run-tier0.ts +152 -0
- package/src/coding-agent/tools.ts +58 -6
- package/src/contract-context.ts +13 -0
- package/src/create-harness.ts +1 -0
- package/src/evaluation/axis-checks/checks/universal.ts +179 -1
- package/src/evaluation/axis-checks/dispatch.ts +8 -1
- package/src/evaluation/types-public.ts +9 -0
- package/src/harness/coding/generate-task-runner.ts +1 -0
- package/src/harness/coding/run-coding-turn.ts +14 -0
- package/src/harness/types-public.ts +7 -0
- package/src/run-check.ts +2 -0
- package/src/tools/get-wire.ts +1 -1
- package/src/validation/primitives.ts +1 -1
|
@@ -4,7 +4,7 @@ import { GadgetCatalogAdapter } from '@ggui-ai/gadgets';
|
|
|
4
4
|
import { GeneratorTier, UiGenerator } from '@ggui-ai/mcp-server-core';
|
|
5
5
|
import { GenerationResult } from './harness/result-types.js';
|
|
6
6
|
import { D as DesignMode } from './design-mode-DLufhrNp.js';
|
|
7
|
-
import { Q as QualityConfig } from './types-public-
|
|
7
|
+
import { Q as QualityConfig } from './types-public-DKR_h70H.js';
|
|
8
8
|
import { EvaluationConfig } from './evaluation/types.js';
|
|
9
9
|
import { A as AgentConfig } from './llm-router-D7fjBhtr.js';
|
|
10
10
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DataContract } from '@ggui-ai/protocol';
|
|
2
2
|
import { C as Classification } from './axes-CzLEMDeB.js';
|
|
3
|
-
import { E as EvalIssue } from './types-public-
|
|
4
|
-
import { D as DesignMode } from './design-mode-DLufhrNp.js';
|
|
3
|
+
import { E as EvalIssue } from './types-public-DKR_h70H.js';
|
|
4
|
+
import { D as DesignMode, C as CanvasClass } from './design-mode-DLufhrNp.js';
|
|
5
5
|
|
|
6
6
|
interface RunAxisChecksInput {
|
|
7
7
|
sourceCode: string;
|
|
@@ -10,6 +10,8 @@ interface RunAxisChecksInput {
|
|
|
10
10
|
originalPrompt: string;
|
|
11
11
|
/** Which triad produced the source — see `AxisCheckInput.designMode`. */
|
|
12
12
|
designMode?: DesignMode;
|
|
13
|
+
/** The canvas the source is judged for — see `AxisCheckInput.canvas` (ggui#1117); absent = no rendering context. */
|
|
14
|
+
canvas?: CanvasClass;
|
|
13
15
|
}
|
|
14
16
|
declare function runAxisChecks(classification: Classification, input: RunAxisChecksInput): EvalIssue[];
|
|
15
17
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { R as RunAxisChecksInput, r as runAxisChecks } from '../../dispatch-
|
|
1
|
+
export { R as RunAxisChecksInput, r as runAxisChecks } from '../../dispatch-N8wdNOX-.js';
|
|
2
2
|
export { REGISTRY } from './registry.js';
|
|
3
|
-
import { A as AxisCheck } from '../../types-public-
|
|
4
|
-
export { a as AxisCheckInput, m as matches } from '../../types-public-
|
|
3
|
+
import { A as AxisCheck } from '../../types-public-DKR_h70H.js';
|
|
4
|
+
export { a as AxisCheckInput, m as matches } from '../../types-public-DKR_h70H.js';
|
|
5
5
|
import '@ggui-ai/protocol';
|
|
6
6
|
import '../../axes-CzLEMDeB.js';
|
|
7
7
|
import '../../design-mode-DLufhrNp.js';
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import { LUCIDE_ICON_NAMES } from '@ggui-ai/design';
|
|
1
|
+
import { LUCIDE_ICON_NAMES, maxWidth } from '@ggui-ai/design';
|
|
2
2
|
import { listContractGadgets, HOOK_NAME_RE, STDLIB_GADGETS_PACKAGE } from '@ggui-ai/protocol';
|
|
3
3
|
import { createHash } from 'crypto';
|
|
4
4
|
|
|
5
5
|
// src/evaluation/axis-checks/checks/universal.ts
|
|
6
|
+
|
|
7
|
+
// src/design-mode.ts
|
|
8
|
+
var CANVAS_VIEWPORTS = {
|
|
9
|
+
"xs-chat-card": { width: 400, height: 640 },
|
|
10
|
+
"mobile-fullscreen-small": { width: 390, height: 844 },
|
|
11
|
+
md: { width: 768, height: 1024 },
|
|
12
|
+
lg: { width: 1024, height: 768 },
|
|
13
|
+
xl: { width: 1440, height: 900 }
|
|
14
|
+
};
|
|
6
15
|
var ID_FIELD_CANDIDATES = ["id", "uuid", "symbol", "key", "slug", "code"];
|
|
7
16
|
function getItemsProperties(p) {
|
|
8
17
|
return p.items?.properties ?? p.schema?.items?.properties;
|
|
@@ -400,6 +409,126 @@ function runViewportSized(input) {
|
|
|
400
409
|
)
|
|
401
410
|
];
|
|
402
411
|
}
|
|
412
|
+
var TERMINAL_WORDS = /* @__PURE__ */ new Set([
|
|
413
|
+
"submit",
|
|
414
|
+
"confirm",
|
|
415
|
+
"approve",
|
|
416
|
+
"schedule",
|
|
417
|
+
"reserve",
|
|
418
|
+
"book",
|
|
419
|
+
"pay",
|
|
420
|
+
"checkout",
|
|
421
|
+
"purchase",
|
|
422
|
+
"order"
|
|
423
|
+
]);
|
|
424
|
+
var TERMINAL_LABEL_RX = /\b(submit|confirm|approve|schedule|reserve|book|pay|checkout|purchase|place\s+order)\b/i;
|
|
425
|
+
var GUARD_RX = /\b(disabled|aria-disabled)\s*=/;
|
|
426
|
+
function nameWords(name) {
|
|
427
|
+
return name.split(/(?=[A-Z])|[_\-\s]+/).map((w) => w.toLowerCase()).filter((w) => w.length > 0);
|
|
428
|
+
}
|
|
429
|
+
function findUnguardedTerminalControls(sourceCode) {
|
|
430
|
+
if (GUARD_RX.test(sourceCode)) return [];
|
|
431
|
+
const names = /* @__PURE__ */ new Set();
|
|
432
|
+
for (const m of sourceCode.matchAll(/useAction(?:<[^>]*>)?\(\s*['"`]([^'"`]+)['"`]/g)) {
|
|
433
|
+
const name = m[1] ?? "";
|
|
434
|
+
if (nameWords(name).some((w) => TERMINAL_WORDS.has(w))) names.add(name);
|
|
435
|
+
}
|
|
436
|
+
for (const m of sourceCode.matchAll(/>([^<>{}]{1,60})<\/Button>/g)) {
|
|
437
|
+
const label = (m[1] ?? "").replace(/\s+/g, " ").trim();
|
|
438
|
+
if (label.length > 0 && TERMINAL_LABEL_RX.test(label)) names.add(label.slice(0, 40));
|
|
439
|
+
}
|
|
440
|
+
return [...names];
|
|
441
|
+
}
|
|
442
|
+
function runTerminalActionUnguarded(input) {
|
|
443
|
+
if (input.compiledCode === null) return [];
|
|
444
|
+
const found = findUnguardedTerminalControls(input.sourceCode);
|
|
445
|
+
if (found.length === 0) return [];
|
|
446
|
+
const list = found.map((t) => `"${t}"`).join(", ");
|
|
447
|
+
return [
|
|
448
|
+
mkIssue(
|
|
449
|
+
"universal.terminal_action_unguarded",
|
|
450
|
+
`${list} reads as an action the user means once, and nothing in this component disables the control after it fires \u2014 a double-click sends it twice.`,
|
|
451
|
+
'Hold the fired state (`const [submitted, setSubmitted] = useState(false)`), set it in the handler, and pass `disabled={submitted}` to that control with a word that says so ("Submitted"). If the action IS meant to repeat \u2014 sending a message, adding an item \u2014 leave it armed and ignore this.',
|
|
452
|
+
"warn"
|
|
453
|
+
)
|
|
454
|
+
];
|
|
455
|
+
}
|
|
456
|
+
function rootOpeningTag(sourceCode) {
|
|
457
|
+
const start = sourceCode.indexOf("export default function");
|
|
458
|
+
const body = start >= 0 ? sourceCode.slice(start) : sourceCode;
|
|
459
|
+
const ret = /\breturn\s*\(?\s*</.exec(body);
|
|
460
|
+
if (ret === null) return null;
|
|
461
|
+
const at = ret.index + ret[0].length - 1;
|
|
462
|
+
const nameMatch = /^<([A-Za-z][\w.]*)/.exec(body.slice(at));
|
|
463
|
+
if (nameMatch === null) return null;
|
|
464
|
+
let j = at + nameMatch[0].length;
|
|
465
|
+
let depth = 0;
|
|
466
|
+
let quote = null;
|
|
467
|
+
for (; j < body.length; j++) {
|
|
468
|
+
const ch = body[j];
|
|
469
|
+
if (quote !== null) {
|
|
470
|
+
if (ch === quote) quote = null;
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
if (ch === '"' || ch === "'" || ch === "`") quote = ch;
|
|
474
|
+
else if (ch === "{") depth++;
|
|
475
|
+
else if (ch === "}") depth--;
|
|
476
|
+
else if (ch === ">" && depth === 0) break;
|
|
477
|
+
}
|
|
478
|
+
return { name: nameMatch[1], attrs: body.slice(at + nameMatch[0].length, j) };
|
|
479
|
+
}
|
|
480
|
+
var CONTAINER_PRESETS = maxWidth;
|
|
481
|
+
var NOT_A_CAP = /* @__PURE__ */ new Set(["full", "none", "100%", "unset", "initial", "inherit"]);
|
|
482
|
+
function capPx(value) {
|
|
483
|
+
const v = value.trim();
|
|
484
|
+
if (NOT_A_CAP.has(v)) return void 0;
|
|
485
|
+
const resolved = CONTAINER_PRESETS[v] ?? v;
|
|
486
|
+
if (NOT_A_CAP.has(resolved)) return void 0;
|
|
487
|
+
const px = /^(\d+(?:\.\d+)?)px$/.exec(resolved);
|
|
488
|
+
return px === null ? null : Number(px[1]);
|
|
489
|
+
}
|
|
490
|
+
function findRootWidthCap(sourceCode) {
|
|
491
|
+
const root = rootOpeningTag(sourceCode);
|
|
492
|
+
if (root === null) return null;
|
|
493
|
+
const { name, attrs } = root;
|
|
494
|
+
const prop = /\bmaxWidth\s*=\s*(?:"([^"]*)"|'([^']*)'|\{\s*(?:"([^"]*)"|'([^']*)'|(\d+(?:\.\d+)?))\s*\})/.exec(attrs);
|
|
495
|
+
if (prop !== null) {
|
|
496
|
+
const raw = prop[1] ?? prop[2] ?? prop[3] ?? prop[4] ?? `${prop[5]}px`;
|
|
497
|
+
const px = capPx(raw);
|
|
498
|
+
return px === void 0 ? null : { element: name, cap: `maxWidth="${raw}"`, px };
|
|
499
|
+
}
|
|
500
|
+
const style = /\bmaxWidth\s*:\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|(\d+(?:\.\d+)?))/.exec(attrs);
|
|
501
|
+
if (style !== null) {
|
|
502
|
+
const raw = style[1] ?? style[2] ?? style[3] ?? `${style[4]}px`;
|
|
503
|
+
const px = capPx(raw);
|
|
504
|
+
return px === void 0 ? null : { element: name, cap: `maxWidth: '${raw}'`, px };
|
|
505
|
+
}
|
|
506
|
+
const cls = /(?<![\w-])max-w-([\w[\]%.-]+)/.exec(attrs);
|
|
507
|
+
if (cls !== null) {
|
|
508
|
+
if (cls[1] === "full" || cls[1] === "none") return null;
|
|
509
|
+
return { element: name, cap: `max-w-${cls[1]}`, px: null };
|
|
510
|
+
}
|
|
511
|
+
if (name === "Container") return { element: name, cap: "lg (Container default)", px: capPx("lg") ?? null };
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
var WIDE_CANVASES = /* @__PURE__ */ new Set(["md", "lg", "xl"]);
|
|
515
|
+
function runRootWidthCap(input) {
|
|
516
|
+
if (input.compiledCode === null) return [];
|
|
517
|
+
if (input.canvas === void 0 || !WIDE_CANVASES.has(input.canvas)) return [];
|
|
518
|
+
const cap2 = findRootWidthCap(input.sourceCode);
|
|
519
|
+
if (cap2 === null) return [];
|
|
520
|
+
const width = CANVAS_VIEWPORTS[input.canvas].width;
|
|
521
|
+
if (cap2.px !== null && cap2.px >= width) return [];
|
|
522
|
+
const sized = cap2.px !== null ? `${cap2.px}px on a ${width}px canvas` : `on a ${width}px canvas`;
|
|
523
|
+
return [
|
|
524
|
+
mkIssue(
|
|
525
|
+
"universal.root_width_cap",
|
|
526
|
+
`The outermost element <${cap2.element}> carries a width cap (${cap2.cap}, ${sized}): on this canvas the card becomes a narrow strip with the frame's ground on either side. The frame owns the width; a cap belongs INSIDE the root, on the column that holds text.`,
|
|
527
|
+
'Let the root fill the frame \u2014 drop the cap on the element you return at the top (or `maxWidth="full"`) \u2014 and put the reading measure on an inner column: `<Box padding="lg"><Container maxWidth="sm">\u2026</Container></Box>`.',
|
|
528
|
+
"warn"
|
|
529
|
+
)
|
|
530
|
+
];
|
|
531
|
+
}
|
|
403
532
|
var UNIVERSAL_CHECKS = [
|
|
404
533
|
{
|
|
405
534
|
id: "universal.icon_name_known",
|
|
@@ -419,6 +548,18 @@ var UNIVERSAL_CHECKS = [
|
|
|
419
548
|
values: ALL_RENDER_VALUES,
|
|
420
549
|
run: runViewportSized
|
|
421
550
|
},
|
|
551
|
+
{
|
|
552
|
+
id: "universal.root_width_cap",
|
|
553
|
+
axis: "render",
|
|
554
|
+
values: ALL_RENDER_VALUES,
|
|
555
|
+
run: runRootWidthCap
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
id: "universal.terminal_action_unguarded",
|
|
559
|
+
axis: "render",
|
|
560
|
+
values: ALL_RENDER_VALUES,
|
|
561
|
+
run: runTerminalActionUnguarded
|
|
562
|
+
},
|
|
422
563
|
{
|
|
423
564
|
id: "universal.accent_text_ink",
|
|
424
565
|
axis: "render",
|
|
@@ -1473,7 +1614,8 @@ function runAxisChecks(classification, input) {
|
|
|
1473
1614
|
...input.contract !== void 0 ? { contract: input.contract } : {},
|
|
1474
1615
|
originalPrompt: input.originalPrompt,
|
|
1475
1616
|
classification,
|
|
1476
|
-
...input.designMode !== void 0 ? { designMode: input.designMode } : {}
|
|
1617
|
+
...input.designMode !== void 0 ? { designMode: input.designMode } : {},
|
|
1618
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
1477
1619
|
};
|
|
1478
1620
|
if (input.compiledCode === null) {
|
|
1479
1621
|
traceAxisChecksSkipped(facts, "compiledCode null \u2014 no check ran");
|
|
@@ -1518,7 +1660,9 @@ function traceFacts(input) {
|
|
|
1518
1660
|
designMode: input.designMode ?? "constrained",
|
|
1519
1661
|
classification: input.classification.vector,
|
|
1520
1662
|
propsSpecKeys: Object.keys(propsSpec ?? {}),
|
|
1521
|
-
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {})
|
|
1663
|
+
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {}),
|
|
1664
|
+
// No default here, unlike designMode: an absent canvas is a fact about the caller, not a guess to paper over.
|
|
1665
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
1522
1666
|
};
|
|
1523
1667
|
}
|
|
1524
1668
|
|