@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
|
@@ -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;
|
|
@@ -5799,6 +5878,126 @@ function runViewportSized(input) {
|
|
|
5799
5878
|
)
|
|
5800
5879
|
];
|
|
5801
5880
|
}
|
|
5881
|
+
var TERMINAL_WORDS = /* @__PURE__ */ new Set([
|
|
5882
|
+
"submit",
|
|
5883
|
+
"confirm",
|
|
5884
|
+
"approve",
|
|
5885
|
+
"schedule",
|
|
5886
|
+
"reserve",
|
|
5887
|
+
"book",
|
|
5888
|
+
"pay",
|
|
5889
|
+
"checkout",
|
|
5890
|
+
"purchase",
|
|
5891
|
+
"order"
|
|
5892
|
+
]);
|
|
5893
|
+
var TERMINAL_LABEL_RX = /\b(submit|confirm|approve|schedule|reserve|book|pay|checkout|purchase|place\s+order)\b/i;
|
|
5894
|
+
var GUARD_RX = /\b(disabled|aria-disabled)\s*=/;
|
|
5895
|
+
function nameWords(name) {
|
|
5896
|
+
return name.split(/(?=[A-Z])|[_\-\s]+/).map((w) => w.toLowerCase()).filter((w) => w.length > 0);
|
|
5897
|
+
}
|
|
5898
|
+
function findUnguardedTerminalControls(sourceCode) {
|
|
5899
|
+
if (GUARD_RX.test(sourceCode)) return [];
|
|
5900
|
+
const names = /* @__PURE__ */ new Set();
|
|
5901
|
+
for (const m of sourceCode.matchAll(/useAction(?:<[^>]*>)?\(\s*['"`]([^'"`]+)['"`]/g)) {
|
|
5902
|
+
const name = m[1] ?? "";
|
|
5903
|
+
if (nameWords(name).some((w) => TERMINAL_WORDS.has(w))) names.add(name);
|
|
5904
|
+
}
|
|
5905
|
+
for (const m of sourceCode.matchAll(/>([^<>{}]{1,60})<\/Button>/g)) {
|
|
5906
|
+
const label = (m[1] ?? "").replace(/\s+/g, " ").trim();
|
|
5907
|
+
if (label.length > 0 && TERMINAL_LABEL_RX.test(label)) names.add(label.slice(0, 40));
|
|
5908
|
+
}
|
|
5909
|
+
return [...names];
|
|
5910
|
+
}
|
|
5911
|
+
function runTerminalActionUnguarded(input) {
|
|
5912
|
+
if (input.compiledCode === null) return [];
|
|
5913
|
+
const found = findUnguardedTerminalControls(input.sourceCode);
|
|
5914
|
+
if (found.length === 0) return [];
|
|
5915
|
+
const list = found.map((t) => `"${t}"`).join(", ");
|
|
5916
|
+
return [
|
|
5917
|
+
mkIssue(
|
|
5918
|
+
"universal.terminal_action_unguarded",
|
|
5919
|
+
`${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.`,
|
|
5920
|
+
'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.',
|
|
5921
|
+
"warn"
|
|
5922
|
+
)
|
|
5923
|
+
];
|
|
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
|
+
}
|
|
5802
6001
|
var UNIVERSAL_CHECKS = [
|
|
5803
6002
|
{
|
|
5804
6003
|
id: "universal.icon_name_known",
|
|
@@ -5818,6 +6017,18 @@ var UNIVERSAL_CHECKS = [
|
|
|
5818
6017
|
values: ALL_RENDER_VALUES,
|
|
5819
6018
|
run: runViewportSized
|
|
5820
6019
|
},
|
|
6020
|
+
{
|
|
6021
|
+
id: "universal.root_width_cap",
|
|
6022
|
+
axis: "render",
|
|
6023
|
+
values: ALL_RENDER_VALUES,
|
|
6024
|
+
run: runRootWidthCap
|
|
6025
|
+
},
|
|
6026
|
+
{
|
|
6027
|
+
id: "universal.terminal_action_unguarded",
|
|
6028
|
+
axis: "render",
|
|
6029
|
+
values: ALL_RENDER_VALUES,
|
|
6030
|
+
run: runTerminalActionUnguarded
|
|
6031
|
+
},
|
|
5821
6032
|
{
|
|
5822
6033
|
id: "universal.accent_text_ink",
|
|
5823
6034
|
axis: "render",
|
|
@@ -6861,7 +7072,8 @@ function runAxisChecks(classification, input) {
|
|
|
6861
7072
|
...input.contract !== void 0 ? { contract: input.contract } : {},
|
|
6862
7073
|
originalPrompt: input.originalPrompt,
|
|
6863
7074
|
classification,
|
|
6864
|
-
...input.designMode !== void 0 ? { designMode: input.designMode } : {}
|
|
7075
|
+
...input.designMode !== void 0 ? { designMode: input.designMode } : {},
|
|
7076
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
6865
7077
|
};
|
|
6866
7078
|
if (input.compiledCode === null) {
|
|
6867
7079
|
traceAxisChecksSkipped(facts, "compiledCode null \u2014 no check ran");
|
|
@@ -6906,7 +7118,9 @@ function traceFacts(input) {
|
|
|
6906
7118
|
designMode: input.designMode ?? "constrained",
|
|
6907
7119
|
classification: input.classification.vector,
|
|
6908
7120
|
propsSpecKeys: Object.keys(propsSpec ?? {}),
|
|
6909
|
-
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {})
|
|
7121
|
+
propsSpecPropertyKeys: Object.keys(propsSpec?.properties ?? {}),
|
|
7122
|
+
// No default here, unlike designMode: an absent canvas is a fact about the caller, not a guess to paper over.
|
|
7123
|
+
...input.canvas !== void 0 ? { canvas: input.canvas } : {}
|
|
6910
7124
|
};
|
|
6911
7125
|
}
|
|
6912
7126
|
var STYLING_PROFILE_TRUNCATION_MARKER = " \u2026[truncated at the profile bound]";
|
|
@@ -7011,87 +7225,6 @@ function judgeDesignIdentity(src) {
|
|
|
7011
7225
|
function resetJudgeDesignIdentityCache() {
|
|
7012
7226
|
identityCache.clear();
|
|
7013
7227
|
}
|
|
7014
|
-
|
|
7015
|
-
// src/design-mode.ts
|
|
7016
|
-
var CANVAS_CLASSES = [
|
|
7017
|
-
"xs-chat-card",
|
|
7018
|
-
"mobile-fullscreen-small",
|
|
7019
|
-
"md",
|
|
7020
|
-
"lg",
|
|
7021
|
-
"xl"
|
|
7022
|
-
];
|
|
7023
|
-
var CANVAS_VIEWPORTS = {
|
|
7024
|
-
"xs-chat-card": { width: 400, height: 640 },
|
|
7025
|
-
"mobile-fullscreen-small": { width: 390, height: 844 },
|
|
7026
|
-
md: { width: 768, height: 1024 },
|
|
7027
|
-
lg: { width: 1024, height: 768 },
|
|
7028
|
-
xl: { width: 1440, height: 900 }
|
|
7029
|
-
};
|
|
7030
|
-
function displayModeForCanvas(canvas) {
|
|
7031
|
-
return canvas === "xs-chat-card" ? "inline" : "fullscreen";
|
|
7032
|
-
}
|
|
7033
|
-
function canvasDisplayModeForShell(shell) {
|
|
7034
|
-
return shell === "chat" || shell === "inline" ? "inline" : "fullscreen";
|
|
7035
|
-
}
|
|
7036
|
-
var CANVAS_BREAKPOINTS = { md: 600, lg: 1024, xl: 1440 };
|
|
7037
|
-
function canvasForViewportWidth(mode, width) {
|
|
7038
|
-
if (mode === "inline") return "xs-chat-card";
|
|
7039
|
-
if (width < CANVAS_BREAKPOINTS.md) return "mobile-fullscreen-small";
|
|
7040
|
-
if (width < CANVAS_BREAKPOINTS.lg) return "md";
|
|
7041
|
-
if (width < CANVAS_BREAKPOINTS.xl) return "lg";
|
|
7042
|
-
return "xl";
|
|
7043
|
-
}
|
|
7044
|
-
function canvasForRendering(shellType, screen) {
|
|
7045
|
-
const shell = shellType ?? "fullscreen";
|
|
7046
|
-
if (canvasDisplayModeForShell(shell) === "inline") return "xs-chat-card";
|
|
7047
|
-
if (shell === "spatial") return "md";
|
|
7048
|
-
switch (screen ?? "universal") {
|
|
7049
|
-
case "mobile":
|
|
7050
|
-
return "mobile-fullscreen-small";
|
|
7051
|
-
case "tablet":
|
|
7052
|
-
return "md";
|
|
7053
|
-
default:
|
|
7054
|
-
return "lg";
|
|
7055
|
-
}
|
|
7056
|
-
}
|
|
7057
|
-
var CANVAS_DESCRIPTORS = {
|
|
7058
|
-
"xs-chat-card": {
|
|
7059
|
-
label: "extra-small chat card",
|
|
7060
|
-
minWidthPx: 320,
|
|
7061
|
-
maxWidthPx: 480,
|
|
7062
|
-
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"
|
|
7063
|
-
},
|
|
7064
|
-
"mobile-fullscreen-small": {
|
|
7065
|
-
label: "small mobile fullscreen",
|
|
7066
|
-
minWidthPx: 320,
|
|
7067
|
-
maxWidthPx: 599,
|
|
7068
|
-
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"
|
|
7069
|
-
},
|
|
7070
|
-
md: {
|
|
7071
|
-
label: "medium panel",
|
|
7072
|
-
minWidthPx: 600,
|
|
7073
|
-
maxWidthPx: 1023,
|
|
7074
|
-
host: "a tablet viewport or a floating panel (spatial / picture-in-picture) \u2014 one or two columns, medium density"
|
|
7075
|
-
},
|
|
7076
|
-
lg: {
|
|
7077
|
-
label: "large fullscreen",
|
|
7078
|
-
minWidthPx: 1024,
|
|
7079
|
-
maxWidthPx: 1439,
|
|
7080
|
-
host: "a desktop viewport the component owns edge to edge \u2014 multi-column layouts, hover states and pointer interactions are available"
|
|
7081
|
-
},
|
|
7082
|
-
xl: {
|
|
7083
|
-
label: "extra-large fullscreen",
|
|
7084
|
-
minWidthPx: 1440,
|
|
7085
|
-
maxWidthPx: 1920,
|
|
7086
|
-
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"
|
|
7087
|
-
}
|
|
7088
|
-
};
|
|
7089
|
-
function describeCanvas(canvas) {
|
|
7090
|
-
const d = CANVAS_DESCRIPTORS[canvas];
|
|
7091
|
-
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.`;
|
|
7092
|
-
}
|
|
7093
|
-
|
|
7094
|
-
// src/evaluation/visual-evaluator.ts
|
|
7095
7228
|
function canvasFitPolicy(canvas) {
|
|
7096
7229
|
switch (canvas) {
|
|
7097
7230
|
case "xs-chat-card":
|