@ggui-ai/ui-gen 0.26.0 → 0.28.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.
Files changed (77) hide show
  1. package/dist/{adapter-BJwn74rx.d.ts → adapter-h4_V69LI.d.ts} +1 -1
  2. package/dist/adapters/base.d.ts +6 -1
  3. package/dist/adapters/base.js.map +1 -1
  4. package/dist/adapters/generation-dispatch.d.ts +2 -2
  5. package/dist/adapters/generation-dispatch.js +233 -17
  6. package/dist/adapters/generation-dispatch.js.map +1 -1
  7. package/dist/adapters/index.js +36 -14
  8. package/dist/adapters/index.js.map +1 -1
  9. package/dist/advanced/index.d.ts +4 -4
  10. package/dist/advanced/index.js +268 -28
  11. package/dist/advanced/index.js.map +1 -1
  12. package/dist/boilerplate.js +4 -6
  13. package/dist/boilerplate.js.map +1 -1
  14. package/dist/check/index.d.ts +1 -7
  15. package/dist/check/index.js +50 -4
  16. package/dist/check/index.js.map +1 -1
  17. package/dist/{create-ui-generator-N4gRXpcL.d.ts → create-ui-generator-BrZHF0cf.d.ts} +2 -2
  18. package/dist/{dispatch-BUoXRj_r.d.ts → dispatch-B07TI30d.d.ts} +1 -1
  19. package/dist/evaluation/axis-checks/index.d.ts +3 -3
  20. package/dist/evaluation/axis-checks/index.js +97 -1
  21. package/dist/evaluation/axis-checks/index.js.map +1 -1
  22. package/dist/evaluation/axis-checks/registry.d.ts +1 -1
  23. package/dist/evaluation/axis-checks/registry.js +97 -1
  24. package/dist/evaluation/axis-checks/registry.js.map +1 -1
  25. package/dist/evaluation/index.d.ts +22 -12
  26. package/dist/evaluation/index.js +138 -14
  27. package/dist/evaluation/index.js.map +1 -1
  28. package/dist/evaluation/types.d.ts +1 -1
  29. package/dist/harness/check/runtime-render/index.d.ts +3 -3
  30. package/dist/harness/index.d.ts +1 -1
  31. package/dist/harness/index.js +6 -6
  32. package/dist/harness/index.js.map +1 -1
  33. package/dist/harness/prompts.js +1 -4
  34. package/dist/harness/prompts.js.map +1 -1
  35. package/dist/harness/result-types.d.ts +14 -3
  36. package/dist/harness/result-types.js.map +1 -1
  37. package/dist/harness/runtime.d.ts +1 -1
  38. package/dist/harness/runtime.js +6 -7
  39. package/dist/harness/runtime.js.map +1 -1
  40. package/dist/harness/types-public.d.ts +1 -1
  41. package/dist/harness/types-public.js +4 -6
  42. package/dist/harness/types-public.js.map +1 -1
  43. package/dist/harness/validator-trace-sink.d.ts +1 -1
  44. package/dist/index.d.ts +6 -6
  45. package/dist/index.js +268 -28
  46. package/dist/index.js.map +1 -1
  47. package/dist/patch.d.ts +1 -1
  48. package/dist/{types-public-B7wn4ce5.d.ts → types-public-h8IMnYuh.d.ts} +4 -0
  49. package/dist/{visual-evaluator-C9L-o6ap.d.ts → visual-evaluator-C2strxqD.d.ts} +1 -1
  50. package/dist/workflows.d.ts +1 -1
  51. package/package.json +13 -13
  52. package/src/adapters/base.ts +6 -1
  53. package/src/adapters/claude/message-parser.ts +5 -6
  54. package/src/adapters/claude/sdk-tool-pins.ts +44 -0
  55. package/src/adapters/claude/sdk.ts +3 -3
  56. package/src/adapters/claude/source-capture.ts +20 -0
  57. package/src/adapters/provider-router.ts +1 -0
  58. package/src/boilerplate/system-prompt.ts +3 -2
  59. package/src/check/run-tier0.ts +61 -0
  60. package/src/create-ui-generator.ts +4 -2
  61. package/src/design-system-docs.ts +2 -1
  62. package/src/evaluation/axis-checks/checks/state-merge.ts +1 -1
  63. package/src/evaluation/axis-checks/helpers.ts +125 -0
  64. package/src/evaluation/criteria/resolve.ts +19 -1
  65. package/src/evaluation/evaluator.ts +2 -2
  66. package/src/evaluation/llm-evaluator.ts +2 -2
  67. package/src/evaluation/loop.ts +25 -4
  68. package/src/evaluation/message-parsing.ts +11 -12
  69. package/src/evaluation/types-public.ts +4 -0
  70. package/src/evaluation/visual-evaluator.ts +1 -1
  71. package/src/harness/coding/assemble-result.ts +1 -0
  72. package/src/harness/coding/dupe-break.ts +70 -0
  73. package/src/harness/coding/generate-task-runner.ts +5 -1
  74. package/src/harness/coding/run-coding-turn.ts +56 -1
  75. package/src/harness/result-types.ts +12 -0
  76. package/src/index.ts +1 -1
  77. package/src/taught-tokens.ts +5 -6
