@ggui-ai/ui-gen 0.18.0 → 0.20.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 +248 -88
- package/dist/adapters/generation-dispatch.js.map +1 -1
- package/dist/adapters/index.js +39 -16
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/types.d.ts +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/advanced/index.d.ts +2 -2
- package/dist/advanced/index.js +217 -34
- package/dist/advanced/index.js.map +1 -1
- package/dist/blueprint-validator.js +5 -2
- package/dist/blueprint-validator.js.map +1 -1
- package/dist/boilerplate.js +2 -2
- package/dist/boilerplate.js.map +1 -1
- package/dist/check/index.d.ts +1 -1
- 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 +143 -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 +138 -1
- package/dist/evaluation/axis-checks/registry.js.map +1 -1
- package/dist/evaluation/index.d.ts +3 -3
- package/dist/evaluation/index.js +213 -84
- package/dist/evaluation/index.js.map +1 -1
- package/dist/harness/check/runtime-render/index.d.ts +1 -1
- package/dist/harness/check/runtime-render/index.js +5 -2
- package/dist/harness/check/runtime-render/index.js.map +1 -1
- package/dist/harness/check/runtime-render/render-check-worker.js +5 -2
- package/dist/harness/check/runtime-render/render-check-worker.js.map +1 -1
- package/dist/harness/index.d.ts +1 -1
- package/dist/harness/index.js +64 -61
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/prompts.js +1 -1
- 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 +4 -4
- package/dist/harness/runtime.js.map +1 -1
- package/dist/harness/types-public.d.ts +8 -1
- package/dist/harness/types-public.js +64 -61
- 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 +217 -34
- 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/adapters/openai/raw.ts +11 -5
- package/src/adapters/openai/sdk.ts +8 -5
- package/src/adapters/openai/tokens.ts +49 -0
- package/src/adapters/types.ts +1 -1
- package/src/boilerplate/hard-sections.ts +1 -1
- package/src/boilerplate/system-prompt.ts +1 -1
- package/src/coding-agent/tools.ts +58 -6
- package/src/contract-context.ts +1 -1
- package/src/create-harness.ts +1 -0
- package/src/evaluation/axis-checks/checks/universal.ts +207 -1
- package/src/evaluation/axis-checks/dispatch.ts +8 -1
- package/src/evaluation/types-public.ts +9 -0
- package/src/harness/check/runtime-render/render-check.ts +15 -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
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { C as CanvasJudgeRecord, E as EvalIssue, V as VisualEvalSummary } from '../types-public-
|
|
2
|
-
export { A as AxisCheck, a as AxisCheckInput, d as CRITERIA, e as CanvasVisualSummary, f as CriterionCoverage, g as CriterionRunStatus, D as DEFAULT_QUALITY_CONFIG, h as EvalCategory, i as EvalCriterion, j as EvalOutcome, b as EvalResult, c as EvalTier, L as LLM_EVAL_STATIC_CRITERIA, P as Priority, Q as QualityConfig, k as QualityMode, l as buildCodingCriteriaSummary, n as criteriaFor, o as getActionableIssues, p as getCriteriaByPriority, q as getCriterionById, r as getLLMCriteria, s as isBlocked, m as matches, t as notApplicableCoverage, u as priorityForIssue } from '../types-public-
|
|
1
|
+
import { C as CanvasJudgeRecord, E as EvalIssue, V as VisualEvalSummary } from '../types-public-DKR_h70H.js';
|
|
2
|
+
export { A as AxisCheck, a as AxisCheckInput, d as CRITERIA, e as CanvasVisualSummary, f as CriterionCoverage, g as CriterionRunStatus, D as DEFAULT_QUALITY_CONFIG, h as EvalCategory, i as EvalCriterion, j as EvalOutcome, b as EvalResult, c as EvalTier, L as LLM_EVAL_STATIC_CRITERIA, P as Priority, Q as QualityConfig, k as QualityMode, l as buildCodingCriteriaSummary, n as criteriaFor, o as getActionableIssues, p as getCriteriaByPriority, q as getCriterionById, r as getLLMCriteria, s as isBlocked, m as matches, t as notApplicableCoverage, u as priorityForIssue } from '../types-public-DKR_h70H.js';
|
|
3
3
|
import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
|
|
4
4
|
import { McpServerConfig } from '@anthropic-ai/claude-agent-sdk';
|
|
5
5
|
import { EvaluationContext, EvaluationConfig, QualityMetadata, EvaluationResult, EvaluationIssue } from './types.js';
|
|
6
6
|
export { DEFAULT_EVAL_MAX_ROUNDS, DimensionScores, MAX_EVAL_ROUNDS_HARD_LIMIT } from './types.js';
|
|
7
|
-
export { R as RunAxisChecksInput, r as runAxisChecks } from '../dispatch-
|
|
7
|
+
export { R as RunAxisChecksInput, r as runAxisChecks } from '../dispatch-N8wdNOX-.js';
|
|
8
8
|
import { A as AgentConfig, L as LLMResponse } from '../llm-router-D7fjBhtr.js';
|
|
9
9
|
import { G as GenerationProfileInput } from '../styling-profile-CxfvV48g.js';
|
|
10
10
|
import { LaunchOptions } from 'puppeteer-core';
|
package/dist/evaluation/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'url';
|
|
|
9
9
|
import { query, createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
|
|
10
10
|
import Anthropic from '@anthropic-ai/sdk';
|
|
11
11
|
import { z } from 'zod';
|
|
12
|
-
import { LUCIDE_ICON_NAMES } from '@ggui-ai/design';
|
|
12
|
+
import { LUCIDE_ICON_NAMES, maxWidth } from '@ggui-ai/design';
|
|
13
13
|
import { listContractGadgets, HOOK_NAME_RE, STDLIB_GADGETS_PACKAGE, APP_GENERATION_PROFILE_BOUNDS } from '@ggui-ai/protocol';
|
|
14
14
|
import { createHash } from 'crypto';
|
|
15
15
|
import { build } from 'esbuild';
|
|
@@ -5402,6 +5402,85 @@ function createEvaluationToolsServer(passThreshold = 70) {
|
|
|
5402
5402
|
]
|
|
5403
5403
|
});
|
|
5404
5404
|
}
|
|
5405
|
+
|
|
5406
|
+
// src/design-mode.ts
|
|
5407
|
+
var CANVAS_CLASSES = [
|
|
5408
|
+
"xs-chat-card",
|
|
5409
|
+
"mobile-fullscreen-small",
|
|
5410
|
+
"md",
|
|
5411
|
+
"lg",
|
|
5412
|
+
"xl"
|
|
5413
|
+
];
|
|
5414
|
+
var CANVAS_VIEWPORTS = {
|
|
5415
|
+
"xs-chat-card": { width: 400, height: 640 },
|
|
5416
|
+
"mobile-fullscreen-small": { width: 390, height: 844 },
|
|
5417
|
+
md: { width: 768, height: 1024 },
|
|
5418
|
+
lg: { width: 1024, height: 768 },
|
|
5419
|
+
xl: { width: 1440, height: 900 }
|
|
5420
|
+
};
|
|
5421
|
+
function displayModeForCanvas(canvas) {
|
|
5422
|
+
return canvas === "xs-chat-card" ? "inline" : "fullscreen";
|
|
5423
|
+
}
|
|
5424
|
+
function canvasDisplayModeForShell(shell) {
|
|
5425
|
+
return shell === "chat" || shell === "inline" ? "inline" : "fullscreen";
|
|
5426
|
+
}
|
|
5427
|
+
var CANVAS_BREAKPOINTS = { md: 600, lg: 1024, xl: 1440 };
|
|
5428
|
+
function canvasForViewportWidth(mode, width) {
|
|
5429
|
+
if (mode === "inline") return "xs-chat-card";
|
|
5430
|
+
if (width < CANVAS_BREAKPOINTS.md) return "mobile-fullscreen-small";
|
|
5431
|
+
if (width < CANVAS_BREAKPOINTS.lg) return "md";
|
|
5432
|
+
if (width < CANVAS_BREAKPOINTS.xl) return "lg";
|
|
5433
|
+
return "xl";
|
|
5434
|
+
}
|
|
5435
|
+
function canvasForRendering(shellType, screen) {
|
|
5436
|
+
const shell = shellType ?? "fullscreen";
|
|
5437
|
+
if (canvasDisplayModeForShell(shell) === "inline") return "xs-chat-card";
|
|
5438
|
+
if (shell === "spatial") return "md";
|
|
5439
|
+
switch (screen ?? "universal") {
|
|
5440
|
+
case "mobile":
|
|
5441
|
+
return "mobile-fullscreen-small";
|
|
5442
|
+
case "tablet":
|
|
5443
|
+
return "md";
|
|
5444
|
+
default:
|
|
5445
|
+
return "lg";
|
|
5446
|
+
}
|
|
5447
|
+
}
|
|
5448
|
+
var CANVAS_DESCRIPTORS = {
|
|
5449
|
+
"xs-chat-card": {
|
|
5450
|
+
label: "extra-small chat card",
|
|
5451
|
+
minWidthPx: 320,
|
|
5452
|
+
maxWidthPx: 480,
|
|
5453
|
+
host: "an inline card inside a chat message bubble \u2014 the host draws the card border, shadow and rounded corners; the component fills the bubble width and takes its natural height"
|
|
5454
|
+
},
|
|
5455
|
+
"mobile-fullscreen-small": {
|
|
5456
|
+
label: "small mobile fullscreen",
|
|
5457
|
+
minWidthPx: 320,
|
|
5458
|
+
maxWidthPx: 599,
|
|
5459
|
+
host: "a phone-sized viewport the component owns edge to edge \u2014 single column, touch targets at least 44px, the component manages its own scroll"
|
|
5460
|
+
},
|
|
5461
|
+
md: {
|
|
5462
|
+
label: "medium panel",
|
|
5463
|
+
minWidthPx: 600,
|
|
5464
|
+
maxWidthPx: 1023,
|
|
5465
|
+
host: "a tablet viewport or a floating panel (spatial / picture-in-picture) \u2014 one or two columns, medium density"
|
|
5466
|
+
},
|
|
5467
|
+
lg: {
|
|
5468
|
+
label: "large fullscreen",
|
|
5469
|
+
minWidthPx: 1024,
|
|
5470
|
+
maxWidthPx: 1439,
|
|
5471
|
+
host: "a desktop viewport the component owns edge to edge \u2014 multi-column layouts, hover states and pointer interactions are available"
|
|
5472
|
+
},
|
|
5473
|
+
xl: {
|
|
5474
|
+
label: "extra-large fullscreen",
|
|
5475
|
+
minWidthPx: 1440,
|
|
5476
|
+
maxWidthPx: 1920,
|
|
5477
|
+
host: "a wide desktop viewport the component owns edge to edge \u2014 cap content width or use the extra room deliberately; never stretch a single column across the whole width"
|
|
5478
|
+
}
|
|
5479
|
+
};
|
|
5480
|
+
function describeCanvas(canvas) {
|
|
5481
|
+
const d = CANVAS_DESCRIPTORS[canvas];
|
|
5482
|
+
return `This component renders on the \`${canvas}\` canvas (${d.label}): ${d.minWidthPx}\u2013${d.maxWidthPx}px wide, ${d.host}. Design for the whole range \u2014 the host may size the iframe anywhere inside it, and the host owns the height: size to your content, never to the viewport.`;
|
|
5483
|
+
}
|
|
5405
5484
|
var ID_FIELD_CANDIDATES = ["id", "uuid", "symbol", "key", "slug", "code"];
|
|
5406
5485
|
function getItemsProperties(p) {
|
|
5407
5486
|
return p.items?.properties ?? p.schema?.items?.properties;
|
|
@@ -5843,6 +5922,122 @@ function runTerminalActionUnguarded(input) {
|
|
|
5843
5922
|
)
|
|
5844
5923
|
];
|
|
5845
5924
|
}
|
|
5925
|
+
function rootOpeningTag(sourceCode) {
|
|
5926
|
+
const start = sourceCode.indexOf("export default function");
|
|
5927
|
+
const body = start >= 0 ? sourceCode.slice(start) : sourceCode;
|
|
5928
|
+
const ret = /\breturn\s*\(?\s*</.exec(body);
|
|
5929
|
+
if (ret === null) return null;
|
|
5930
|
+
const at = ret.index + ret[0].length - 1;
|
|
5931
|
+
const nameMatch = /^<([A-Za-z][\w.]*)/.exec(body.slice(at));
|
|
5932
|
+
if (nameMatch === null) return null;
|
|
5933
|
+
let j = at + nameMatch[0].length;
|
|
5934
|
+
let depth = 0;
|
|
5935
|
+
let quote = null;
|
|
5936
|
+
for (; j < body.length; j++) {
|
|
5937
|
+
const ch = body[j];
|
|
5938
|
+
if (quote !== null) {
|
|
5939
|
+
if (ch === quote) quote = null;
|
|
5940
|
+
continue;
|
|
5941
|
+
}
|
|
5942
|
+
if (ch === '"' || ch === "'" || ch === "`") quote = ch;
|
|
5943
|
+
else if (ch === "{") depth++;
|
|
5944
|
+
else if (ch === "}") depth--;
|
|
5945
|
+
else if (ch === ">" && depth === 0) break;
|
|
5946
|
+
}
|
|
5947
|
+
return { name: nameMatch[1], attrs: body.slice(at + nameMatch[0].length, j) };
|
|
5948
|
+
}
|
|
5949
|
+
var CONTAINER_PRESETS = maxWidth;
|
|
5950
|
+
var NOT_A_CAP = /* @__PURE__ */ new Set(["full", "none", "100%", "unset", "initial", "inherit"]);
|
|
5951
|
+
function capPx(value) {
|
|
5952
|
+
const v = value.trim();
|
|
5953
|
+
if (NOT_A_CAP.has(v)) return void 0;
|
|
5954
|
+
const resolved = CONTAINER_PRESETS[v] ?? v;
|
|
5955
|
+
if (NOT_A_CAP.has(resolved)) return void 0;
|
|
5956
|
+
const px = /^(\d+(?:\.\d+)?)px$/.exec(resolved);
|
|
5957
|
+
return px === null ? null : Number(px[1]);
|
|
5958
|
+
}
|
|
5959
|
+
function findRootWidthCap(sourceCode) {
|
|
5960
|
+
const root = rootOpeningTag(sourceCode);
|
|
5961
|
+
if (root === null) return null;
|
|
5962
|
+
const { name, attrs } = root;
|
|
5963
|
+
const prop = /\bmaxWidth\s*=\s*(?:"([^"]*)"|'([^']*)'|\{\s*(?:"([^"]*)"|'([^']*)'|(\d+(?:\.\d+)?))\s*\})/.exec(attrs);
|
|
5964
|
+
if (prop !== null) {
|
|
5965
|
+
const raw = prop[1] ?? prop[2] ?? prop[3] ?? prop[4] ?? `${prop[5]}px`;
|
|
5966
|
+
const px = capPx(raw);
|
|
5967
|
+
return px === void 0 ? null : { element: name, cap: `maxWidth="${raw}"`, px };
|
|
5968
|
+
}
|
|
5969
|
+
const style = /\bmaxWidth\s*:\s*(?:"([^"]*)"|'([^']*)'|`([^`]*)`|(\d+(?:\.\d+)?))/.exec(attrs);
|
|
5970
|
+
if (style !== null) {
|
|
5971
|
+
const raw = style[1] ?? style[2] ?? style[3] ?? `${style[4]}px`;
|
|
5972
|
+
const px = capPx(raw);
|
|
5973
|
+
return px === void 0 ? null : { element: name, cap: `maxWidth: '${raw}'`, px };
|
|
5974
|
+
}
|
|
5975
|
+
const cls = /(?<![\w-])max-w-([\w[\]%.-]+)/.exec(attrs);
|
|
5976
|
+
if (cls !== null) {
|
|
5977
|
+
if (cls[1] === "full" || cls[1] === "none") return null;
|
|
5978
|
+
return { element: name, cap: `max-w-${cls[1]}`, px: null };
|
|
5979
|
+
}
|
|
5980
|
+
if (name === "Container") return { element: name, cap: "lg (Container default)", px: capPx("lg") ?? null };
|
|
5981
|
+
return null;
|
|
5982
|
+
}
|
|
5983
|
+
var WIDE_CANVASES = /* @__PURE__ */ new Set(["md", "lg", "xl"]);
|
|
5984
|
+
function runRootWidthCap(input) {
|
|
5985
|
+
if (input.compiledCode === null) return [];
|
|
5986
|
+
if (input.canvas === void 0 || !WIDE_CANVASES.has(input.canvas)) return [];
|
|
5987
|
+
const cap2 = findRootWidthCap(input.sourceCode);
|
|
5988
|
+
if (cap2 === null) return [];
|
|
5989
|
+
const width = CANVAS_VIEWPORTS[input.canvas].width;
|
|
5990
|
+
if (cap2.px !== null && cap2.px >= width) return [];
|
|
5991
|
+
const sized = cap2.px !== null ? `${cap2.px}px on a ${width}px canvas` : `on a ${width}px canvas`;
|
|
5992
|
+
return [
|
|
5993
|
+
mkIssue(
|
|
5994
|
+
"universal.root_width_cap",
|
|
5995
|
+
`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.`,
|
|
5996
|
+
'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>`.',
|
|
5997
|
+
"warn"
|
|
5998
|
+
)
|
|
5999
|
+
];
|
|
6000
|
+
}
|
|
6001
|
+
var LABEL_SPECIAL_CHAR = /[^a-z0-9\s]/i;
|
|
6002
|
+
var normText = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
6003
|
+
var alnumText = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
6004
|
+
function visibleText(sourceCode) {
|
|
6005
|
+
const jsx = (sourceCode.match(/>([^<>]*)</g) ?? []).map((m2) => m2.slice(1, -1).replace(/\{[^}]*\}/g, " ")).join(" ");
|
|
6006
|
+
let attrs = "";
|
|
6007
|
+
const attrRx = /\b(?:aria-label|placeholder|title|alt)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi;
|
|
6008
|
+
let m;
|
|
6009
|
+
while ((m = attrRx.exec(sourceCode)) !== null) attrs += " " + (m[1] ?? m[2] ?? "");
|
|
6010
|
+
return jsx + " " + attrs;
|
|
6011
|
+
}
|
|
6012
|
+
function findDroppedActionLabels(sourceCode, contract) {
|
|
6013
|
+
const actionSpec = contract?.actionSpec;
|
|
6014
|
+
if (actionSpec === void 0) return [];
|
|
6015
|
+
if (/\.label\b/.test(sourceCode)) return [];
|
|
6016
|
+
const vis = visibleText(sourceCode);
|
|
6017
|
+
const normVis = normText(vis);
|
|
6018
|
+
const alnumVis = alnumText(vis);
|
|
6019
|
+
const out = [];
|
|
6020
|
+
for (const [name, entry] of Object.entries(actionSpec)) {
|
|
6021
|
+
const label = entry.label;
|
|
6022
|
+
if (typeof label !== "string" || label.length === 0 || label === name) continue;
|
|
6023
|
+
if (!LABEL_SPECIAL_CHAR.test(label)) continue;
|
|
6024
|
+
if (alnumText(label).length < 3) continue;
|
|
6025
|
+
if (normVis.includes(normText(label))) continue;
|
|
6026
|
+
if (alnumVis.includes(alnumText(label))) out.push({ name, label });
|
|
6027
|
+
}
|
|
6028
|
+
return out;
|
|
6029
|
+
}
|
|
6030
|
+
function runActionLabelDropped(input) {
|
|
6031
|
+
if (input.compiledCode === null) return [];
|
|
6032
|
+
return findDroppedActionLabels(input.sourceCode, input.contract).map(
|
|
6033
|
+
({ name, label }) => mkIssue(
|
|
6034
|
+
"universal.action_label_dropped",
|
|
6035
|
+
`The action "${name}" declares label "${label}", but the rendered control appears to drop its "${label.replace(/[a-z0-9\s]/gi, "").trim()}": the label's words are in the generated source, the full label is not \u2014 a transcription drop (ggui#1190).`,
|
|
6036
|
+
`Render the label EXACTLY as the contract states it \u2014 button text should be the verbatim \`actionSpec.${name}.label\`, or render it from data (\`{x.label}\`), never a re-typed copy that drops "&", "/", "+", etc.`,
|
|
6037
|
+
"warn"
|
|
6038
|
+
)
|
|
6039
|
+
);
|
|
6040
|
+
}
|
|
5846
6041
|
var UNIVERSAL_CHECKS = [
|
|
5847
6042
|
{
|
|
5848
6043
|
id: "universal.icon_name_known",
|
|
@@ -5862,6 +6057,18 @@ var UNIVERSAL_CHECKS = [
|
|
|
5862
6057
|
values: ALL_RENDER_VALUES,
|
|
5863
6058
|
run: runViewportSized
|
|
5864
6059
|
},
|
|
6060
|
+
{
|
|
6061
|
+
id: "universal.root_width_cap",
|
|
6062
|
+
axis: "render",
|
|
6063
|
+
values: ALL_RENDER_VALUES,
|
|
6064
|
+
run: runRootWidthCap
|
|
6065
|
+
},
|
|
6066
|
+
{
|
|
6067
|
+
id: "universal.action_label_dropped",
|
|
6068
|
+
axis: "render",
|
|
6069
|
+
values: ALL_RENDER_VALUES,
|
|
6070
|
+
run: runActionLabelDropped
|
|
6071
|
+
},
|
|
5865
6072
|
{
|
|
5866
6073
|
id: "universal.terminal_action_unguarded",
|
|
5867
6074
|
axis: "render",
|
|
@@ -6911,7 +7118,8 @@ function runAxisChecks(classification, input) {
|
|
|
6911
7118
|
...input.contract !== void 0 ? { contract: input.contract } : {},
|
|
6912
7119
|
originalPrompt: input.originalPrompt,
|
|
6913
7120
|
classification,
|
|
6914
|
-
...input.designMode !== void 0 ? { designMode: input.designMode } : {}
|
|
7121
|
+
...input.designMode !== void 0 ? { designMode: input.designMode } : {},
|
|
7122
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
6915
7123
|
};
|
|
6916
7124
|
if (input.compiledCode === null) {
|
|
6917
7125
|
traceAxisChecksSkipped(facts, "compiledCode null \u2014 no check ran");
|
|
@@ -6956,7 +7164,9 @@ function traceFacts(input) {
|
|
|
6956
7164
|
designMode: input.designMode ?? "constrained",
|
|
6957
7165
|
classification: input.classification.vector,
|
|
6958
7166
|
propsSpecKeys: Object.keys(propsSpec ?? {}),
|
|
6959
|
-
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {})
|
|
7167
|
+
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {}),
|
|
7168
|
+
// No default here, unlike designMode: an absent canvas is a fact about the caller, not a guess to paper over.
|
|
7169
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
6960
7170
|
};
|
|
6961
7171
|
}
|
|
6962
7172
|
var STYLING_PROFILE_TRUNCATION_MARKER = " \u2026[truncated at the profile bound]";
|
|
@@ -7061,87 +7271,6 @@ function judgeDesignIdentity(src) {
|
|
|
7061
7271
|
function resetJudgeDesignIdentityCache() {
|
|
7062
7272
|
identityCache.clear();
|
|
7063
7273
|
}
|
|
7064
|
-
|
|
7065
|
-
// src/design-mode.ts
|
|
7066
|
-
var CANVAS_CLASSES = [
|
|
7067
|
-
"xs-chat-card",
|
|
7068
|
-
"mobile-fullscreen-small",
|
|
7069
|
-
"md",
|
|
7070
|
-
"lg",
|
|
7071
|
-
"xl"
|
|
7072
|
-
];
|
|
7073
|
-
var CANVAS_VIEWPORTS = {
|
|
7074
|
-
"xs-chat-card": { width: 400, height: 640 },
|
|
7075
|
-
"mobile-fullscreen-small": { width: 390, height: 844 },
|
|
7076
|
-
md: { width: 768, height: 1024 },
|
|
7077
|
-
lg: { width: 1024, height: 768 },
|
|
7078
|
-
xl: { width: 1440, height: 900 }
|
|
7079
|
-
};
|
|
7080
|
-
function displayModeForCanvas(canvas) {
|
|
7081
|
-
return canvas === "xs-chat-card" ? "inline" : "fullscreen";
|
|
7082
|
-
}
|
|
7083
|
-
function canvasDisplayModeForShell(shell) {
|
|
7084
|
-
return shell === "chat" || shell === "inline" ? "inline" : "fullscreen";
|
|
7085
|
-
}
|
|
7086
|
-
var CANVAS_BREAKPOINTS = { md: 600, lg: 1024, xl: 1440 };
|
|
7087
|
-
function canvasForViewportWidth(mode, width) {
|
|
7088
|
-
if (mode === "inline") return "xs-chat-card";
|
|
7089
|
-
if (width < CANVAS_BREAKPOINTS.md) return "mobile-fullscreen-small";
|
|
7090
|
-
if (width < CANVAS_BREAKPOINTS.lg) return "md";
|
|
7091
|
-
if (width < CANVAS_BREAKPOINTS.xl) return "lg";
|
|
7092
|
-
return "xl";
|
|
7093
|
-
}
|
|
7094
|
-
function canvasForRendering(shellType, screen) {
|
|
7095
|
-
const shell = shellType ?? "fullscreen";
|
|
7096
|
-
if (canvasDisplayModeForShell(shell) === "inline") return "xs-chat-card";
|
|
7097
|
-
if (shell === "spatial") return "md";
|
|
7098
|
-
switch (screen ?? "universal") {
|
|
7099
|
-
case "mobile":
|
|
7100
|
-
return "mobile-fullscreen-small";
|
|
7101
|
-
case "tablet":
|
|
7102
|
-
return "md";
|
|
7103
|
-
default:
|
|
7104
|
-
return "lg";
|
|
7105
|
-
}
|
|
7106
|
-
}
|
|
7107
|
-
var CANVAS_DESCRIPTORS = {
|
|
7108
|
-
"xs-chat-card": {
|
|
7109
|
-
label: "extra-small chat card",
|
|
7110
|
-
minWidthPx: 320,
|
|
7111
|
-
maxWidthPx: 480,
|
|
7112
|
-
host: "an inline card inside a chat message bubble \u2014 the host draws the card border, shadow and rounded corners; the component fills the bubble width and takes its natural height"
|
|
7113
|
-
},
|
|
7114
|
-
"mobile-fullscreen-small": {
|
|
7115
|
-
label: "small mobile fullscreen",
|
|
7116
|
-
minWidthPx: 320,
|
|
7117
|
-
maxWidthPx: 599,
|
|
7118
|
-
host: "a phone-sized viewport the component owns edge to edge \u2014 single column, touch targets at least 44px, the component manages its own scroll"
|
|
7119
|
-
},
|
|
7120
|
-
md: {
|
|
7121
|
-
label: "medium panel",
|
|
7122
|
-
minWidthPx: 600,
|
|
7123
|
-
maxWidthPx: 1023,
|
|
7124
|
-
host: "a tablet viewport or a floating panel (spatial / picture-in-picture) \u2014 one or two columns, medium density"
|
|
7125
|
-
},
|
|
7126
|
-
lg: {
|
|
7127
|
-
label: "large fullscreen",
|
|
7128
|
-
minWidthPx: 1024,
|
|
7129
|
-
maxWidthPx: 1439,
|
|
7130
|
-
host: "a desktop viewport the component owns edge to edge \u2014 multi-column layouts, hover states and pointer interactions are available"
|
|
7131
|
-
},
|
|
7132
|
-
xl: {
|
|
7133
|
-
label: "extra-large fullscreen",
|
|
7134
|
-
minWidthPx: 1440,
|
|
7135
|
-
maxWidthPx: 1920,
|
|
7136
|
-
host: "a wide desktop viewport the component owns edge to edge \u2014 cap content width or use the extra room deliberately; never stretch a single column across the whole width"
|
|
7137
|
-
}
|
|
7138
|
-
};
|
|
7139
|
-
function describeCanvas(canvas) {
|
|
7140
|
-
const d = CANVAS_DESCRIPTORS[canvas];
|
|
7141
|
-
return `This component renders on the \`${canvas}\` canvas (${d.label}): ${d.minWidthPx}\u2013${d.maxWidthPx}px wide, ${d.host}. Design for the whole range \u2014 the host may size the iframe anywhere inside it, and the host owns the height: size to your content, never to the viewport.`;
|
|
7142
|
-
}
|
|
7143
|
-
|
|
7144
|
-
// src/evaluation/visual-evaluator.ts
|
|
7145
7274
|
function canvasFitPolicy(canvas) {
|
|
7146
7275
|
switch (canvas) {
|
|
7147
7276
|
case "xs-chat-card":
|