@contentful/experience-design-system-cli 2.41.1-dev-build-c9e39919.0 → 2.41.1-dev-build-3a724687.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/app.js CHANGED
@@ -197,7 +197,6 @@ __export(debug_store_exports, {
197
197
  currentDebugSessionDir: () => currentDebugSessionDir,
198
198
  currentSessionDir: () => currentSessionDir,
199
199
  finishDebugRun: () => finishDebugRun,
200
- setDebugRunProgress: () => setDebugRunProgress,
201
200
  startDebugRun: () => startDebugRun,
202
201
  startDebugSessionIn: () => startDebugSessionIn,
203
202
  startImportRun: () => startImportRun
@@ -293,15 +292,11 @@ function startDebugRun({
293
292
  const runId = generateRunId();
294
293
  const startedAt = Date.now();
295
294
  const redactedInputs = redact(inputs);
296
- const run = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
297
- pendingRun = run;
298
- void isDebugModeEnabled().then((enabled) => {
299
- if (!enabled && pendingRun === run) pendingRun = void 0;
295
+ isDebugModeEnabled().then((enabled) => {
296
+ if (!enabled) return;
297
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
300
298
  });
301
299
  }
302
- function setDebugRunProgress(outputs) {
303
- if (pendingRun) pendingRun.progress = outputs;
304
- }
305
300
  async function finishDebugRun({
306
301
  outputs,
307
302
  status,
@@ -310,10 +305,9 @@ async function finishDebugRun({
310
305
  const run = pendingRun;
311
306
  if (!run) return;
312
307
  pendingRun = void 0;
313
- if (!await isDebugModeEnabled()) return;
314
308
  const durationMs = Date.now() - run.startedAt;
315
309
  const log = {
316
- flow: logFolder(run.flow, run.step),
310
+ flow: run.flow,
317
311
  menuOption: run.menuOption,
318
312
  content: renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs })
319
313
  };
@@ -324,9 +318,6 @@ async function finishDebugRun({
324
318
  }
325
319
  await writeLog(root, log);
326
320
  }
327
- function logFolder(flow, step) {
328
- return flow.startsWith("import/") && /^\d+-/.test(step) ? `import/${step}` : flow;
329
- }
330
321
  async function writeLog(root, log) {
331
322
  const dir = join5(root, ...log.flow.split("/"));
332
323
  await mkdir2(dir, { recursive: true });
@@ -383,7 +374,7 @@ ${JSON.stringify(finish.outputs, null, 2)}
383
374
  `;
384
375
  }
385
376
  function handleCrash() {
386
- return finishDebugRun({ outputs: pendingRun?.progress ?? {}, status: "error", exitMethod: "crashed" });
377
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
387
378
  }
388
379
  var pendingRun, sessionDir, WAITING_LIMIT, waiting;
389
380
  var init_debug_store = __esm({
@@ -427,17 +418,11 @@ var init_debug_store = __esm({
427
418
  throw reason;
428
419
  });
429
420
  });
430
- for (const [signal, exitCode] of [
431
- ["SIGINT", 130],
432
- ["SIGTERM", 143],
433
- ["SIGHUP", 129]
434
- ]) {
435
- process.once(signal, () => {
436
- void handleCrash().finally(() => {
437
- process.exit(exitCode);
438
- });
421
+ process.once("SIGINT", () => {
422
+ void handleCrash().finally(() => {
423
+ process.exit(130);
439
424
  });
440
- }
425
+ });
441
426
  }
442
427
  });
443
428
 
@@ -1691,9 +1676,12 @@ var init_schema = __esm({
1691
1676
  $required: { type: "boolean" },
1692
1677
  $default: {},
1693
1678
  $values: { type: "array", items: { type: "string" } },
1694
- "$token.kind": { type: "string" },
1679
+ "$token.kind": { type: "string", minLength: 1 },
1695
1680
  "$token.allowed": { type: "array", items: { type: "string" } }
1696
1681
  },
1682
+ // The API rejects a token property that does not say which kind of token it takes.
1683
+ if: { type: "object", properties: { $type: { const: "token" } }, required: ["$type"] },
1684
+ then: { type: "object", required: ["$token.kind"] },
1697
1685
  additionalProperties: false
1698
1686
  },
1699
1687
  slot: {
@@ -2499,7 +2487,7 @@ var init_cache_keys = __esm({
2499
2487
  });
2500
2488
 
2501
2489
  // packages/experience-design-system-cli/app.tsx
2502
- import { useEffect as useEffect36, useState as useState39 } from "react";
2490
+ import { useEffect as useEffect31, useState as useState39 } from "react";
2503
2491
 
2504
2492
  // packages/experience-design-system-cli/src/tui/home/home.tsx
2505
2493
  import { useEffect as useEffect2, useState as useState2 } from "react";
@@ -3057,8 +3045,8 @@ function progressPercent(progress) {
3057
3045
  }
3058
3046
  function formatElapsed(totalSeconds) {
3059
3047
  const minutes = Math.floor(totalSeconds / 60);
3060
- const seconds2 = totalSeconds % 60;
3061
- return minutes > 0 ? `${minutes}m ${seconds2}s` : `${seconds2}s`;
3048
+ const seconds = totalSeconds % 60;
3049
+ return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
3062
3050
  }
3063
3051
 
3064
3052
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/theme.ts
@@ -3076,12 +3064,12 @@ var PROGRESS_THEME = extendTheme(defaultTheme, {
3076
3064
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/use-elapsed.ts
3077
3065
  import { useEffect as useEffect3, useState as useState3 } from "react";
3078
3066
  function useElapsed() {
3079
- const [seconds2, setSeconds] = useState3(0);
3067
+ const [seconds, setSeconds] = useState3(0);
3080
3068
  useEffect3(() => {
3081
3069
  const timer = setInterval(() => setSeconds((current) => current + 1), 1e3);
3082
3070
  return () => clearInterval(timer);
3083
3071
  }, []);
3084
- return formatElapsed(seconds2);
3072
+ return formatElapsed(seconds);
3085
3073
  }
3086
3074
 
3087
3075
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx
@@ -15268,8 +15256,8 @@ function retryAfterMs(response) {
15268
15256
  const value = response.headers?.get("retry-after")?.trim();
15269
15257
  if (!value)
15270
15258
  return void 0;
15271
- const seconds2 = Number(value);
15272
- const delayMs = Number.isFinite(seconds2) ? seconds2 * 1e3 : Date.parse(value) - Date.now();
15259
+ const seconds = Number(value);
15260
+ const delayMs = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(value) - Date.now();
15273
15261
  if (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > MAX_RETRY_AFTER_MS)
15274
15262
  return void 0;
15275
15263
  return Math.round(delayMs);
@@ -17417,10 +17405,10 @@ async function readCandidateFiles(components, extraFiles = []) {
17417
17405
  async function selectCompositionPromptFiles(components, sourceFiles) {
17418
17406
  const allFiles = await readCandidateFiles(components, sourceFiles);
17419
17407
  const selectedCandidates = selectCandidateFiles(allFiles).map((c2) => ({ path: c2.path, content: c2.content }));
17420
- const capped3 = capCandidatesToPromptBudget(selectedCandidates);
17421
- const promptFiles = capped3.kept;
17408
+ const capped = capCandidatesToPromptBudget(selectedCandidates);
17409
+ const promptFiles = capped.kept;
17422
17410
  const runtimeFiles = allFiles.map((c2) => ({ path: c2.path, content: c2.content }));
17423
- const droppedWarning = capped3.dropped.length > 0 ? `composition \u2014 ${capped3.dropped.length} candidate file(s) omitted from the agent prompt to fit the context budget; resolution runs on the ${promptFiles.length} highest-value files.` : void 0;
17411
+ const droppedWarning = capped.dropped.length > 0 ? `composition \u2014 ${capped.dropped.length} candidate file(s) omitted from the agent prompt to fit the context budget; resolution runs on the ${promptFiles.length} highest-value files.` : void 0;
17424
17412
  return { promptFiles, runtimeFiles, droppedWarning };
17425
17413
  }
17426
17414
 
@@ -18172,9 +18160,8 @@ function PathValidationScreen({
18172
18160
  }
18173
18161
 
18174
18162
  // packages/experience-design-system-cli/src/tui/import/steps/04-credentials/screen.tsx
18175
- import { useEffect as useEffect8, useRef as useRef5, useState as useState9 } from "react";
18163
+ import { useRef as useRef5, useState as useState9 } from "react";
18176
18164
  import { Box as Box14, Text as Text14, useInput as useInput11 } from "ink";
18177
- init_debug_store();
18178
18165
 
18179
18166
  // packages/experience-design-system-cli/src/tui/shared/components/FieldForm.tsx
18180
18167
  import { useState as useState8 } from "react";
@@ -18351,39 +18338,6 @@ function FieldForm({
18351
18338
  ] });
18352
18339
  }
18353
18340
 
18354
- // packages/experience-design-system-cli/src/tui/shared/debug-trail.ts
18355
- init_config();
18356
- import { existsSync as existsSync9 } from "node:fs";
18357
- function diffSnapshots(before, after) {
18358
- const names = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])];
18359
- const changed_fields = names.filter((name) => before[name] !== after[name]);
18360
- return { changed: changed_fields.length > 0, changed_fields };
18361
- }
18362
- var DEFAULT_TRAIL_LIMIT = 30;
18363
- function createTrail(limit = DEFAULT_TRAIL_LIMIT) {
18364
- const actions = [];
18365
- return {
18366
- record(action) {
18367
- actions.push(action);
18368
- if (actions.length > limit) actions.shift();
18369
- },
18370
- entries: () => [...actions]
18371
- };
18372
- }
18373
- var MIN_SECRET_LENGTH = 6;
18374
- function scrubError(error, secrets) {
18375
- let message = error instanceof Error ? error.message : String(error);
18376
- for (const secret of secrets) {
18377
- if (secret.length < MIN_SECRET_LENGTH) continue;
18378
- for (const form of /* @__PURE__ */ new Set([secret, encodeURIComponent(secret)])) message = message.split(form).join("[redacted]");
18379
- }
18380
- return message;
18381
- }
18382
- function describeSettingsFile() {
18383
- const path5 = configFilePath();
18384
- return { path: path5, eds_home_set: Boolean(process.env["EDS_HOME"]), exists: existsSync9(path5) };
18385
- }
18386
-
18387
18341
  // packages/experience-design-system-cli/src/tui/import/steps/04-credentials/logic.ts
18388
18342
  var FIELDS = ["spaceId", "environmentId", "cmaToken", "host"];
18389
18343
  function credentialsPurpose(tokensOnly) {
@@ -18398,36 +18352,12 @@ function normalize(values) {
18398
18352
  host: toConfiguredHost2(values.host) ?? DEFAULT_CONFIGURED_HOST
18399
18353
  };
18400
18354
  }
18401
- function missingFields(values) {
18402
- return ["spaceId", "environmentId", "cmaToken"].filter((field) => values[field] === "");
18355
+ function missingField(values) {
18356
+ return values.spaceId === "" || values.environmentId === "" || values.cmaToken === "";
18403
18357
  }
18404
18358
  function isUnchanged(current, initial) {
18405
18359
  return FIELDS.every((field) => current[field] === initial[field]);
18406
18360
  }
18407
- function rejectedAttempt(reason, credentials) {
18408
- return { host: credentials.host, reason: scrubError(reason, [credentials.cmaToken]) };
18409
- }
18410
- function credentialsLog(credentials) {
18411
- return {
18412
- space_id: credentials.spaceId,
18413
- environment_id: credentials.environmentId,
18414
- host: credentials.host,
18415
- cma_token: credentials.cmaToken
18416
- };
18417
- }
18418
- function credentialsOutputs({
18419
- outcome,
18420
- credentials,
18421
- initial,
18422
- attempts
18423
- }) {
18424
- return {
18425
- outcome,
18426
- ...credentialsLog(credentials),
18427
- changed_fields: diffSnapshots(initial, credentials).changed_fields,
18428
- rejected_attempts: attempts
18429
- };
18430
- }
18431
18361
 
18432
18362
  // packages/experience-design-system-cli/src/tui/user-agent.ts
18433
18363
  init_version();
@@ -18475,9 +18405,7 @@ var MENU = [
18475
18405
  { choice: "continue", label: "Continue", description: "Check the credentials and go on" },
18476
18406
  { choice: "edit", label: "Edit", description: "Change the credentials" }
18477
18407
  ];
18478
- var MAX_LOGGED_ATTEMPTS2 = 10;
18479
18408
  function CredentialsScreen({
18480
- mode,
18481
18409
  onDone,
18482
18410
  onBack,
18483
18411
  initial = {},
@@ -18500,64 +18428,17 @@ function CredentialsScreen({
18500
18428
  const [focus, setFocus] = useState9(0);
18501
18429
  const [active, setActive] = useState9(0);
18502
18430
  const [beforeEdit, setBeforeEdit] = useState9(initialValues);
18503
- const visit = useRef5({ attempts: [], lastReason: "" }).current;
18504
- useEffect8(() => {
18505
- startDebugRun({
18506
- flow: "import/credentials",
18507
- step: "04-credentials",
18508
- menuOption: "Credentials",
18509
- inputs: { import_mode: mode, prefilled, ...credentialsLog(initialValues) }
18510
- });
18511
- }, []);
18512
- const reject = (attempt, text) => {
18513
- if (visit.attempts.length < MAX_LOGGED_ATTEMPTS2) visit.attempts.push(attempt);
18514
- visit.lastReason = attempt.reason;
18515
- setNotice({ kind: "error", text });
18516
- };
18517
- const leave = () => {
18518
- void finishDebugRun({
18519
- outputs: {
18520
- ...credentialsOutputs({
18521
- outcome: "back",
18522
- credentials: normalize(values),
18523
- initial: initialValues,
18524
- attempts: visit.attempts
18525
- }),
18526
- ...notice ? { error: visit.lastReason } : {}
18527
- },
18528
- status: notice ? "error" : "success",
18529
- exitMethod: "discarded"
18530
- });
18531
- onBack();
18532
- };
18533
18431
  const submit = async () => {
18534
18432
  const credentials = normalize(values);
18535
- const missing = missingFields(credentials);
18536
- if (missing.length > 0) {
18537
- reject(
18538
- rejectedAttempt(`Missing required fields: ${missing.join(", ")}`, credentials),
18539
- "Space ID, environment and CMA token are all required."
18540
- );
18433
+ if (missingField(credentials)) {
18434
+ setNotice({ kind: "error", text: "Space ID, environment and CMA token are all required." });
18541
18435
  return;
18542
18436
  }
18543
18437
  setValidating(true);
18544
18438
  const result = await validate3(credentials);
18545
18439
  setValidating(false);
18546
- if (!result.ok) {
18547
- reject(rejectedAttempt(result.error, credentials), result.error);
18548
- return;
18549
- }
18550
- void finishDebugRun({
18551
- outputs: credentialsOutputs({
18552
- outcome: "validated",
18553
- credentials,
18554
- initial: initialValues,
18555
- attempts: visit.attempts
18556
- }),
18557
- status: "success",
18558
- exitMethod: "saved"
18559
- });
18560
- onDone({ skipped: false, credentials });
18440
+ if (result.ok) onDone({ skipped: false, credentials });
18441
+ else setNotice({ kind: "error", text: result.error });
18561
18442
  };
18562
18443
  const choose = (choice) => {
18563
18444
  if (choice === "continue") void submit();
@@ -18566,7 +18447,7 @@ function CredentialsScreen({
18566
18447
  setBeforeEdit(values);
18567
18448
  setActive(0);
18568
18449
  setEditing(true);
18569
- } else leave();
18450
+ } else onBack();
18570
18451
  };
18571
18452
  const stopEditing = () => {
18572
18453
  setEditing(false);
@@ -18576,7 +18457,7 @@ function CredentialsScreen({
18576
18457
  if (validating) return;
18577
18458
  if (editing) {
18578
18459
  if (key.escape) {
18579
- if (!prefilled) leave();
18460
+ if (!prefilled) onBack();
18580
18461
  else {
18581
18462
  setValues(beforeEdit);
18582
18463
  setNotice(null);
@@ -18684,47 +18565,6 @@ function CredentialsScreen({
18684
18565
  }
18685
18566
 
18686
18567
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/logic.ts
18687
- function extractionLogInputs(input) {
18688
- const { credentials } = input;
18689
- return {
18690
- project_path: input.projectPath,
18691
- out_dir: input.outDir ?? "",
18692
- files_to_scan: input.filePaths.length,
18693
- raw_tokens_path: input.rawTokensPath,
18694
- agent: input.agent,
18695
- agent_model: input.agentModel ?? "",
18696
- prompt_overrides: input.promptOverrides,
18697
- cache: !input.noCache,
18698
- has_credentials: credentials !== null,
18699
- space_id: credentials?.spaceId ?? "",
18700
- environment_id: credentials?.environmentId ?? "",
18701
- host: credentials?.host ?? "",
18702
- cma_token: credentials?.cmaToken ?? ""
18703
- };
18704
- }
18705
- function extractionLogOutputs(result, progress, cmaToken) {
18706
- const last = progress ? { final_progress: progress } : {};
18707
- if (!result.ok) {
18708
- return {
18709
- outputs: { result: "failed", failed_step: result.step, error: scrubError(result.message, [cmaToken]), ...last },
18710
- status: "error"
18711
- };
18712
- }
18713
- const { extraction } = result;
18714
- return {
18715
- outputs: {
18716
- result: "done",
18717
- session_id: extraction.sessionId,
18718
- out_dir: extraction.outDir,
18719
- tokens_path: extraction.tokensPath,
18720
- token_count: extraction.tokenCount,
18721
- existing_entities_status: extraction.existingEntitiesStatus,
18722
- composition_phase: extraction.compositionPhase,
18723
- ...last
18724
- },
18725
- status: "success"
18726
- };
18727
- }
18728
18568
  function initialProgress(input) {
18729
18569
  return {
18730
18570
  scan: null,
@@ -18819,9 +18659,8 @@ function ExtractionScreen({ progress, agent }) {
18819
18659
  }
18820
18660
 
18821
18661
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-review/screen.tsx
18822
- import { useEffect as useEffect9, useMemo as useMemo2, useState as useState10 } from "react";
18662
+ import { useMemo as useMemo2, useState as useState10 } from "react";
18823
18663
  import { Box as Box15, Text as Text15, useInput as useInput12 } from "ink";
18824
- init_debug_store();
18825
18664
 
18826
18665
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-review/load.ts
18827
18666
  import { readFileSync as readFileSync9 } from "node:fs";
@@ -18885,31 +18724,12 @@ function TokenReviewScreen({ tokensPath, onContinue, onQuit }) {
18885
18724
  const rows = loaded.ok ? loaded.rows : [];
18886
18725
  const columns = useTerminalWidth();
18887
18726
  const [selected, setSelected] = useState10(0);
18888
- useEffect9(() => {
18889
- startDebugRun({
18890
- flow: "import/token-review",
18891
- step: "05-token-review",
18892
- menuOption: "Token review",
18893
- inputs: { import_mode: "tokens", tokens_path: tokensPath }
18894
- });
18895
- }, []);
18896
- const finish = (outcome) => {
18897
- void finishDebugRun({
18898
- outputs: { outcome, ...loaded.ok ? { tokens: rows.length } : { load_error: loaded.message } },
18899
- status: loaded.ok ? "success" : "error",
18900
- exitMethod: outcome === "continued" ? "saved" : "discarded"
18901
- });
18902
- };
18903
18727
  const move = (to) => setSelected(Math.max(0, Math.min(to, rows.length - 1)));
18904
18728
  const { start, end } = computeColumnWindow(rows.length, selected, VISIBLE_ROWS);
18905
18729
  useInput12((_input, key) => {
18906
- if (key.return) {
18907
- finish("continued");
18908
- onContinue();
18909
- } else if (key.escape) {
18910
- finish("back");
18911
- onQuit();
18912
- } else if (key.upArrow) move(selected - 1);
18730
+ if (key.return) onContinue();
18731
+ else if (key.escape) onQuit();
18732
+ else if (key.upArrow) move(selected - 1);
18913
18733
  else if (key.downArrow) move(selected + 1);
18914
18734
  else if (key.pageUp) move(selected - VISIBLE_ROWS);
18915
18735
  else if (key.pageDown) move(selected + VISIBLE_ROWS);
@@ -18973,15 +18793,14 @@ function TokenReviewScreen({ tokensPath, onContinue, onQuit }) {
18973
18793
  init_config();
18974
18794
 
18975
18795
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
18976
- init_debug_store();
18977
- import { useEffect as useEffect10, useRef as useRef6, useState as useState11 } from "react";
18796
+ import { useEffect as useEffect8, useRef as useRef6, useState as useState11 } from "react";
18978
18797
 
18979
18798
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run.ts
18980
18799
  import { mkdir as mkdir8 } from "node:fs/promises";
18981
18800
  import { join as join20, resolve as resolve24 } from "node:path";
18982
18801
 
18983
18802
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/find-skill-path.ts
18984
- import { existsSync as existsSync10 } from "node:fs";
18803
+ import { existsSync as existsSync9 } from "node:fs";
18985
18804
  import { dirname as dirname16, join as join19, resolve as resolve22 } from "node:path";
18986
18805
  import { fileURLToPath as fileURLToPath4 } from "node:url";
18987
18806
  function findSkillPath(fileName) {
@@ -18989,7 +18808,7 @@ function findSkillPath(fileName) {
18989
18808
  let dir = thisDir;
18990
18809
  for (; ; ) {
18991
18810
  const candidate = join19(dir, "skills", fileName);
18992
- if (existsSync10(candidate)) return candidate;
18811
+ if (existsSync9(candidate)) return candidate;
18993
18812
  const parent = resolve22(dir, "..");
18994
18813
  if (parent === dir) {
18995
18814
  throw new Error(`skill file not found (looked for skills/${fileName} from ${thisDir})`);
@@ -19231,7 +19050,7 @@ async function resolveSelectionPrompt(overrides) {
19231
19050
  function useExtraction(input) {
19232
19051
  const [state2, setState] = useState11();
19233
19052
  const current = useRef6();
19234
- useEffect10(() => {
19053
+ useEffect8(() => {
19235
19054
  current.current = input;
19236
19055
  if (!input) {
19237
19056
  setState(void 0);
@@ -19244,23 +19063,10 @@ function useExtraction(input) {
19244
19063
  hasRawTokens: input.rawTokensPath !== ""
19245
19064
  })
19246
19065
  });
19247
- let lastProgress;
19248
- startDebugRun({
19249
- flow: "import/extraction",
19250
- step: "06-extraction",
19251
- menuOption: "Extraction",
19252
- inputs: extractionLogInputs(input)
19253
- });
19254
19066
  void runExtraction(input, (progress) => {
19255
- lastProgress = progress;
19256
19067
  if (current.current === input) setState({ status: "running", progress });
19257
19068
  }).then((result) => {
19258
- if (current.current !== input) return;
19259
- void finishDebugRun({
19260
- ...extractionLogOutputs(result, lastProgress, input.credentials?.cmaToken ?? ""),
19261
- exitMethod: result.ok ? "saved" : "discarded"
19262
- });
19263
- setState({ status: "done", result });
19069
+ if (current.current === input) setState({ status: "done", result });
19264
19070
  });
19265
19071
  return () => {
19266
19072
  if (current.current === input) current.current = void 0;
@@ -19270,7 +19076,7 @@ function useExtraction(input) {
19270
19076
  }
19271
19077
 
19272
19078
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-tokens-only.ts
19273
- import { useEffect as useEffect11, useRef as useRef7, useState as useState12 } from "react";
19079
+ import { useEffect as useEffect9, useRef as useRef7, useState as useState12 } from "react";
19274
19080
 
19275
19081
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run-tokens-only.ts
19276
19082
  var TOKENS_SKILL_PATH2 = findSkillPath("generate-tokens.md");
@@ -19305,7 +19111,7 @@ async function runTokensOnly(input, deps = realDeps2) {
19305
19111
  function useTokensOnly(input) {
19306
19112
  const [state2, setState] = useState12();
19307
19113
  const current = useRef7();
19308
- useEffect11(() => {
19114
+ useEffect9(() => {
19309
19115
  current.current = input;
19310
19116
  if (!input) {
19311
19117
  setState(void 0);
@@ -19323,37 +19129,9 @@ function useTokensOnly(input) {
19323
19129
  }
19324
19130
 
19325
19131
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/screen.tsx
19326
- init_debug_store();
19327
- import { useEffect as useEffect14, useMemo as useMemo4 } from "react";
19132
+ import { useMemo as useMemo4 } from "react";
19328
19133
  import { Box as Box25, Text as Text26 } from "ink";
19329
19134
 
19330
- // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/log.ts
19331
- var MAX_NAMES = 20;
19332
- var capped = (names) => {
19333
- const unique = [...new Set(names)];
19334
- return { count: unique.length, names: unique.slice(0, MAX_NAMES) };
19335
- };
19336
- function scopeGateLogInputs(components, tokenCount) {
19337
- const ai = { accepted: 0, rejected: 0, failed: 0, none: 0 };
19338
- for (const component of components) ai[component.aiDecision ?? "none"] += 1;
19339
- return {
19340
- components_found: components.length,
19341
- ai_suggestions: ai,
19342
- needs_review: components.filter((component) => component.needsReview === true).length,
19343
- tokens: tokenCount
19344
- };
19345
- }
19346
- function scopeGateLogOutputs(components, decisions) {
19347
- const suggested = new Map(components.map((component) => [component.name, component.aiDecision]));
19348
- return {
19349
- outcome: "continued",
19350
- accepted: new Set(decisions.accepted).size,
19351
- rejected: new Set(decisions.rejected).size,
19352
- accepted_although_ai_rejected: capped(decisions.accepted.filter((name) => suggested.get(name) === "rejected")),
19353
- not_accepted_although_ai_accepted: capped(decisions.rejected.filter((name) => suggested.get(name) === "accepted"))
19354
- };
19355
- }
19356
-
19357
19135
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/tokens-column.tsx
19358
19136
  import { Box as Box17, Text as Text17 } from "ink";
19359
19137
  import figures2 from "figures";
@@ -20537,7 +20315,7 @@ function useImmediateInput(handler, enabled = true) {
20537
20315
 
20538
20316
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.ts
20539
20317
  import { useStdout as useStdout2 } from "ink";
20540
- import { useEffect as useEffect12, useState as useState13 } from "react";
20318
+ import { useEffect as useEffect10, useState as useState13 } from "react";
20541
20319
  function readTerminalSize(stdout) {
20542
20320
  return {
20543
20321
  columns: stdout?.columns ?? 80,
@@ -20547,7 +20325,7 @@ function readTerminalSize(stdout) {
20547
20325
  function useTerminalSize() {
20548
20326
  const { stdout } = useStdout2();
20549
20327
  const [size, setSize] = useState13(() => readTerminalSize(stdout));
20550
- useEffect12(() => {
20328
+ useEffect10(() => {
20551
20329
  const updateSize = () => setSize(readTerminalSize(stdout));
20552
20330
  stdout?.on("resize", updateSize);
20553
20331
  updateSize();
@@ -20730,7 +20508,7 @@ function createSidebarViewsHelpSection(includeBreaking) {
20730
20508
  }
20731
20509
 
20732
20510
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
20733
- import { useEffect as useEffect13, useMemo as useMemo3, useRef as useRef9, useState as useState16 } from "react";
20511
+ import { useEffect as useEffect11, useMemo as useMemo3, useRef as useRef9, useState as useState16 } from "react";
20734
20512
 
20735
20513
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/columns.ts
20736
20514
  var TWO_COLUMN_MIN_WIDTH = 100;
@@ -21467,7 +21245,7 @@ function useScopeGate({ components, tokenCount, tokensWidth, onConfirm, onQuit }
21467
21245
  return seed;
21468
21246
  });
21469
21247
  const seededGroupsRef = useRef9(closures.size > 0 || cycleParticipants.size > 0);
21470
- useEffect13(() => {
21248
+ useEffect11(() => {
21471
21249
  if (seededGroupsRef.current) return;
21472
21250
  if (closures.size === 0 && cycleParticipants.size === 0) return;
21473
21251
  seededGroupsRef.current = true;
@@ -21558,7 +21336,7 @@ function useScopeGate({ components, tokenCount, tokensWidth, onConfirm, onQuit }
21558
21336
  entryCount: 0
21559
21337
  });
21560
21338
  const panelLayout = useMemo3(() => computePanelLayout(visibleCount), [visibleCount]);
21561
- useEffect13(() => {
21339
+ useEffect11(() => {
21562
21340
  setNav((prev) => {
21563
21341
  const maxIdx = Math.max(0, visibleRows.length - 1);
21564
21342
  const nextCursor = Math.min(prev.cursor, maxIdx);
@@ -21919,55 +21697,23 @@ var HELP_SECTIONS = [
21919
21697
  }
21920
21698
  ];
21921
21699
  function ScopeGateScreen(props) {
21922
- if (props.components.length === 0) return /* @__PURE__ */ jsx29(NoComponents, {});
21700
+ if (props.components.length === 0) {
21701
+ return /* @__PURE__ */ jsx29(Box25, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx29(Text26, { color: PALETTE.error, children: "Error: no components found for this session \u2014 please re-run analyze extract." }) });
21702
+ }
21923
21703
  return /* @__PURE__ */ jsx29(ScopeGateView, { ...props });
21924
21704
  }
21925
- function NoComponents() {
21926
- useEffect14(() => {
21927
- startDebugRun({
21928
- flow: "import/scope-gate",
21929
- step: "07-scope-gate",
21930
- menuOption: "Scope gate",
21931
- inputs: scopeGateLogInputs([], 0)
21932
- });
21933
- void finishDebugRun({
21934
- outputs: { outcome: "nothing to decide", error: "No components were found for this session." },
21935
- status: "error",
21936
- exitMethod: "discarded"
21937
- });
21938
- }, []);
21939
- return /* @__PURE__ */ jsx29(Box25, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx29(Text26, { color: PALETTE.error, children: "Error: no components found for this session \u2014 please re-run analyze extract." }) });
21940
- }
21941
21705
  function ScopeGateView({ components, tokensPath, onConfirm, onQuit }) {
21942
21706
  const tokens = useMemo4(() => {
21943
21707
  const loaded = tokensPath ? loadTokenRows(tokensPath) : void 0;
21944
21708
  return loaded?.ok ? loaded.rows : [];
21945
21709
  }, [tokensPath]);
21946
21710
  const longest = useMemo4(() => longestEntries(tokens), [tokens]);
21947
- useEffect14(() => {
21948
- startDebugRun({
21949
- flow: "import/scope-gate",
21950
- step: "07-scope-gate",
21951
- menuOption: "Scope gate",
21952
- inputs: scopeGateLogInputs(components, tokens.length)
21953
- });
21954
- }, []);
21955
21711
  const gate = useScopeGate({
21956
21712
  components,
21957
21713
  tokenCount: tokens.length,
21958
21714
  tokensWidth: longest.path + longest.value + 10,
21959
- onConfirm: (decisions) => {
21960
- void finishDebugRun({
21961
- outputs: scopeGateLogOutputs(components, decisions),
21962
- status: "success",
21963
- exitMethod: "saved"
21964
- });
21965
- onConfirm(decisions);
21966
- },
21967
- onQuit: () => {
21968
- void finishDebugRun({ outputs: { outcome: "quit" }, status: "success", exitMethod: "discarded" });
21969
- onQuit();
21970
- }
21715
+ onConfirm,
21716
+ onQuit
21971
21717
  });
21972
21718
  const { search, graph, columnPlan, panelLayout, counters } = gate;
21973
21719
  if (gate.showHelp) {
@@ -22065,8 +21811,7 @@ function ScopeGateView({ components, tokensPath, onConfirm, onQuit }) {
22065
21811
  }
22066
21812
 
22067
21813
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.ts
22068
- init_debug_store();
22069
- import { useEffect as useEffect15, useMemo as useMemo5, useRef as useRef10, useState as useState17 } from "react";
21814
+ import { useEffect as useEffect12, useMemo as useMemo5, useRef as useRef10, useState as useState17 } from "react";
22070
21815
 
22071
21816
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts
22072
21817
  async function checkGenerationCache(input) {
@@ -22115,21 +21860,7 @@ function useScopeGateFlow(input, deps = realDeps3) {
22115
21860
  const loaded = useMemo5(() => sessionId ? deps.load(sessionId) : void 0, [sessionId]);
22116
21861
  const cacheCheck = useRef10(void 0);
22117
21862
  const [confirmed, setConfirmed] = useState17();
22118
- useEffect15(() => {
22119
- if (!sessionId || !loaded || loaded.ok) return;
22120
- startDebugRun({
22121
- flow: "import/scope-gate",
22122
- step: "07-scope-gate",
22123
- menuOption: "Scope gate",
22124
- inputs: { session_id: sessionId }
22125
- });
22126
- void finishDebugRun({
22127
- outputs: { outcome: "could not load the components", error: loaded.message },
22128
- status: "error",
22129
- exitMethod: "discarded"
22130
- });
22131
- }, [sessionId, loaded]);
22132
- useEffect15(() => {
21863
+ useEffect12(() => {
22133
21864
  if (!input || !loaded?.ok || cacheCheck.current) return;
22134
21865
  cacheCheck.current = deps.checkCache(input.cache);
22135
21866
  }, [input, loaded]);
@@ -22141,41 +21872,6 @@ function useScopeGateFlow(input, deps = realDeps3) {
22141
21872
  }
22142
21873
 
22143
21874
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/logic.ts
22144
- function generationLogInputs(input) {
22145
- return {
22146
- session_id: input.sessionId,
22147
- accepted: input.decisions.accepted.length,
22148
- rejected: input.decisions.rejected.length,
22149
- tokens_path: input.tokensPath,
22150
- token_session_id: input.tokenSessionId,
22151
- existing_entities_path: input.existingEntitiesPath,
22152
- agent: input.agent,
22153
- agent_model: input.agentModel ?? "",
22154
- prompt_overrides: input.promptOverrides,
22155
- generate_prompt_path: input.generatePromptPath ?? "",
22156
- cache: !input.noCache,
22157
- has_tokens: input.hasTokens
22158
- };
22159
- }
22160
- function generationLogOutputs(result, progress) {
22161
- const last = progress ? { final_progress: progress } : {};
22162
- if (!result.ok) {
22163
- return { outputs: { result: "failed", failed_step: result.step, error: result.message, ...last }, status: "error" };
22164
- }
22165
- const { generation } = result;
22166
- return {
22167
- outputs: generation.route === "review" ? {
22168
- result: "done",
22169
- route: generation.route,
22170
- session_id: generation.sessionId,
22171
- accepted: generation.acceptedCount,
22172
- generated: generation.generatedCount,
22173
- map_tokens_eligible: generation.mapTokensEligible,
22174
- ...last
22175
- } : { result: "done", route: generation.route, accepted: generation.acceptedCount, ...last },
22176
- status: "success"
22177
- };
22178
- }
22179
21875
  function initialProgress2() {
22180
21876
  return { components: null, mapTokens: "idle", mapTokensEligible: null };
22181
21877
  }
@@ -22231,8 +21927,7 @@ function GenerationScreen({
22231
21927
  }
22232
21928
 
22233
21929
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts
22234
- init_debug_store();
22235
- import { useEffect as useEffect16, useRef as useRef11, useState as useState18 } from "react";
21930
+ import { useEffect as useEffect13, useRef as useRef11, useState as useState18 } from "react";
22236
21931
 
22237
21932
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
22238
21933
  import { resolve as resolve25 } from "node:path";
@@ -22398,30 +22093,17 @@ function applyProgressEvent2(event, previous, total) {
22398
22093
  function useGeneration(input) {
22399
22094
  const [state2, setState] = useState18();
22400
22095
  const current = useRef11();
22401
- useEffect16(() => {
22096
+ useEffect13(() => {
22402
22097
  current.current = input;
22403
22098
  if (!input) {
22404
22099
  setState(void 0);
22405
22100
  return;
22406
22101
  }
22407
22102
  setState({ status: "running", progress: initialProgress2() });
22408
- let lastProgress;
22409
- startDebugRun({
22410
- flow: "import/generation",
22411
- step: "08-generation",
22412
- menuOption: "Generation",
22413
- inputs: generationLogInputs(input)
22414
- });
22415
22103
  void runGeneration(input, (progress) => {
22416
- lastProgress = progress;
22417
22104
  if (current.current === input) setState({ status: "running", progress });
22418
22105
  }).then((result) => {
22419
- if (current.current !== input) return;
22420
- void finishDebugRun({
22421
- ...generationLogOutputs(result, lastProgress),
22422
- exitMethod: result.ok ? "saved" : "discarded"
22423
- });
22424
- setState({ status: "done", result });
22106
+ if (current.current === input) setState({ status: "done", result });
22425
22107
  });
22426
22108
  return () => {
22427
22109
  if (current.current === input) current.current = void 0;
@@ -22536,9 +22218,12 @@ var cdfJsonSchema2 = {
22536
22218
  $required: { type: "boolean" },
22537
22219
  $default: {},
22538
22220
  $values: { type: "array", items: { type: "string" } },
22539
- "$token.kind": { type: "string" },
22221
+ "$token.kind": { type: "string", minLength: 1 },
22540
22222
  "$token.allowed": { type: "array", items: { type: "string" } }
22541
22223
  },
22224
+ // The API rejects a token property that does not say which kind of token it takes.
22225
+ if: { type: "object", properties: { $type: { const: "token" } }, required: ["$type"] },
22226
+ then: { type: "object", required: ["$token.kind"] },
22542
22227
  additionalProperties: false
22543
22228
  },
22544
22229
  slot: {
@@ -22892,7 +22577,7 @@ function PreviewValidationErrorScreen({
22892
22577
  }
22893
22578
 
22894
22579
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/generate-review-step.tsx
22895
- import { useCallback as useCallback5, useEffect as useEffect24, useMemo as useMemo6, useRef as useRef17, useState as useState26 } from "react";
22580
+ import { useCallback as useCallback5, useEffect as useEffect20, useMemo as useMemo6, useRef as useRef16, useState as useState26 } from "react";
22896
22581
  import figures8 from "figures";
22897
22582
 
22898
22583
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/review-json-panel.ts
@@ -23153,7 +22838,7 @@ function enumerateCycleBreaks(cycle, components) {
23153
22838
  import { Box as Box32, Text as Text34 } from "ink";
23154
22839
 
23155
22840
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/components/FieldEditor.tsx
23156
- import React13, { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useState as useState19 } from "react";
22841
+ import React13, { useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useState as useState19 } from "react";
23157
22842
  import figures6 from "figures";
23158
22843
  import { Box as Box26, measureElement, Text as Text27 } from "ink";
23159
22844
 
@@ -24711,7 +24396,7 @@ function FieldEditor({
24711
24396
  }
24712
24397
  return Math.max(start + 1, end2);
24713
24398
  };
24714
- useEffect17(() => {
24399
+ useEffect14(() => {
24715
24400
  if (focusLevel === "field" || selectedRowIdx < 0) return;
24716
24401
  setListScrollStart((previous) => {
24717
24402
  if (initialFocusTarget && !initialFocusScrollApplied.current) {
@@ -25783,7 +25468,7 @@ function finalizeReviewSession(extractSessionId, components) {
25783
25468
  }
25784
25469
 
25785
25470
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-session.ts
25786
- import { useCallback as useCallback2, useEffect as useEffect19, useRef as useRef13, useState as useState21 } from "react";
25471
+ import { useCallback as useCallback2, useEffect as useEffect16, useRef as useRef13, useState as useState21 } from "react";
25787
25472
 
25788
25473
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/history.ts
25789
25474
  var DEFAULT_MAX_DEPTH = 50;
@@ -25839,7 +25524,7 @@ function createHistoryStack(seed, maxDepth = DEFAULT_MAX_DEPTH) {
25839
25524
  }
25840
25525
 
25841
25526
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-finalize-preview.ts
25842
- import { useEffect as useEffect18, useRef as useRef12, useState as useState20 } from "react";
25527
+ import { useEffect as useEffect15, useRef as useRef12, useState as useState20 } from "react";
25843
25528
 
25844
25529
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/run-live-preview.ts
25845
25530
  var TimeoutError = class extends Error {
@@ -25999,7 +25684,7 @@ function useFinalizePreview(opts) {
25999
25684
  const [scrollOffset, setScrollOffset] = useState20(0);
26000
25685
  const generationRef = useRef12(0);
26001
25686
  const acceptedKey = [...acceptedKeys].sort().join("\0");
26002
- useEffect18(() => {
25687
+ useEffect15(() => {
26003
25688
  if (!open) {
26004
25689
  setStatus("idle");
26005
25690
  setRemoved([]);
@@ -26062,7 +25747,7 @@ function useReviewSession({
26062
25747
  }));
26063
25748
  return { result, catalog };
26064
25749
  }, [loadSession, tokensPath]);
26065
- useEffect19(() => {
25750
+ useEffect16(() => {
26066
25751
  let disposed = false;
26067
25752
  void (async () => {
26068
25753
  try {
@@ -26115,7 +25800,7 @@ function useReviewSession({
26115
25800
  function useReviewMetadata({ components, selectedIdx, extractSessionId }) {
26116
25801
  const [reviewMetadata, setReviewMetadata] = useState21(null);
26117
25802
  const [componentRationale, setComponentRationale] = useState21(null);
26118
- useEffect19(() => {
25803
+ useEffect16(() => {
26119
25804
  const current = components[selectedIdx];
26120
25805
  if (!current) {
26121
25806
  setReviewMetadata(null);
@@ -26144,16 +25829,10 @@ function useReviewMetadata({ components, selectedIdx, extractSessionId }) {
26144
25829
  }, [components, extractSessionId, selectedIdx]);
26145
25830
  return { reviewMetadata, componentRationale };
26146
25831
  }
26147
- function useReviewHistory({
26148
- loading,
26149
- components,
26150
- createSnapshot,
26151
- applySnapshot,
26152
- onAction
26153
- }) {
25832
+ function useReviewHistory({ loading, components, createSnapshot, applySnapshot }) {
26154
25833
  const historyRef = useRef13(null);
26155
25834
  const historySeededRef = useRef13(false);
26156
- useEffect19(() => {
25835
+ useEffect16(() => {
26157
25836
  if (loading || historySeededRef.current) return;
26158
25837
  historySeededRef.current = true;
26159
25838
  historyRef.current = createHistoryStack(createSnapshot(components));
@@ -26161,19 +25840,14 @@ function useReviewHistory({
26161
25840
  const pushHistorySnapshot = (entries, label) => {
26162
25841
  if (!historyRef.current) return;
26163
25842
  historyRef.current.push(createSnapshot(entries), label);
26164
- onAction?.(label);
26165
25843
  };
26166
25844
  const handleUndo = () => {
26167
25845
  const snapshot = historyRef.current?.undo();
26168
- if (!snapshot) return;
26169
- applySnapshot(snapshot);
26170
- onAction?.("undo");
25846
+ if (snapshot) applySnapshot(snapshot);
26171
25847
  };
26172
25848
  const handleRedo = () => {
26173
25849
  const snapshot = historyRef.current?.redo();
26174
- if (!snapshot) return;
26175
- applySnapshot(snapshot);
26176
- onAction?.("redo");
25850
+ if (snapshot) applySnapshot(snapshot);
26177
25851
  };
26178
25852
  const resetHistory = (snapshot) => {
26179
25853
  historyRef.current?.reset(snapshot);
@@ -26209,7 +25883,7 @@ function useReviewFinalize({
26209
25883
  }
26210
25884
 
26211
25885
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-editor.ts
26212
- import { useEffect as useEffect20, useRef as useRef14, useState as useState22 } from "react";
25886
+ import { useEffect as useEffect17, useRef as useRef14, useState as useState22 } from "react";
26213
25887
 
26214
25888
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/token-suggestions.ts
26215
25889
  function collectTokenSuggestions(entry, availableTokens = []) {
@@ -26262,7 +25936,7 @@ function useReviewEditor({
26262
25936
  const [tokenReviewEditSelection, setTokenReviewEditSelection] = useState22(/* @__PURE__ */ new Set());
26263
25937
  const tokenReviewSuggestedRef = useRef14(/* @__PURE__ */ new Map());
26264
25938
  const pendingGRef = useRef14(false);
26265
- useEffect20(() => {
25939
+ useEffect17(() => {
26266
25940
  setTokenReviewRow(0);
26267
25941
  setTokenReviewEditing(false);
26268
25942
  setTokenReviewEditCursor(0);
@@ -26674,7 +26348,7 @@ function handleJsonPanelInput(input, key, state2) {
26674
26348
  }
26675
26349
 
26676
26350
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-preview.ts
26677
- import { useCallback as useCallback4, useEffect as useEffect22, useState as useState25 } from "react";
26351
+ import { useCallback as useCallback4, useEffect as useEffect19, useState as useState25 } from "react";
26678
26352
 
26679
26353
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/preview-annotations.ts
26680
26354
  function applyPreviewAnnotations(preview, localNames) {
@@ -26709,7 +26383,7 @@ function applyPreviewAnnotations(preview, localNames) {
26709
26383
  }
26710
26384
 
26711
26385
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-live-preview.ts
26712
- import { useCallback as useCallback3, useEffect as useEffect21, useRef as useRef15, useState as useState24 } from "react";
26386
+ import { useCallback as useCallback3, useEffect as useEffect18, useRef as useRef15, useState as useState24 } from "react";
26713
26387
  var DEFAULT_DEBOUNCE_MS = 500;
26714
26388
  function useLivePreview(opts) {
26715
26389
  const debounceMs = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
@@ -26720,14 +26394,14 @@ function useLivePreview(opts) {
26720
26394
  const latestRef = useRef15(0);
26721
26395
  const inflightRef = useRef15(0);
26722
26396
  const optsRef = useRef15(opts);
26723
- useEffect21(() => {
26397
+ useEffect18(() => {
26724
26398
  optsRef.current = opts;
26725
26399
  });
26726
26400
  const disabledRef = useRef15(disabled);
26727
- useEffect21(() => {
26401
+ useEffect18(() => {
26728
26402
  disabledRef.current = disabled;
26729
26403
  }, [disabled]);
26730
- useEffect21(() => {
26404
+ useEffect18(() => {
26731
26405
  return () => {
26732
26406
  if (timerRef.current) {
26733
26407
  clearTimeout(timerRef.current);
@@ -26841,13 +26515,13 @@ function useReviewPreview({
26841
26515
  deleteAllComponents
26842
26516
  });
26843
26517
  const [spinnerTick, setSpinnerTick] = useState25(0);
26844
- useEffect22(() => {
26518
+ useEffect19(() => {
26845
26519
  if (livePreviewHook.status !== "running") return;
26846
26520
  const id = setInterval(() => setSpinnerTick((tick) => tick + 1), 80);
26847
26521
  return () => clearInterval(id);
26848
26522
  }, [livePreviewHook.status]);
26849
26523
  const livePreviewSpinner = SPINNER_FRAMES[spinnerTick % SPINNER_FRAMES.length];
26850
- useEffect22(() => {
26524
+ useEffect19(() => {
26851
26525
  if (loading) return;
26852
26526
  if (!livePreview) return;
26853
26527
  if (components.length === 0) return;
@@ -26856,117 +26530,6 @@ function useReviewPreview({
26856
26530
  return { previewAnnotations, removedComponents, livePreviewHook, livePreviewSpinner };
26857
26531
  }
26858
26532
 
26859
- // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-log.ts
26860
- init_debug_store();
26861
- import { useEffect as useEffect23, useRef as useRef16 } from "react";
26862
-
26863
- // packages/experience-design-system-cli/src/tui/import/steps/09-review/review-log.ts
26864
- var REVIEW_RUN = { flow: "import/review", step: "09-review", menuOption: "Review" };
26865
- var MAX_ACTIONS = 30;
26866
- var MAX_NAMES2 = 20;
26867
- var countStatuses = (components) => {
26868
- const counts = {};
26869
- for (const { status } of components) counts[status] = (counts[status] ?? 0) + 1;
26870
- return counts;
26871
- };
26872
- var capped2 = (keys) => ({
26873
- count: keys.length,
26874
- keys: keys.slice(0, MAX_NAMES2)
26875
- });
26876
- function reviewInputs(components) {
26877
- return { components: components.length, by_status: countStatuses(components) };
26878
- }
26879
- function openReviewTrail(components, now) {
26880
- return {
26881
- startedAt: now,
26882
- start: new Map(components.map((component) => [component.key, component.status])),
26883
- actions: [],
26884
- kinds: {}
26885
- };
26886
- }
26887
- function recordReviewAction(trail, label) {
26888
- const kind = label.split(":")[0] ?? label;
26889
- trail.kinds[kind] = (trail.kinds[kind] ?? 0) + 1;
26890
- if (trail.actions.length < MAX_ACTIONS) trail.actions.push(label);
26891
- }
26892
- function render(trail, components, now, outcome) {
26893
- const acceptedByUser = [];
26894
- const rejectedByUser = [];
26895
- for (const { key, status } of components) {
26896
- const was = trail.start.get(key);
26897
- if (was === status) continue;
26898
- if (status === "accepted") acceptedByUser.push(key);
26899
- if (status === "rejected") rejectedByUser.push(key);
26900
- }
26901
- const total = Object.values(trail.kinds).reduce((sum, count) => sum + count, 0);
26902
- return {
26903
- outcome,
26904
- seconds: Math.round((now - trail.startedAt) / 100) / 10,
26905
- edits: { total, by_kind: trail.kinds, in_order: trail.actions },
26906
- now: countStatuses(components),
26907
- accepted_by_user: capped2(acceptedByUser),
26908
- rejected_by_user: capped2(rejectedByUser)
26909
- };
26910
- }
26911
- function reviewProgress(trail, components, now) {
26912
- return render(trail, components, now, "interrupted");
26913
- }
26914
- function reviewFinish(trail, components, now, final) {
26915
- const outcome = final ? `finalized: ${final.accepted} accepted, ${final.rejected} rejected, ${final.unresolved} unresolved` : "left the review without finishing";
26916
- return {
26917
- outputs: render(trail, components, now, outcome),
26918
- status: "success",
26919
- exitMethod: final ? "saved" : "discarded"
26920
- };
26921
- }
26922
-
26923
- // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-log.ts
26924
- function useReviewLog({
26925
- loading,
26926
- loadError,
26927
- components
26928
- }) {
26929
- const trail = useRef16(void 0);
26930
- const started = useRef16(false);
26931
- const latest = useRef16(components);
26932
- latest.current = components;
26933
- useEffect23(() => {
26934
- if (loading || started.current) return;
26935
- started.current = true;
26936
- startDebugRun({ ...REVIEW_RUN, inputs: reviewInputs(components) });
26937
- if (loadError) {
26938
- void finishDebugRun({
26939
- outputs: { outcome: "could not load the components", error: loadError },
26940
- status: "error",
26941
- exitMethod: "discarded"
26942
- });
26943
- return;
26944
- }
26945
- trail.current = openReviewTrail(components, Date.now());
26946
- setDebugRunProgress(reviewProgress(trail.current, components, Date.now()));
26947
- }, [loading, loadError, components]);
26948
- useEffect23(
26949
- () => () => {
26950
- const open = trail.current;
26951
- trail.current = void 0;
26952
- if (open) void finishDebugRun(reviewFinish(open, latest.current, Date.now(), void 0));
26953
- },
26954
- []
26955
- );
26956
- return {
26957
- record: (label) => {
26958
- if (!trail.current) return;
26959
- recordReviewAction(trail.current, label);
26960
- setDebugRunProgress(reviewProgress(trail.current, latest.current, Date.now()));
26961
- },
26962
- finish: (counts) => {
26963
- const open = trail.current;
26964
- trail.current = void 0;
26965
- if (open) void finishDebugRun(reviewFinish(open, latest.current, Date.now(), counts));
26966
- }
26967
- };
26968
- }
26969
-
26970
26533
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/components/LivePreviewSummary.tsx
26971
26534
  import { Box as Box37, Text as Text39 } from "ink";
26972
26535
  import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
@@ -27254,7 +26817,6 @@ function GenerateReviewStepView({
27254
26817
  tokensPath,
27255
26818
  onExtraLoaded: setLoadedSlotCycles
27256
26819
  });
27257
- const reviewLog = useReviewLog({ loading, loadError, components });
27258
26820
  const [nav, setNav] = useState26({
27259
26821
  cursorRowIdx: 0,
27260
26822
  sidebarScrollOffset: 0
@@ -27272,7 +26834,7 @@ function GenerateReviewStepView({
27272
26834
  setFinalizeError
27273
26835
  } = reviewSurface;
27274
26836
  const [removedBannerCollapsed, setRemovedBannerCollapsed] = useState26(false);
27275
- const removedBannerDefaultedRef = useRef17(false);
26837
+ const removedBannerDefaultedRef = useRef16(false);
27276
26838
  const [cyclePanelScroll, setCyclePanelScroll] = useState26(0);
27277
26839
  const [cyclesCursor, setCyclesCursor] = useState26(0);
27278
26840
  const cyclePanel = useOverlayPanel({
@@ -27292,7 +26854,7 @@ function GenerateReviewStepView({
27292
26854
  const [breakCursor, setBreakCursor] = useState26(0);
27293
26855
  const [breakConfirm, setBreakConfirm] = useState26(false);
27294
26856
  const [expandedGroups, setExpandedGroups] = useState26(/* @__PURE__ */ new Set());
27295
- const seededGroupsRef = useRef17(false);
26857
+ const seededGroupsRef = useRef16(false);
27296
26858
  const {
27297
26859
  searchOpen,
27298
26860
  setSearchOpen,
@@ -27316,7 +26878,7 @@ function GenerateReviewStepView({
27316
26878
  const [pendingEditorFocus, setPendingEditorFocus] = useState26(null);
27317
26879
  const [autoRejected, setAutoRejected] = useState26([]);
27318
26880
  const [undoSnapshot, setUndoSnapshot] = useState26(null);
27319
- const autoRejectFiredRef = useRef17(false);
26881
+ const autoRejectFiredRef = useRef16(false);
27320
26882
  const [showReloadDialog, setShowReloadDialog] = useState26(false);
27321
26883
  const acceptedCountForPreview = components.filter((c2) => c2.status === "accepted").length;
27322
26884
  const { previewAnnotations, removedComponents, livePreviewHook, livePreviewSpinner } = useReviewPreview({
@@ -27348,10 +26910,7 @@ function GenerateReviewStepView({
27348
26910
  cmaToken,
27349
26911
  host,
27350
26912
  components,
27351
- onFinalize: (accepted, rejected, unresolved) => {
27352
- reviewLog.finish({ accepted, rejected, unresolved });
27353
- onFinalize(accepted, rejected, unresolved);
27354
- }
26913
+ onFinalize
27355
26914
  });
27356
26915
  const recomputeCycles = (currentComponents) => {
27357
26916
  try {
@@ -27382,7 +26941,7 @@ function GenerateReviewStepView({
27382
26941
  [components]
27383
26942
  );
27384
26943
  const closures = useMemo6(() => computeAllClosures(componentGraph), [componentGraph]);
27385
- useEffect24(() => {
26944
+ useEffect20(() => {
27386
26945
  if (seededGroupsRef.current) return;
27387
26946
  if (closures.size === 0 && slotCycles.length === 0) return;
27388
26947
  seededGroupsRef.current = true;
@@ -27409,7 +26968,7 @@ function GenerateReviewStepView({
27409
26968
  suggestedBreak: cycle.edges.length > 0 ? suggestCycleBreakEdge2(cycle, cycleView.pushBlocking) : null
27410
26969
  }));
27411
26970
  }, [slotCycles, cycleView]);
27412
- useEffect24(() => {
26971
+ useEffect20(() => {
27413
26972
  const decision = computeAutoRejectDecision({
27414
26973
  loading,
27415
26974
  autoRejectFired: autoRejectFiredRef.current,
@@ -27450,11 +27009,10 @@ function GenerateReviewStepView({
27450
27009
  autoRejected,
27451
27010
  undoSnapshot
27452
27011
  }),
27453
- applySnapshot: applyHistorySnapshot,
27454
- onAction: reviewLog.record
27012
+ applySnapshot: applyHistorySnapshot
27455
27013
  });
27456
- const autoRejectPushedRef = useRef17(false);
27457
- useEffect24(() => {
27014
+ const autoRejectPushedRef = useRef16(false);
27015
+ useEffect20(() => {
27458
27016
  if (loading) return;
27459
27017
  if (!historySeededRef.current) return;
27460
27018
  if (!autoRejectFiredRef.current) return;
@@ -27538,7 +27096,7 @@ function GenerateReviewStepView({
27538
27096
  const panelHeight = leftPanelHeight + 2;
27539
27097
  const panelContentHeight = Math.max(1, panelHeight - 3);
27540
27098
  const cycleViewportHeight = Math.max(1, panelHeight - 4);
27541
- useEffect24(() => {
27099
+ useEffect20(() => {
27542
27100
  if (selectableRowPositions.length === 0) return;
27543
27101
  const cursorInRange = selectableRowPositions.includes(cursorRowIdx);
27544
27102
  const maxScroll = Math.max(0, visibleRowsMemo.length - visibleCount);
@@ -28483,10 +28041,10 @@ function normalizePath(input) {
28483
28041
  }
28484
28042
 
28485
28043
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
28486
- import { useEffect as useEffect25, useState as useState27 } from "react";
28044
+ import { useEffect as useEffect21, useState as useState27 } from "react";
28487
28045
  function useBlinkingCursor() {
28488
28046
  const [visible, setVisible] = useState27(true);
28489
- useEffect25(() => {
28047
+ useEffect21(() => {
28490
28048
  const interval = setInterval(() => setVisible((current) => !current), 500);
28491
28049
  return () => clearInterval(interval);
28492
28050
  }, []);
@@ -28602,12 +28160,12 @@ function countedThings({ components, tokens }, counts = {}) {
28602
28160
  }
28603
28161
 
28604
28162
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-timed-spinner.tsx
28605
- import { useEffect as useEffect26, useState as useState29 } from "react";
28163
+ import { useEffect as useEffect22, useState as useState29 } from "react";
28606
28164
  import { Spinner as Spinner2 } from "@inkjs/ui";
28607
28165
  import { jsx as jsx53 } from "react/jsx-runtime";
28608
28166
  function useTimedSpinner() {
28609
28167
  const [elapsedSeconds, setElapsedSeconds] = useState29(0);
28610
- useEffect26(() => {
28168
+ useEffect22(() => {
28611
28169
  const timer = setInterval(() => setElapsedSeconds((current) => current + 1), 1e3);
28612
28170
  return () => {
28613
28171
  clearInterval(timer);
@@ -28665,7 +28223,7 @@ function PushingStep({ progress, produced, counts }) {
28665
28223
  }
28666
28224
 
28667
28225
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/WizardPreviewStep.tsx
28668
- import { useEffect as useEffect27, useState as useState30, useMemo as useMemo7 } from "react";
28226
+ import { useEffect as useEffect23, useState as useState30, useMemo as useMemo7 } from "react";
28669
28227
  import { Box as Box44, Text as Text46 } from "ink";
28670
28228
 
28671
28229
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/preview-diff.ts
@@ -29060,7 +28618,7 @@ function WizardPreviewStep({
29060
28618
  const activeLines = diffExpanded ? diffLines : summaryLines;
29061
28619
  const maxScroll = Math.max(0, activeLines.length - viewportHeight);
29062
28620
  const boundedScrollOffset = Math.min(scrollOffset, maxScroll);
29063
- useEffect27(() => {
28621
+ useEffect23(() => {
29064
28622
  setScrollOffset((previous) => Math.min(previous, maxScroll));
29065
28623
  }, [maxScroll]);
29066
28624
  useImmediateInput((input, key) => {
@@ -29150,194 +28708,6 @@ function buildRunTeaserLine(runId) {
29150
28708
  return `Run saved as ${runId}.`;
29151
28709
  }
29152
28710
 
29153
- // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow-log.ts
29154
- init_debug_store();
29155
- import { useEffect as useEffect28, useRef as useRef18 } from "react";
29156
-
29157
- // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/flow-log.ts
29158
- var FLOW_RUN = { flow: "import/publish", step: "10-publish", menuOption: "Publish" };
29159
- var LABELS = {
29160
- "final-review": "Final review",
29161
- "path-prompt": "Save path",
29162
- printing: "Save files",
29163
- previewing: "Preview",
29164
- "preview-gate": "Preview confirmation",
29165
- pushing: "Push",
29166
- "print-gate": "Files saved",
29167
- done: "Done",
29168
- error: "Error",
29169
- "preview-validation-error": "Preview validation"
29170
- };
29171
- var WORK = ["printing", "previewing", "pushing"];
29172
- var FINISHED = ["done", "error", "preview-validation-error", "final-review"];
29173
- var MAX_LOGGED = 10;
29174
- var MAX_OUTCOME = 200;
29175
- var scrub = (text, state2) => scrubError(text, [state2.cmaToken]);
29176
- var seconds = (ms) => Math.round(ms / 100) / 10;
29177
- var pushHasFailures = (result) => result.componentTypes.failed + result.designTokens.failed > 0 || (result.failures?.length ?? 0) > 0 || (result.summary?.failed ?? 0) > 0;
29178
- function previewSummary(preview) {
29179
- const counts = (group) => ({
29180
- new: group.new.length,
29181
- changed: group.changed.length,
29182
- removed: group.removed.length
29183
- });
29184
- return {
29185
- components: counts(preview.components),
29186
- tokens: counts(preview.tokens),
29187
- breaking_components: preview.components.changed.filter(
29188
- (entry) => entry.changeClassification?.classification === "breaking"
29189
- ).length
29190
- };
29191
- }
29192
- function pushSummary(result, state2) {
29193
- const failures = result.failures ?? [];
29194
- return {
29195
- component_types: result.componentTypes,
29196
- design_tokens: result.designTokens,
29197
- ...result.summary ? { summary: result.summary } : {},
29198
- ...failures.length > 0 ? {
29199
- failure_count: failures.length,
29200
- failures: failures.slice(0, MAX_LOGGED).map((failure) => ({
29201
- entity_type: failure.entityType,
29202
- entity_id: failure.entityId,
29203
- message: scrub(failure.message, state2)
29204
- }))
29205
- } : {}
29206
- };
29207
- }
29208
- function flowContext(state2) {
29209
- return {
29210
- agent: state2.agent,
29211
- space_id: state2.spaceId,
29212
- environment_id: state2.environmentId,
29213
- host: state2.host,
29214
- credentials_skipped: state2.credentialsSkipped,
29215
- components_generated: state2.generatedCount,
29216
- components_accepted: state2.generatedAcceptedCount,
29217
- tokens: state2.tokenCount,
29218
- cma_token: state2.cmaToken
29219
- };
29220
- }
29221
- function arrive(trail, state2) {
29222
- const next = { ...trail, at: state2.step };
29223
- if (state2.step === "error") {
29224
- next.failure = { step: state2.errorStep, message: scrub(state2.errorMessage, state2) };
29225
- }
29226
- if (state2.step === "preview-validation-error") {
29227
- next.validation = {
29228
- count: state2.previewValidationErrors.length,
29229
- errors: state2.previewValidationErrors.slice(0, MAX_LOGGED).map((error) => ({
29230
- component: error.componentName,
29231
- path: error.path,
29232
- message: scrub(error.message, state2)
29233
- })),
29234
- missing_names: state2.previewValidationMissingNames.slice(0, MAX_LOGGED * 2)
29235
- };
29236
- }
29237
- return next;
29238
- }
29239
- function openTrail(state2, now) {
29240
- return arrive({ startedAt: now, stageStartedAt: now, at: state2.step, stages: [] }, state2);
29241
- }
29242
- function advance(trail, from, to, now) {
29243
- const next = { ...trail, stages: [...trail.stages], stageStartedAt: now };
29244
- const failed = to.step === "error" || to.step === "preview-validation-error" || from.step === "pushing" && pushHasFailures(to.pushResult);
29245
- if (WORK.includes(from.step)) {
29246
- next.stages.push(`${LABELS[from.step]}: ${failed ? "failed" : "ok"} (${seconds(now - trail.stageStartedAt)}s)`);
29247
- }
29248
- if (from.step === "previewing" && to.serverPreview) next.preview = previewSummary(to.serverPreview);
29249
- if (from.step === "pushing") {
29250
- next.push = pushSummary(to.pushResult, to);
29251
- next.pushFailed = pushHasFailures(to.pushResult);
29252
- }
29253
- if (from.step === "printing" && !failed) next.saved = { path: to.componentsPath, run_id: to.lastRunId };
29254
- return arrive(next, to);
29255
- }
29256
- var isFlowFinished = (step) => FINISHED.includes(step);
29257
- function render2(trail, now, outcome) {
29258
- return {
29259
- outcome,
29260
- total_seconds: seconds(now - trail.startedAt),
29261
- stages: trail.stages,
29262
- ...trail.preview ? { preview: trail.preview } : {},
29263
- ...trail.push ? { push: trail.push } : {},
29264
- ...trail.saved ? { saved: trail.saved } : {},
29265
- ...trail.failure ? { error: trail.failure } : {},
29266
- ...trail.validation ? { preview_validation: trail.validation } : {}
29267
- };
29268
- }
29269
- function flowProgress(trail, now) {
29270
- return render2(trail, now, `interrupted at ${LABELS[trail.at]}`);
29271
- }
29272
- function flowFinish(trail, final, now) {
29273
- if (!final) {
29274
- const midWork = WORK.includes(trail.at);
29275
- const outcome2 = `left the import ${midWork ? "while" : "at"} ${LABELS[trail.at]}${midWork ? " was running" : ""}`;
29276
- return { outputs: render2(trail, now, outcome2), status: midWork ? "error" : "success", exitMethod: "discarded" };
29277
- }
29278
- if (final.step === "final-review") {
29279
- return {
29280
- outputs: render2(trail, now, "went back to edit the definitions"),
29281
- status: "success",
29282
- exitMethod: "discarded"
29283
- };
29284
- }
29285
- let outcome;
29286
- let failed = true;
29287
- if (trail.validation) {
29288
- outcome = `blocked by ${String(trail.validation["count"])} preview validation error(s)`;
29289
- } else if (trail.failure) {
29290
- outcome = `failed at ${trail.failure.step}: ${trail.failure.message.slice(0, MAX_OUTCOME)}`;
29291
- } else if (trail.pushFailed) {
29292
- outcome = "pushed, but some entities failed";
29293
- } else {
29294
- failed = false;
29295
- outcome = final.credentialsSkipped ? "saved without pushing (credentials skipped)" : "published";
29296
- }
29297
- return {
29298
- outputs: render2(trail, now, outcome),
29299
- status: failed ? "error" : "success",
29300
- exitMethod: failed ? "discarded" : "saved"
29301
- };
29302
- }
29303
-
29304
- // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow-log.ts
29305
- function useFlowLog(state2) {
29306
- const trail = useRef18(void 0);
29307
- const previous = useRef18(void 0);
29308
- useEffect28(() => {
29309
- const before = previous.current;
29310
- previous.current = state2;
29311
- const moved = before !== void 0 && before.step !== state2.step;
29312
- const now = Date.now();
29313
- let open = trail.current;
29314
- if (!open) {
29315
- if (state2.step === "final-review" || before && !moved) return;
29316
- open = openTrail(state2, now);
29317
- startDebugRun({ ...FLOW_RUN, inputs: flowContext(state2) });
29318
- } else if (before && moved) {
29319
- open = advance(open, before, state2, now);
29320
- } else {
29321
- return;
29322
- }
29323
- if (isFlowFinished(state2.step)) {
29324
- trail.current = void 0;
29325
- void finishDebugRun(flowFinish(open, state2, now));
29326
- return;
29327
- }
29328
- trail.current = open;
29329
- setDebugRunProgress(flowProgress(open, now));
29330
- }, [state2]);
29331
- useEffect28(
29332
- () => () => {
29333
- const open = trail.current;
29334
- trail.current = void 0;
29335
- if (open) void finishDebugRun(flowFinish(open, void 0, Date.now()));
29336
- },
29337
- []
29338
- );
29339
- }
29340
-
29341
28711
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/screen.tsx
29342
28712
  import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
29343
28713
  function canEditFromPreview(cdf) {
@@ -29351,7 +28721,6 @@ function FlowScreen({
29351
28721
  generatePromptPath,
29352
28722
  onExit
29353
28723
  }) {
29354
- useFlowLog(state2);
29355
28724
  const produced = producedOf(state2);
29356
28725
  const counts = { components: state2.generatedAcceptedCount, tokens: state2.tokenCount };
29357
28726
  const things = countedThings(produced, counts);
@@ -29467,7 +28836,7 @@ function FlowScreen({
29467
28836
  }
29468
28837
 
29469
28838
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
29470
- import { useEffect as useEffect29, useRef as useRef19, useSyncExternalStore } from "react";
28839
+ import { useEffect as useEffect24, useRef as useRef17, useSyncExternalStore } from "react";
29471
28840
 
29472
28841
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
29473
28842
  import { appendFileSync, writeFileSync } from "node:fs";
@@ -29832,12 +29201,14 @@ function nextStateAfterPrint(opts) {
29832
29201
 
29833
29202
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/save.ts
29834
29203
  var SAVE_CONFIRMATION_DELAY_MS = 1e3;
29204
+ var describeCdfError = (error) => `${error.path.replace(/^\//, "").replace("/$properties/", ".").replaceAll("/", ".")}: ${error.message}`;
29835
29205
  function buildSavedCDF(components, tokens, opts = {}) {
29836
29206
  const cdf = buildCDF2(components, toCdfTokens(tokens), opts);
29837
29207
  if (!cdf) throw new Error("nothing to save \u2014 no components or tokens resolved");
29838
29208
  const validation = validateCDF2(cdf);
29839
29209
  if (!validation.valid) {
29840
- throw new Error(`generated CDF failed validation: ${validation.errors.map((error) => error.message).join(", ")}`);
29210
+ const errors = validation.errors.filter((error) => error.message !== 'must match "then" schema');
29211
+ throw new Error(`generated CDF failed validation: ${errors.map(describeCdfError).join("; ")}`);
29841
29212
  }
29842
29213
  return cdf;
29843
29214
  }
@@ -30209,7 +29580,7 @@ function createFlowController(start, deps) {
30209
29580
 
30210
29581
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
30211
29582
  function useFlow(start, options = {}) {
30212
- const controller = useRef19();
29583
+ const controller = useRef17();
30213
29584
  if (start && !controller.current) {
30214
29585
  try {
30215
29586
  startWizardLog();
@@ -30226,14 +29597,14 @@ function useFlow(start, options = {}) {
30226
29597
  (listener) => current?.subscribe(listener) ?? (() => void 0),
30227
29598
  () => current?.getState()
30228
29599
  );
30229
- useEffect29(() => {
29600
+ useEffect24(() => {
30230
29601
  if (!start) controller.current = void 0;
30231
29602
  }, [start]);
30232
29603
  return current && state2 ? { controller: current, state: state2 } : void 0;
30233
29604
  }
30234
29605
 
30235
29606
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
30236
- import { useEffect as useEffect30, useState as useState31 } from "react";
29607
+ import { useEffect as useEffect25, useState as useState31 } from "react";
30237
29608
  import { Box as Box46, Text as Text47, useInput as useInput13 } from "ink";
30238
29609
  init_debug_store();
30239
29610
 
@@ -30307,7 +29678,7 @@ function Section({ title, rows }) {
30307
29678
  }
30308
29679
  function HelpScreen({ onDone }) {
30309
29680
  const [info, setInfo] = useState31();
30310
- useEffect30(() => {
29681
+ useEffect25(() => {
30311
29682
  startDebugRun({ flow: "help", step: "01-help", menuOption: "Help", inputs: {} });
30312
29683
  void readHelpInfo().then(setInfo);
30313
29684
  }, []);
@@ -30404,10 +29775,43 @@ import { useState as useState36 } from "react";
30404
29775
  import { Box as Box51, Text as Text53, useInput as useInput17 } from "ink";
30405
29776
 
30406
29777
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentsScreen.tsx
30407
- import { useEffect as useEffect32, useRef as useRef20, useState as useState34 } from "react";
29778
+ import { useEffect as useEffect27, useRef as useRef18, useState as useState34 } from "react";
30408
29779
  import { Box as Box49, Text as Text51, useInput as useInput15 } from "ink";
30409
29780
  init_debug_store();
30410
29781
 
29782
+ // packages/experience-design-system-cli/src/tui/settings/shared/debug-trail.ts
29783
+ init_config();
29784
+ import { existsSync as existsSync10 } from "node:fs";
29785
+ function diffSnapshots(before, after) {
29786
+ const names = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])];
29787
+ const changed_fields = names.filter((name) => before[name] !== after[name]);
29788
+ return { changed: changed_fields.length > 0, changed_fields };
29789
+ }
29790
+ var DEFAULT_TRAIL_LIMIT = 30;
29791
+ function createTrail(limit = DEFAULT_TRAIL_LIMIT) {
29792
+ const actions = [];
29793
+ return {
29794
+ record(action) {
29795
+ actions.push(action);
29796
+ if (actions.length > limit) actions.shift();
29797
+ },
29798
+ entries: () => [...actions]
29799
+ };
29800
+ }
29801
+ var MIN_SECRET_LENGTH = 6;
29802
+ function scrubError(error, secrets) {
29803
+ let message = error instanceof Error ? error.message : String(error);
29804
+ for (const secret of secrets) {
29805
+ if (secret.length < MIN_SECRET_LENGTH) continue;
29806
+ for (const form of /* @__PURE__ */ new Set([secret, encodeURIComponent(secret)])) message = message.split(form).join("[redacted]");
29807
+ }
29808
+ return message;
29809
+ }
29810
+ function describeSettingsFile() {
29811
+ const path5 = configFilePath();
29812
+ return { path: path5, eds_home_set: Boolean(process.env["EDS_HOME"]), exists: existsSync10(path5) };
29813
+ }
29814
+
30411
29815
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts
30412
29816
  import { execFile as execFile2 } from "node:child_process";
30413
29817
  import { access as access5, constants } from "node:fs/promises";
@@ -30492,7 +29896,7 @@ async function testAgent(name, binary, model) {
30492
29896
  timeoutMs: PROMPT_TIMEOUT_MS
30493
29897
  })
30494
29898
  );
30495
- const seconds2 = ((Date.now() - started) / 1e3).toFixed(1);
29899
+ const seconds = ((Date.now() - started) / 1e3).toFixed(1);
30496
29900
  if (result.timedOut) {
30497
29901
  return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
30498
29902
  }
@@ -30500,7 +29904,7 @@ async function testAgent(name, binary, model) {
30500
29904
  const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
30501
29905
  return [...checks, fail3("prompt", reason)];
30502
29906
  }
30503
- return [...checks, pass("prompt", `answered in ${seconds2}s`)];
29907
+ return [...checks, pass("prompt", `answered in ${seconds}s`)];
30504
29908
  }
30505
29909
  function statusFromChecks(name, checks, savedBinary) {
30506
29910
  if (checks.length === 0) return "checking";
@@ -30700,7 +30104,7 @@ async function writeAgentConfig(config) {
30700
30104
  }
30701
30105
 
30702
30106
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentDetail.tsx
30703
- import { useEffect as useEffect31, useState as useState33 } from "react";
30107
+ import { useEffect as useEffect26, useState as useState33 } from "react";
30704
30108
  import { Box as Box48, Text as Text50 } from "ink";
30705
30109
 
30706
30110
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentStatusBadge.tsx
@@ -30763,7 +30167,7 @@ function AgentDetail({
30763
30167
  const [testing, setTesting] = useState33(false);
30764
30168
  const [notice, setNotice] = useState33(null);
30765
30169
  const [checks, setChecks] = useState33(void 0);
30766
- useEffect31(() => {
30170
+ useEffect26(() => {
30767
30171
  let active = true;
30768
30172
  setChecks(void 0);
30769
30173
  const timer = setTimeout(() => {
@@ -30848,7 +30252,7 @@ function AgentsScreen({ onDone }) {
30848
30252
  const [saving, setSaving] = useState34(false);
30849
30253
  const [loadError, setLoadError] = useState34(null);
30850
30254
  const [checks, setChecks] = useState34({});
30851
- const visit = useRef20({
30255
+ const visit = useRef18({
30852
30256
  trail: createTrail(),
30853
30257
  before: void 0,
30854
30258
  environment: void 0,
@@ -30861,7 +30265,7 @@ function AgentsScreen({ onDone }) {
30861
30265
  );
30862
30266
  }
30863
30267
  };
30864
- useEffect32(() => {
30268
+ useEffect27(() => {
30865
30269
  readAgentConfig().then((loaded) => {
30866
30270
  setConfig(loaded);
30867
30271
  inspectAll(loaded);
@@ -31038,7 +30442,7 @@ function AgentsScreen({ onDone }) {
31038
30442
  }
31039
30443
 
31040
30444
  // packages/experience-design-system-cli/src/tui/settings/configuration/project/ProjectScreen.tsx
31041
- import { useEffect as useEffect33, useRef as useRef21, useState as useState35 } from "react";
30445
+ import { useEffect as useEffect28, useRef as useRef19, useState as useState35 } from "react";
31042
30446
  import { Box as Box50, Text as Text52, useInput as useInput16 } from "ink";
31043
30447
  init_debug_store();
31044
30448
 
@@ -31096,14 +30500,14 @@ function ProjectScreen({ onDone }) {
31096
30500
  const [saving, setSaving] = useState35(false);
31097
30501
  const [notice, setNotice] = useState35(null);
31098
30502
  const [loadError, setLoadError] = useState35(null);
31099
- const visit = useRef21({
30503
+ const visit = useRef19({
31100
30504
  trail: createTrail(),
31101
30505
  before: void 0,
31102
30506
  persisted: void 0,
31103
30507
  error: ""
31104
30508
  }).current;
31105
- const scrub2 = (err) => scrubError(err, [config?.cmaToken ?? ""]);
31106
- useEffect33(() => {
30509
+ const scrub = (err) => scrubError(err, [config?.cmaToken ?? ""]);
30510
+ useEffect28(() => {
31107
30511
  readCredentials().then((cfg) => {
31108
30512
  setConfig(cfg);
31109
30513
  visit.before = snapshotOf(cfg);
@@ -31170,7 +30574,7 @@ function ProjectScreen({ onDone }) {
31170
30574
  if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
31171
30575
  setNotice({ kind: "success", text: "Project settings saved" });
31172
30576
  }).catch((err) => {
31173
- visit.error = scrub2(err);
30577
+ visit.error = scrub(err);
31174
30578
  visit.trail.record("save failed");
31175
30579
  setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
31176
30580
  }).finally(() => setSaving(false));
@@ -31255,7 +30659,7 @@ function ConfigurationScreen({ onDone }) {
31255
30659
  }
31256
30660
 
31257
30661
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
31258
- import { useEffect as useEffect34, useState as useState37 } from "react";
30662
+ import { useEffect as useEffect29, useState as useState37 } from "react";
31259
30663
  import { Box as Box52, Text as Text54, useInput as useInput18 } from "ink";
31260
30664
 
31261
30665
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
@@ -31279,7 +30683,7 @@ import { Fragment as Fragment20, jsx as jsx64, jsxs as jsxs52 } from "react/jsx-
31279
30683
  function OptInAnalyticsScreen({ onDone }) {
31280
30684
  const [loading, setLoading] = useState37(true);
31281
30685
  const [enabled, setEnabled] = useState37(true);
31282
- useEffect34(() => {
30686
+ useEffect29(() => {
31283
30687
  readAnalyticsSetting().then((setting) => {
31284
30688
  setEnabled(setting.enabled);
31285
30689
  setLoading(false);
@@ -31333,7 +30737,7 @@ function OptInAnalyticsScreen({ onDone }) {
31333
30737
  }
31334
30738
 
31335
30739
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
31336
- import { useEffect as useEffect35, useRef as useRef22, useState as useState38 } from "react";
30740
+ import { useEffect as useEffect30, useRef as useRef20, useState as useState38 } from "react";
31337
30741
  import { Box as Box53, Text as Text55, useInput as useInput19 } from "ink";
31338
30742
  init_debug_mode_store();
31339
30743
  init_debug_store();
@@ -31350,8 +30754,8 @@ function DebugModeScreen({ onDone }) {
31350
30754
  RETENTION_CHOICES[RETENTION_CHOICES.length - 1]
31351
30755
  );
31352
30756
  const [notice, setNotice] = useState38(null);
31353
- const visit = useRef22({ trail: createTrail(), before: void 0, error: "" }).current;
31354
- useEffect35(() => {
30757
+ const visit = useRef20({ trail: createTrail(), before: void 0, error: "" }).current;
30758
+ useEffect30(() => {
31355
30759
  readDebugModeSetting().then((loaded) => {
31356
30760
  setSetting(loaded);
31357
30761
  setPending(loaded.retentionDays);
@@ -31506,7 +30910,7 @@ function App({ importOptions, inkClear }) {
31506
30910
  const [flowStart, setFlowStart] = useState39();
31507
30911
  const flow = useFlow(flowStart, { beforeStepChange: inkClear });
31508
30912
  const [importDefaults, setImportDefaults] = useState39();
31509
- useEffect36(() => {
30913
+ useEffect31(() => {
31510
30914
  if (screen !== "import") {
31511
30915
  setImportDefaults(void 0);
31512
30916
  return;
@@ -31579,7 +30983,7 @@ function App({ importOptions, inkClear }) {
31579
30983
  }
31580
30984
  });
31581
30985
  };
31582
- useEffect36(() => {
30986
+ useEffect31(() => {
31583
30987
  if (!tokensOnlyRun || tokensOnly?.status !== "done" || !tokensOnly.result.ok) return;
31584
30988
  const { credentialsSkipped, input, tokens } = tokensOnlyRun;
31585
30989
  const { tokensPath, tokenSessionId, tokenCount } = tokensOnly.result;
@@ -31601,12 +31005,12 @@ function App({ importOptions, inkClear }) {
31601
31005
  }
31602
31006
  });
31603
31007
  }, [tokensOnly, tokensOnlyRun]);
31604
- useEffect36(() => {
31008
+ useEffect31(() => {
31605
31009
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
31606
31010
  setExtractionRun(void 0);
31607
31011
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
31608
31012
  }, [extraction, extractionRun]);
31609
- useEffect36(() => {
31013
+ useEffect31(() => {
31610
31014
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
31611
31015
  const { extraction: produced, input, generatePromptPath } = scopeRun;
31612
31016
  setGenerationInput({
@@ -31624,7 +31028,7 @@ function App({ importOptions, inkClear }) {
31624
31028
  ...generatePromptPath ? { generatePromptPath } : {}
31625
31029
  });
31626
31030
  }, [scopeFlow, scopeRun, generationInput]);
31627
- useEffect36(() => {
31031
+ useEffect31(() => {
31628
31032
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
31629
31033
  const { credentialsSkipped, extraction: produced, input, generatePromptPath } = scopeRun;
31630
31034
  inkClear();
@@ -31793,7 +31197,6 @@ function App({ importOptions, inkClear }) {
31793
31197
  return /* @__PURE__ */ jsx66(
31794
31198
  CredentialsScreen,
31795
31199
  {
31796
- mode: target,
31797
31200
  initial: importDefaults.credentials,
31798
31201
  tokensOnly: target === "tokens",
31799
31202
  onBack: () => goBackFrom("credentials"),