@@ -1,12 +1,12 @@
1
- import { r as CriteriaSelection, h as CriteriaContext, C as CriteriaAnswerCounts, s as VisionFinishReason, k as CriteriaBlock } from '../types-public-B7wn4ce5.js';
2
- export { A as AxisCheck, a as AxisCheckInput, t as CRITERIA, n as CanvasHostPresentation, j as CanvasJudgeRecord, l as CanvasPresentationOutcome, u as CanvasVisualSummary, v as ContractFeedbackRecord, w as CriterionCoverage, x as CriterionRunStatus, D as DEFAULT_QUALITY_CONFIG, y as EvalCategory, z as EvalCriterion, E as EvalIssue, B as EvalOutcome, e as EvalResult, q as EvalTier, H as HostInlineFrame, F as HostPresentationIgnoredReason, G as LLM_EVAL_STATIC_CRITERIA, I as Priority, Q as QualityConfig, K as QualityMode, o as VisualEvalSummary, M as buildCodingCriteriaSummary, N as criteriaFor, O as getActionableIssues, S as getCriteriaByPriority, T as getCriterionById, U as getLLMCriteria, W as isBlocked, m as matches, X as notApplicableCoverage, Y as priorityForIssue } from '../types-public-B7wn4ce5.js';
1
+ import { r as CriteriaSelection, h as CriteriaContext, C as CriteriaAnswerCounts, s as VisionFinishReason, k as CriteriaBlock } from '../types-public-h8IMnYuh.js';
2
+ export { A as AxisCheck, a as AxisCheckInput, t as CRITERIA, n as CanvasHostPresentation, j as CanvasJudgeRecord, l as CanvasPresentationOutcome, u as CanvasVisualSummary, v as ContractFeedbackRecord, w as CriterionCoverage, x as CriterionRunStatus, D as DEFAULT_QUALITY_CONFIG, y as EvalCategory, z as EvalCriterion, E as EvalIssue, B as EvalOutcome, e as EvalResult, q as EvalTier, H as HostInlineFrame, F as HostPresentationIgnoredReason, G as LLM_EVAL_STATIC_CRITERIA, I as Priority, Q as QualityConfig, K as QualityMode, o as VisualEvalSummary, M as buildCodingCriteriaSummary, N as criteriaFor, O as getActionableIssues, S as getCriteriaByPriority, T as getCriterionById, U as getLLMCriteria, W as isBlocked, m as matches, X as notApplicableCoverage, Y as priorityForIssue } from '../types-public-h8IMnYuh.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, CriteriaAnswer } 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-BUoXRj_r.js';
8
- import { E as EdgeVerdict, a as EdgeBlock, C as CriteriaCallTokens } from '../visual-evaluator-C9L-o6ap.js';
9
- export { b as CARD_HEIGHT_EXPRESSION, c as CONTENT_HEIGHT_EXPRESSION, d as CanvasFitPolicy, e as CanvasVisualResult, f as CaptureMode, g as ChromiumProvider, h as CriteriaContextInput, i as CriteriaContextSources, j as EDGE_TOLERANCE_PX, k as EdgeOffset, H as HOST_COLOUR_PATTERN, l as HOST_FRAME_BOUNDS, J as JUDGE_GROUND_MARGIN_PX, m as JUDGE_INK_INSET_PX, n as JudgeDesignIdentity, N as NaturalCaptureOptions, S as ScreenshotAttempt, o as ScreenshotBrowser, p as ScreenshotClip, q as ScreenshotDeps, r as ScreenshotLauncher, s as ScreenshotPage, t as StoredCaptureInput, u as StoredCaptureOutcome, v as StoredCaptureVerdict, w as VISUAL_EVAL_PROMPT, x as VISUAL_JUDGE_MAX_OUTPUT_TOKENS, y as VISUAL_JUDGE_PROMPT_DIGEST, z as VISUAL_JUDGE_PROMPT_VERSION, A as VisualEvalConfig, B as VisualEvalContext, D as VisualEvalDeps, F as VisualEvalDetailed, G as VisualEvalOutcome, I as VisualEvaluationResult, V as VisualLegTokens, K as callMultimodalLLM, L as canvasBlankIssue, M as canvasFitPolicy, O as canvasOverflowIssue, P as captureScreenshot, Q as captureScreenshotDetailed, R as chromaOfCssTokens, T as criteriaContextFor, U as designTreeSha256, W as judgeDesignIdentity, X as judgeEdges, Y as judgeStoredCapture, Z as resetJudgeDesignIdentityCache, _ as resolveDesignPackageDir, $ as resolveLaunchOptions, a0 as runVisualEval, a1 as runVisualEvaluation, a2 as runVisualEvaluationDetailed, a3 as summarizeVisualResult } from '../visual-evaluator-C9L-o6ap.js';
7
+ export { R as RunAxisChecksInput, r as runAxisChecks } from '../dispatch-B07TI30d.js';
8
+ import { E as EdgeVerdict, a as EdgeBlock, C as CriteriaCallTokens } from '../visual-evaluator-C2strxqD.js';
9
+ export { b as CARD_HEIGHT_EXPRESSION, c as CONTENT_HEIGHT_EXPRESSION, d as CanvasFitPolicy, e as CanvasVisualResult, f as CaptureMode, g as ChromiumProvider, h as CriteriaContextInput, i as CriteriaContextSources, j as EDGE_TOLERANCE_PX, k as EdgeOffset, H as HOST_COLOUR_PATTERN, l as HOST_FRAME_BOUNDS, J as JUDGE_GROUND_MARGIN_PX, m as JUDGE_INK_INSET_PX, n as JudgeDesignIdentity, N as NaturalCaptureOptions, S as ScreenshotAttempt, o as ScreenshotBrowser, p as ScreenshotClip, q as ScreenshotDeps, r as ScreenshotLauncher, s as ScreenshotPage, t as StoredCaptureInput, u as StoredCaptureOutcome, v as StoredCaptureVerdict, w as VISUAL_EVAL_PROMPT, x as VISUAL_JUDGE_MAX_OUTPUT_TOKENS, y as VISUAL_JUDGE_PROMPT_DIGEST, z as VISUAL_JUDGE_PROMPT_VERSION, A as VisualEvalConfig, B as VisualEvalContext, D as VisualEvalDeps, F as VisualEvalDetailed, G as VisualEvalOutcome, I as VisualEvaluationResult, V as VisualLegTokens, K as callMultimodalLLM, L as canvasBlankIssue, M as canvasFitPolicy, O as canvasOverflowIssue, P as captureScreenshot, Q as captureScreenshotDetailed, R as chromaOfCssTokens, T as criteriaContextFor, U as designTreeSha256, W as judgeDesignIdentity, X as judgeEdges, Y as judgeStoredCapture, Z as resetJudgeDesignIdentityCache, _ as resolveDesignPackageDir, $ as resolveLaunchOptions, a0 as runVisualEval, a1 as runVisualEvaluation, a2 as runVisualEvaluationDetailed, a3 as summarizeVisualResult } from '../visual-evaluator-C2strxqD.js';
10
10
  export { b as CANVAS_BREAKPOINTS, c as CANVAS_CLASSES, d as CANVAS_DESCRIPTORS, e as CANVAS_VIEWPORTS, C as CanvasClass, f as CanvasDescriptor, g as CanvasDisplayMode, a as CanvasViewport, j as canvasDisplayModeForShell, k as canvasForRendering, l as canvasForViewportWidth, m as describeCanvas } from '../design-mode-DGWN_Gkm.js';
11
11
  import { AppTheme } from '@ggui-ai/protocol';
12
12
  import { C as CriteriaBank } from '../bank-Ctdp3FUA.js';
@@ -43,8 +43,13 @@ interface EvaluationLoopOptions {
43
43
  cwd?: string;
44
44
  /** MCP servers available to the fix agent */
45
45
  mcpServers?: Record<string, McpServerConfig>;
46
- /** Tools the fix agent is allowed to call */
46
+ /** Tool names to approve. Absent → every tool of every server in `mcpServers` (ggui#1714). */
47
47
  allowedTools?: string[];
48
+ /**
49
+ * CLI built-in tools to offer the fix agent (e.g. `['Write']`). Default: none.
50
+ * An explicit opt-in: a built-in that writes or executes acts on the host (ggui#1714).
51
+ */
52
+ builtinTools?: readonly string[];
48
53
  /** LLM model for fix rounds */
49
54
  model?: string;
50
55
  /** Environment variables (includes BYOK credentials) */
@@ -167,13 +172,14 @@ declare function extractEvalResult(messages: SdkMessage[]): EvaluationResult | u
167
172
  */
168
173
  declare function extractCompiledCodeFromMessage(message: SdkMessage): string | undefined;
169
174
  /**
170
- * Extract source code from an assistant's Write tool_use message.
175
+ * Extract source code from an assistant message's tool_use blocks.
171
176
  *
172
- * Looks for `tool_use` blocks with `name === 'Write'` and returns
173
- * the `input.content` string. If multiple Write calls exist, returns
174
- * the last one (the final version).
177
+ * Reads the bridged compile tool (`*__compile_component`, `input.code`)
178
+ * and the CLI's `Write` (`input.content`, offered only by opt-in), by the
179
+ * one rule in `adapters/claude/source-capture.ts` (ggui#1714). If several
180
+ * calls carry source, returns the last one (the final version).
175
181
  *
176
- * Used by: loop.ts, generator.ts
182
+ * Used by: loop.ts
177
183
  */
178
184
  declare function extractSourceCodeFromMessage(message: SdkMessage): string | undefined;
179
185
  /**
@@ -183,7 +189,7 @@ declare function extractSourceCodeFromMessage(message: SdkMessage): string | und
183
189
  */
184
190
  declare function extractCompiledCode(messages: SdkMessage[]): string | undefined;
185
191
  /**
186
- * Scan all messages for the last sourceCode from Write tool_use.
192
+ * Scan all messages for the last sourceCode a tool_use carried.
187
193
  *
188
194
  * Convenience wrapper for tests and one-shot extraction.
189
195
  */
@@ -282,6 +288,8 @@ interface CriteriaMeasurements {
282
288
  * `null` when the probe ran and failed.
283
289
  */
284
290
  readonly edge?: EdgeVerdict | null;
291
+ /** ggui#1711 — the capture includes a state after an action ran. Absent = no (every capture today). */
292
+ readonly postActionCapture?: boolean;
285
293
  }
286
294
  declare function resolveCriteriaBlock(args: {
287
295
  readonly bank: CriteriaBank;
@@ -314,6 +322,8 @@ interface CriteriaJudgeInputs {
314
322
  readonly frame?: CriteriaJudgeFrame;
315
323
  /** JSON text of the props the card was rendered with; bounded by {@link CRITERIA_PROPS_MAX_CHARS}. */
316
324
  readonly propsJson?: string;
325
+ /** ggui#1711 — the capture includes a post-action state; absent = no, and rows needing one are not asked. */
326
+ readonly postActionCapture?: boolean;
317
327
  }
318
328
  /** The judge's prompt block for the selected `judge` rows; empty when none is selected. */
319
329
  declare function buildCriteriaJudgeBlock(bank: CriteriaBank, selected: CriteriaSelectionResult, inputs?: CriteriaJudgeInputs): string;
@@ -415,6 +415,13 @@ function buildCodingCriteriaSummary(designMode = "constrained") {
415
415
  }
416
416
  return lines.join("\n");
417
417
  }
418
+
419
+ // src/adapters/claude/sdk-tool-pins.ts
420
+ function sdkToolPins(input) {
421
+ const builtins = [...input.builtinTools ?? []];
422
+ const approved = input.allowedTools !== void 0 ? [...input.allowedTools] : Object.keys(input.mcpServers ?? {}).map((name) => `mcp__${name}`);
423
+ return { tools: builtins, settingSources: [], allowedTools: [...approved, ...builtins] };
424
+ }
418
425
  function createAnthropicClient(rawKey) {
419
426
  if (rawKey === void 0) {
420
427
  return new Anthropic({
@@ -475,6 +482,8 @@ function claudeCodeLoginQueryOptions() {
475
482
  function getBedrockModelId(model) {
476
483
  const BEDROCK_MAP = {
477
484
  "anthropic/claude-haiku-4-5": "us.anthropic.claude-haiku-4-5-20251001-v1:0",
485
+ "anthropic/claude-haiku-5-5": "us.anthropic.claude-haiku-5-5",
486
+ // listed ACTIVE in us-east-1 (ggui#1743)
478
487
  "anthropic/claude-sonnet-4-6": "us.anthropic.claude-sonnet-4-6",
479
488
  "anthropic/claude-opus-4-6": "us.anthropic.claude-opus-4-6-v1:0",
480
489
  // Claude 5-family (ggui#706, strings verified 2026-09-02 against
@@ -2337,16 +2346,26 @@ function buildEvalResult(raw, passThreshold, inputTokens, outputTokens) {
2337
2346
  function getDefaultEvalModel(provider) {
2338
2347
  switch (provider) {
2339
2348
  case "claude":
2340
- return "claude-haiku-4-5-20251001";
2349
+ return "claude-haiku-5-5";
2341
2350
  case "openai":
2342
2351
  return "gpt-5.6-luna";
2343
2352
  case "google":
2344
2353
  return "gemini-3.5-flash-lite";
2345
2354
  default:
2346
- return "claude-haiku-4-5-20251001";
2355
+ return "claude-haiku-5-5";
2347
2356
  }
2348
2357
  }
2349
2358
 
2359
+ // src/adapters/claude/source-capture.ts
2360
+ var COMPILE_TOOL_SUFFIX = "__compile_component";
2361
+ function sourceCodeFromToolUse(name, input) {
2362
+ if (typeof name !== "string") return void 0;
2363
+ const field2 = name === "Write" ? "content" : name.endsWith(COMPILE_TOOL_SUFFIX) ? "code" : void 0;
2364
+ if (field2 === void 0 || typeof input !== "object" || input === null) return void 0;
2365
+ const value = Reflect.get(input, field2);
2366
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2367
+ }
2368
+
2350
2369
  // src/evaluation/message-parsing.ts
2351
2370
  function extractToolResultTexts(message) {
2352
2371
  if (message.type !== "user") return [];
@@ -2416,12 +2435,9 @@ function extractSourceCodeFromMessage(message) {
2416
2435
  const content = betaMessage?.content;
2417
2436
  if (!Array.isArray(content)) return void 0;
2418
2437
  for (const block of content) {
2419
- if (block.type === "tool_use" && block.name === "Write") {
2420
- const input = block.input;
2421
- if (input?.content) {
2422
- sourceCode = input.content;
2423
- }
2424
- }
2438
+ if (block.type !== "tool_use") continue;
2439
+ const value = sourceCodeFromToolUse(block.name, block.input);
2440
+ if (value !== void 0) sourceCode = value;
2425
2441
  }
2426
2442
  return sourceCode;
2427
2443
  }
@@ -2540,6 +2556,12 @@ async function runEvaluationLoop(options) {
2540
2556
  let currentSourceCode = context.sourceCode;
2541
2557
  let round2 = 0;
2542
2558
  const maxRounds = Math.min(config.maxRounds ?? 3, MAX_EVAL_ROUNDS_HARD_LIMIT);
2559
+ const offersATool = Object.keys(generatorOptions?.mcpServers ?? {}).length > 0 || (generatorOptions?.builtinTools?.length ?? 0) > 0;
2560
+ if (maxRounds > 1 && !offersATool) {
2561
+ throw new Error(
2562
+ "runEvaluationLoop: a fix round needs a tool that can return code \u2014 pass generatorOptions.mcpServers (e.g. a server with compile_component) or opt into a built-in with generatorOptions.builtinTools (e.g. ['Write'])."
2563
+ );
2564
+ }
2543
2565
  while (round2 < maxRounds) {
2544
2566
  round2++;
2545
2567
  onProgress?.({ type: "evaluating", round: round2 });
@@ -2579,12 +2601,15 @@ async function runEvaluationLoop(options) {
2579
2601
  maxTurns: 15,
2580
2602
  maxBudgetUsd: config.maxBudgetPerFix,
2581
2603
  env,
2582
- permissionMode: "bypassPermissions",
2583
- allowDangerouslySkipPermissions: true,
2584
2604
  ...cliPath && { pathToClaudeCodeExecutable: cliPath },
2585
2605
  ...generatorOptions?.cwd && { cwd: generatorOptions.cwd },
2586
2606
  ...generatorOptions?.mcpServers && { mcpServers: generatorOptions.mcpServers },
2587
- ...generatorOptions?.allowedTools && { allowedTools: generatorOptions.allowedTools },
2607
+ // ggui#1714 — no CLI built-ins unless asked for, no host settings, no permission bypass.
2608
+ ...sdkToolPins({
2609
+ mcpServers: generatorOptions?.mcpServers,
2610
+ allowedTools: generatorOptions?.allowedTools,
2611
+ builtinTools: generatorOptions?.builtinTools
2612
+ }),
2588
2613
  ...generatorOptions?.model && { model: generatorOptions.model },
2589
2614
  ...generatorOptions?.stderr && { stderr: generatorOptions.stderr }
2590
2615
  }
@@ -2897,10 +2922,96 @@ function getInitialValuePropNames(contract) {
2897
2922
  }
2898
2923
  return names;
2899
2924
  }
2925
+ function objectLiteralKeysAt(src, open) {
2926
+ if (src[open] !== "{") return void 0;
2927
+ const keys = [];
2928
+ let depth = 0;
2929
+ let expectKey = true;
2930
+ for (let i = open; i < src.length; i++) {
2931
+ const c = src[i];
2932
+ if (c === '"' || c === "'" || c === "`") {
2933
+ let j = i + 1;
2934
+ while (j < src.length && src[j] !== c) j += src[j] === "\\" ? 2 : 1;
2935
+ if (depth === 1 && expectKey && /^\s*:/.test(src.slice(j + 1))) keys.push(src.slice(i + 1, j));
2936
+ i = j;
2937
+ expectKey = false;
2938
+ continue;
2939
+ }
2940
+ if (c === "{" || c === "[" || c === "(") {
2941
+ depth++;
2942
+ if (depth === 1) expectKey = true;
2943
+ continue;
2944
+ }
2945
+ if (c === "}" || c === "]" || c === ")") {
2946
+ depth--;
2947
+ if (depth === 0) return keys;
2948
+ continue;
2949
+ }
2950
+ if (depth !== 1) continue;
2951
+ if (c === ",") {
2952
+ expectKey = true;
2953
+ continue;
2954
+ }
2955
+ if (expectKey && /[A-Za-z_$]/.test(c ?? "")) {
2956
+ const m = /^([A-Za-z_$][\w$]*)\s*(:|,|\})/.exec(src.slice(i));
2957
+ if (m !== null && m[1] !== void 0) keys.push(m[1]);
2958
+ expectKey = false;
2959
+ }
2960
+ }
2961
+ return keys;
2962
+ }
2963
+ function callArgsAt(src, open) {
2964
+ const args = [];
2965
+ let depth = 0;
2966
+ let start = open + 1;
2967
+ for (let i = open; i < src.length; i++) {
2968
+ const c = src[i];
2969
+ if (c === '"' || c === "'" || c === "`") {
2970
+ let j = i + 1;
2971
+ while (j < src.length && src[j] !== c) j += src[j] === "\\" ? 2 : 1;
2972
+ i = j;
2973
+ continue;
2974
+ }
2975
+ if (c === "(" || c === "{" || c === "[") depth++;
2976
+ else if (c === ")" || c === "}" || c === "]") {
2977
+ depth--;
2978
+ if (depth === 0) {
2979
+ args.push(src.slice(start, i));
2980
+ return args;
2981
+ }
2982
+ } else if (c === "," && depth === 1) {
2983
+ args.push(src.slice(start, i));
2984
+ start = i + 1;
2985
+ }
2986
+ }
2987
+ return args;
2988
+ }
2989
+ function initialStateKeys(src, argStart, argText) {
2990
+ const lead = argText.length - argText.trimStart().length;
2991
+ let at = argStart + lead;
2992
+ let text = argText.trim();
2993
+ const lazy = /^\(\s*\)\s*=>\s*\(?\s*/.exec(text);
2994
+ if (lazy !== null) {
2995
+ at += lazy[0].length;
2996
+ text = text.slice(lazy[0].length);
2997
+ }
2998
+ if (text.startsWith("{")) return objectLiteralKeysAt(src, at) ?? [];
2999
+ const ident = /^([A-Za-z_$][\w$]*)\s*\)?\s*$/.exec(text);
3000
+ if (ident === null || ident[1] === void 0) return [];
3001
+ const decls = [...src.matchAll(new RegExp(`(?:const|let|var)\\s+${ident[1]}\\s*(?::[^=]{1,200})?=\\s*`, "g"))];
3002
+ const decl = decls.length === 1 ? decls[0] : void 0;
3003
+ if (decl === void 0) return [];
3004
+ return objectLiteralKeysAt(src, (decl.index ?? 0) + decl[0].length) ?? [];
3005
+ }
2900
3006
  function collectStateKeys(src) {
2901
3007
  const keys = /* @__PURE__ */ new Set();
2902
3008
  const varRe = /const\s*\[\s*(\w+)\s*,\s*(\w+)\s*\]\s*=\s*useState/g;
2903
3009
  for (const m of src.matchAll(varRe)) keys.add(m[1]);
3010
+ const contextRe = /const\s*\[\s*(\w+)\s*,\s*\w+\s*\]\s*=\s*useGguiContext\s*(?:<[^>]*>)?\s*\(\s*['"`](\w+)['"`]/g;
3011
+ for (const m of src.matchAll(contextRe)) {
3012
+ keys.add(m[1]);
3013
+ keys.add(m[2]);
3014
+ }
2904
3015
  const objRe = /useState(?:<[^>]*>)?\s*\(\s*\{([\s\S]*?)\}\s*\)/g;
2905
3016
  for (const m of src.matchAll(objRe)) {
2906
3017
  const keyRe = /(?:^|,)\s*(\w+)\s*:/g;
@@ -2911,6 +3022,16 @@ function collectStateKeys(src) {
2911
3022
  const keyRe = /(?:^|,)\s*(\w+)\s*:/g;
2912
3023
  for (const km of m[1].matchAll(keyRe)) keys.add(km[1]);
2913
3024
  }
3025
+ for (const m of src.matchAll(/\b(useState|useReducer)\s*(?:<[^>]*>)?\s*\(/g)) {
3026
+ const open = (m.index ?? 0) + m[0].length - 1;
3027
+ const args = callArgsAt(src, open);
3028
+ const which = m[1] === "useReducer" ? 1 : 0;
3029
+ const arg = args[which];
3030
+ if (arg === void 0) continue;
3031
+ let argStart = open + 1;
3032
+ for (let k = 0; k < which; k++) argStart += (args[k]?.length ?? 0) + 1;
3033
+ for (const key of initialStateKeys(src, argStart, arg)) keys.add(key);
3034
+ }
2914
3035
  return keys;
2915
3036
  }
2916
3037
  function mkIssue(subcategory, description, fix, result = "fail") {
@@ -3523,7 +3644,7 @@ function runNoHardcodedEntities(input) {
3523
3644
  mkIssue(
3524
3645
  "state.merge.no_hardcoded_entities",
3525
3646
  `Hardcoded entity array literal (multiple objects with "${idField}") in the component \u2014 entity data should come from state/props.`,
3526
- `Remove the literal array. Seed state from props.{entityProp} and merge updates via stream.`
3647
+ `Remove the literal array: this data comes from ${all.filter((e) => e.idField === idField).map((e) => `props.${e.name}`).join(" / ") || "props"}. Read it there (\`?? []\` for an absent value, never a literal default), seed state from it, and merge updates via stream.`
3527
3648
  )
3528
3649
  );
3529
3650
  }
@@ -4719,6 +4840,8 @@ var INSTRUMENT_BY_ID = {
4719
4840
  var INSTRUMENT_BESIDE_JUDGE = {
4720
4841
  "space.edge": "edge"
4721
4842
  };
4843
+ var REQUIRES_POST_ACTION_CAPTURE = /* @__PURE__ */ new Set(["state.feedback"]);
4844
+ var NO_POST_ACTION = "not evaluated: no post-action capture";
4722
4845
  function besideRead(kind, m) {
4723
4846
  if (m.edge === void 0) return { verdict: "n/a", evidence: "not measured: this capture had no page to read" };
4724
4847
  if (m.edge === null) return { verdict: "n/a", evidence: "edge probe failed on this capture" };
@@ -4744,6 +4867,7 @@ function instrumentRead(kind, m) {
4744
4867
  return { verdict: "n/a", evidence: `fill ${m.inkRatio.toFixed(3)} reported; no floor ruled` };
4745
4868
  }
4746
4869
  function readRow(row, answers, m, unansweredReason) {
4870
+ if (row.evaluation === "judge" && REQUIRES_POST_ACTION_CAPTURE.has(row.id) && m.postActionCapture !== true) return { verdict: "n/a", evidence: NO_POST_ACTION };
4747
4871
  if (row.evaluation === "judge") return majority(row.id, answers, unansweredReason);
4748
4872
  if (row.evaluation === "human") return { verdict: "n/a", evidence: `reader's column (status ${row.status})` };
4749
4873
  if (row.status !== "live") return { verdict: "n/a", evidence: `not implemented (status ${row.status})` };
@@ -4803,7 +4927,7 @@ ${text}
4803
4927
  }
4804
4928
  function buildCriteriaJudgeBlock(bank, selected, inputs = {}) {
4805
4929
  const byId = new Map(bankRows(bank).map((r) => [r.id, r]));
4806
- const asked = selected.selection.map((s) => byId.get(s.id)).filter((r) => r !== void 0 && r.evaluation === "judge");
4930
+ const asked = selected.selection.map((s) => byId.get(s.id)).filter((r) => r !== void 0 && r.evaluation === "judge").filter((r) => inputs.postActionCapture === true || !REQUIRES_POST_ACTION_CAPTURE.has(r.id));
4807
4931
  if (asked.length === 0) return "";
4808
4932
  const lines = asked.map((r) => `- ${r.id} (${r.severity}): ${r.text} Evidence must name: ${r.evidence}`);
4809
4933
  return "## Criteria \u2014 answer each one from the FRAME only\nRead these off the screenshot. Never infer them from the request, the styling profile or any direction text above.\n" + (inputs.frame !== void 0 ? `${criteriaFrameLine(inputs.frame)}
@@ -6343,7 +6467,7 @@ function parseCriteriaAnswers(raw) {
6343
6467
  function getDefaultVisualModel(provider) {
6344
6468
  switch (provider) {
6345
6469
  case "claude":
6346
- return "claude-haiku-4-5-20251001";
6470
+ return "claude-haiku-5-5";
6347
6471
  case "google":
6348
6472
  return "gemini-3-flash-preview";
6349
6473
  }