@contentful/experience-design-system-cli 2.41.1-dev-build-f74a0859.0 → 2.41.1-dev-build-0eca66e2.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,6 +197,7 @@ __export(debug_store_exports, {
197
197
  currentDebugSessionDir: () => currentDebugSessionDir,
198
198
  currentSessionDir: () => currentSessionDir,
199
199
  finishDebugRun: () => finishDebugRun,
200
+ setDebugRunProgress: () => setDebugRunProgress,
200
201
  startDebugRun: () => startDebugRun,
201
202
  startDebugSessionIn: () => startDebugSessionIn,
202
203
  startImportRun: () => startImportRun
@@ -292,11 +293,15 @@ function startDebugRun({
292
293
  const runId = generateRunId();
293
294
  const startedAt = Date.now();
294
295
  const redactedInputs = redact(inputs);
295
- isDebugModeEnabled().then((enabled) => {
296
- if (!enabled) return;
297
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
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;
298
300
  });
299
301
  }
302
+ function setDebugRunProgress(outputs) {
303
+ if (pendingRun) pendingRun.progress = outputs;
304
+ }
300
305
  async function finishDebugRun({
301
306
  outputs,
302
307
  status,
@@ -305,9 +310,10 @@ async function finishDebugRun({
305
310
  const run = pendingRun;
306
311
  if (!run) return;
307
312
  pendingRun = void 0;
313
+ if (!await isDebugModeEnabled()) return;
308
314
  const durationMs = Date.now() - run.startedAt;
309
315
  const log = {
310
- flow: run.flow,
316
+ flow: logFolder(run.flow, run.step),
311
317
  menuOption: run.menuOption,
312
318
  content: renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs })
313
319
  };
@@ -318,6 +324,9 @@ async function finishDebugRun({
318
324
  }
319
325
  await writeLog(root, log);
320
326
  }
327
+ function logFolder(flow, step) {
328
+ return flow.startsWith("import/") && /^\d+-/.test(step) ? `import/${step}` : flow;
329
+ }
321
330
  async function writeLog(root, log) {
322
331
  const dir = join5(root, ...log.flow.split("/"));
323
332
  await mkdir2(dir, { recursive: true });
@@ -374,7 +383,7 @@ ${JSON.stringify(finish.outputs, null, 2)}
374
383
  `;
375
384
  }
376
385
  function handleCrash() {
377
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
386
+ return finishDebugRun({ outputs: pendingRun?.progress ?? {}, status: "error", exitMethod: "crashed" });
378
387
  }
379
388
  var pendingRun, sessionDir, WAITING_LIMIT, waiting;
380
389
  var init_debug_store = __esm({
@@ -418,11 +427,17 @@ var init_debug_store = __esm({
418
427
  throw reason;
419
428
  });
420
429
  });
421
- process.once("SIGINT", () => {
422
- void handleCrash().finally(() => {
423
- process.exit(130);
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
+ });
424
439
  });
425
- });
440
+ }
426
441
  }
427
442
  });
428
443
 
@@ -2484,7 +2499,7 @@ var init_cache_keys = __esm({
2484
2499
  });
2485
2500
 
2486
2501
  // packages/experience-design-system-cli/app.tsx
2487
- import { useEffect as useEffect31, useState as useState39 } from "react";
2502
+ import { useEffect as useEffect36, useState as useState39 } from "react";
2488
2503
 
2489
2504
  // packages/experience-design-system-cli/src/tui/home/home.tsx
2490
2505
  import { useEffect as useEffect2, useState as useState2 } from "react";
@@ -3042,8 +3057,8 @@ function progressPercent(progress) {
3042
3057
  }
3043
3058
  function formatElapsed(totalSeconds) {
3044
3059
  const minutes = Math.floor(totalSeconds / 60);
3045
- const seconds = totalSeconds % 60;
3046
- return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
3060
+ const seconds2 = totalSeconds % 60;
3061
+ return minutes > 0 ? `${minutes}m ${seconds2}s` : `${seconds2}s`;
3047
3062
  }
3048
3063
 
3049
3064
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/theme.ts
@@ -3061,12 +3076,12 @@ var PROGRESS_THEME = extendTheme(defaultTheme, {
3061
3076
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/use-elapsed.ts
3062
3077
  import { useEffect as useEffect3, useState as useState3 } from "react";
3063
3078
  function useElapsed() {
3064
- const [seconds, setSeconds] = useState3(0);
3079
+ const [seconds2, setSeconds] = useState3(0);
3065
3080
  useEffect3(() => {
3066
3081
  const timer = setInterval(() => setSeconds((current) => current + 1), 1e3);
3067
3082
  return () => clearInterval(timer);
3068
3083
  }, []);
3069
- return formatElapsed(seconds);
3084
+ return formatElapsed(seconds2);
3070
3085
  }
3071
3086
 
3072
3087
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx
@@ -15253,8 +15268,8 @@ function retryAfterMs(response) {
15253
15268
  const value = response.headers?.get("retry-after")?.trim();
15254
15269
  if (!value)
15255
15270
  return void 0;
15256
- const seconds = Number(value);
15257
- const delayMs = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(value) - Date.now();
15271
+ const seconds2 = Number(value);
15272
+ const delayMs = Number.isFinite(seconds2) ? seconds2 * 1e3 : Date.parse(value) - Date.now();
15258
15273
  if (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > MAX_RETRY_AFTER_MS)
15259
15274
  return void 0;
15260
15275
  return Math.round(delayMs);
@@ -17402,10 +17417,10 @@ async function readCandidateFiles(components, extraFiles = []) {
17402
17417
  async function selectCompositionPromptFiles(components, sourceFiles) {
17403
17418
  const allFiles = await readCandidateFiles(components, sourceFiles);
17404
17419
  const selectedCandidates = selectCandidateFiles(allFiles).map((c2) => ({ path: c2.path, content: c2.content }));
17405
- const capped = capCandidatesToPromptBudget(selectedCandidates);
17406
- const promptFiles = capped.kept;
17420
+ const capped3 = capCandidatesToPromptBudget(selectedCandidates);
17421
+ const promptFiles = capped3.kept;
17407
17422
  const runtimeFiles = allFiles.map((c2) => ({ path: c2.path, content: c2.content }));
17408
- 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;
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;
17409
17424
  return { promptFiles, runtimeFiles, droppedWarning };
17410
17425
  }
17411
17426
 
@@ -18157,8 +18172,9 @@ function PathValidationScreen({
18157
18172
  }
18158
18173
 
18159
18174
  // packages/experience-design-system-cli/src/tui/import/steps/04-credentials/screen.tsx
18160
- import { useRef as useRef5, useState as useState9 } from "react";
18175
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState9 } from "react";
18161
18176
  import { Box as Box14, Text as Text14, useInput as useInput11 } from "ink";
18177
+ init_debug_store();
18162
18178
 
18163
18179
  // packages/experience-design-system-cli/src/tui/shared/components/FieldForm.tsx
18164
18180
  import { useState as useState8 } from "react";
@@ -18335,6 +18351,39 @@ function FieldForm({
18335
18351
  ] });
18336
18352
  }
18337
18353
 
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
+
18338
18387
  // packages/experience-design-system-cli/src/tui/import/steps/04-credentials/logic.ts
18339
18388
  var FIELDS = ["spaceId", "environmentId", "cmaToken", "host"];
18340
18389
  function credentialsPurpose(tokensOnly) {
@@ -18349,12 +18398,36 @@ function normalize(values) {
18349
18398
  host: toConfiguredHost2(values.host) ?? DEFAULT_CONFIGURED_HOST
18350
18399
  };
18351
18400
  }
18352
- function missingField(values) {
18353
- return values.spaceId === "" || values.environmentId === "" || values.cmaToken === "";
18401
+ function missingFields(values) {
18402
+ return ["spaceId", "environmentId", "cmaToken"].filter((field) => values[field] === "");
18354
18403
  }
18355
18404
  function isUnchanged(current, initial) {
18356
18405
  return FIELDS.every((field) => current[field] === initial[field]);
18357
18406
  }
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
+ }
18358
18431
 
18359
18432
  // packages/experience-design-system-cli/src/tui/user-agent.ts
18360
18433
  init_version();
@@ -18402,7 +18475,9 @@ var MENU = [
18402
18475
  { choice: "continue", label: "Continue", description: "Check the credentials and go on" },
18403
18476
  { choice: "edit", label: "Edit", description: "Change the credentials" }
18404
18477
  ];
18478
+ var MAX_LOGGED_ATTEMPTS2 = 10;
18405
18479
  function CredentialsScreen({
18480
+ mode,
18406
18481
  onDone,
18407
18482
  onBack,
18408
18483
  initial = {},
@@ -18425,17 +18500,64 @@ function CredentialsScreen({
18425
18500
  const [focus, setFocus] = useState9(0);
18426
18501
  const [active, setActive] = useState9(0);
18427
18502
  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
+ };
18428
18533
  const submit = async () => {
18429
18534
  const credentials = normalize(values);
18430
- if (missingField(credentials)) {
18431
- setNotice({ kind: "error", text: "Space ID, environment and CMA token are all required." });
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
+ );
18432
18541
  return;
18433
18542
  }
18434
18543
  setValidating(true);
18435
18544
  const result = await validate3(credentials);
18436
18545
  setValidating(false);
18437
- if (result.ok) onDone({ skipped: false, credentials });
18438
- else setNotice({ kind: "error", text: result.error });
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 });
18439
18561
  };
18440
18562
  const choose = (choice) => {
18441
18563
  if (choice === "continue") void submit();
@@ -18444,7 +18566,7 @@ function CredentialsScreen({
18444
18566
  setBeforeEdit(values);
18445
18567
  setActive(0);
18446
18568
  setEditing(true);
18447
- } else onBack();
18569
+ } else leave();
18448
18570
  };
18449
18571
  const stopEditing = () => {
18450
18572
  setEditing(false);
@@ -18454,7 +18576,7 @@ function CredentialsScreen({
18454
18576
  if (validating) return;
18455
18577
  if (editing) {
18456
18578
  if (key.escape) {
18457
- if (!prefilled) onBack();
18579
+ if (!prefilled) leave();
18458
18580
  else {
18459
18581
  setValues(beforeEdit);
18460
18582
  setNotice(null);
@@ -18562,6 +18684,47 @@ function CredentialsScreen({
18562
18684
  }
18563
18685
 
18564
18686
  // 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
+ }
18565
18728
  function initialProgress(input) {
18566
18729
  return {
18567
18730
  scan: null,
@@ -18656,8 +18819,9 @@ function ExtractionScreen({ progress, agent }) {
18656
18819
  }
18657
18820
 
18658
18821
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-review/screen.tsx
18659
- import { useMemo as useMemo2, useState as useState10 } from "react";
18822
+ import { useEffect as useEffect9, useMemo as useMemo2, useState as useState10 } from "react";
18660
18823
  import { Box as Box15, Text as Text15, useInput as useInput12 } from "ink";
18824
+ init_debug_store();
18661
18825
 
18662
18826
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-review/load.ts
18663
18827
  import { readFileSync as readFileSync9 } from "node:fs";
@@ -18721,12 +18885,31 @@ function TokenReviewScreen({ tokensPath, onContinue, onQuit }) {
18721
18885
  const rows = loaded.ok ? loaded.rows : [];
18722
18886
  const columns = useTerminalWidth();
18723
18887
  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
+ };
18724
18903
  const move = (to) => setSelected(Math.max(0, Math.min(to, rows.length - 1)));
18725
18904
  const { start, end } = computeColumnWindow(rows.length, selected, VISIBLE_ROWS);
18726
18905
  useInput12((_input, key) => {
18727
- if (key.return) onContinue();
18728
- else if (key.escape) onQuit();
18729
- else if (key.upArrow) move(selected - 1);
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
18913
  else if (key.downArrow) move(selected + 1);
18731
18914
  else if (key.pageUp) move(selected - VISIBLE_ROWS);
18732
18915
  else if (key.pageDown) move(selected + VISIBLE_ROWS);
@@ -18790,14 +18973,15 @@ function TokenReviewScreen({ tokensPath, onContinue, onQuit }) {
18790
18973
  init_config();
18791
18974
 
18792
18975
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
18793
- import { useEffect as useEffect8, useRef as useRef6, useState as useState11 } from "react";
18976
+ init_debug_store();
18977
+ import { useEffect as useEffect10, useRef as useRef6, useState as useState11 } from "react";
18794
18978
 
18795
18979
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run.ts
18796
18980
  import { mkdir as mkdir8 } from "node:fs/promises";
18797
18981
  import { join as join20, resolve as resolve24 } from "node:path";
18798
18982
 
18799
18983
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/find-skill-path.ts
18800
- import { existsSync as existsSync9 } from "node:fs";
18984
+ import { existsSync as existsSync10 } from "node:fs";
18801
18985
  import { dirname as dirname16, join as join19, resolve as resolve22 } from "node:path";
18802
18986
  import { fileURLToPath as fileURLToPath4 } from "node:url";
18803
18987
  function findSkillPath(fileName) {
@@ -18805,7 +18989,7 @@ function findSkillPath(fileName) {
18805
18989
  let dir = thisDir;
18806
18990
  for (; ; ) {
18807
18991
  const candidate = join19(dir, "skills", fileName);
18808
- if (existsSync9(candidate)) return candidate;
18992
+ if (existsSync10(candidate)) return candidate;
18809
18993
  const parent = resolve22(dir, "..");
18810
18994
  if (parent === dir) {
18811
18995
  throw new Error(`skill file not found (looked for skills/${fileName} from ${thisDir})`);
@@ -19047,7 +19231,7 @@ async function resolveSelectionPrompt(overrides) {
19047
19231
  function useExtraction(input) {
19048
19232
  const [state2, setState] = useState11();
19049
19233
  const current = useRef6();
19050
- useEffect8(() => {
19234
+ useEffect10(() => {
19051
19235
  current.current = input;
19052
19236
  if (!input) {
19053
19237
  setState(void 0);
@@ -19060,10 +19244,23 @@ function useExtraction(input) {
19060
19244
  hasRawTokens: input.rawTokensPath !== ""
19061
19245
  })
19062
19246
  });
19247
+ let lastProgress;
19248
+ startDebugRun({
19249
+ flow: "import/extraction",
19250
+ step: "06-extraction",
19251
+ menuOption: "Extraction",
19252
+ inputs: extractionLogInputs(input)
19253
+ });
19063
19254
  void runExtraction(input, (progress) => {
19255
+ lastProgress = progress;
19064
19256
  if (current.current === input) setState({ status: "running", progress });
19065
19257
  }).then((result) => {
19066
- if (current.current === input) setState({ status: "done", 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 });
19067
19264
  });
19068
19265
  return () => {
19069
19266
  if (current.current === input) current.current = void 0;
@@ -19073,7 +19270,7 @@ function useExtraction(input) {
19073
19270
  }
19074
19271
 
19075
19272
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-tokens-only.ts
19076
- import { useEffect as useEffect9, useRef as useRef7, useState as useState12 } from "react";
19273
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState12 } from "react";
19077
19274
 
19078
19275
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run-tokens-only.ts
19079
19276
  var TOKENS_SKILL_PATH2 = findSkillPath("generate-tokens.md");
@@ -19108,7 +19305,7 @@ async function runTokensOnly(input, deps = realDeps2) {
19108
19305
  function useTokensOnly(input) {
19109
19306
  const [state2, setState] = useState12();
19110
19307
  const current = useRef7();
19111
- useEffect9(() => {
19308
+ useEffect11(() => {
19112
19309
  current.current = input;
19113
19310
  if (!input) {
19114
19311
  setState(void 0);
@@ -19126,9 +19323,37 @@ function useTokensOnly(input) {
19126
19323
  }
19127
19324
 
19128
19325
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/screen.tsx
19129
- import { useMemo as useMemo4 } from "react";
19326
+ init_debug_store();
19327
+ import { useEffect as useEffect14, useMemo as useMemo4 } from "react";
19130
19328
  import { Box as Box25, Text as Text26 } from "ink";
19131
19329
 
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
+
19132
19357
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/panels/tokens-column.tsx
19133
19358
  import { Box as Box17, Text as Text17 } from "ink";
19134
19359
  import figures2 from "figures";
@@ -20312,7 +20537,7 @@ function useImmediateInput(handler, enabled = true) {
20312
20537
 
20313
20538
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/sidebar/hooks/use-terminal-size.ts
20314
20539
  import { useStdout as useStdout2 } from "ink";
20315
- import { useEffect as useEffect10, useState as useState13 } from "react";
20540
+ import { useEffect as useEffect12, useState as useState13 } from "react";
20316
20541
  function readTerminalSize(stdout) {
20317
20542
  return {
20318
20543
  columns: stdout?.columns ?? 80,
@@ -20322,7 +20547,7 @@ function readTerminalSize(stdout) {
20322
20547
  function useTerminalSize() {
20323
20548
  const { stdout } = useStdout2();
20324
20549
  const [size, setSize] = useState13(() => readTerminalSize(stdout));
20325
- useEffect10(() => {
20550
+ useEffect12(() => {
20326
20551
  const updateSize = () => setSize(readTerminalSize(stdout));
20327
20552
  stdout?.on("resize", updateSize);
20328
20553
  updateSize();
@@ -20505,7 +20730,7 @@ function createSidebarViewsHelpSection(includeBreaking) {
20505
20730
  }
20506
20731
 
20507
20732
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
20508
- import { useEffect as useEffect11, useMemo as useMemo3, useRef as useRef9, useState as useState16 } from "react";
20733
+ import { useEffect as useEffect13, useMemo as useMemo3, useRef as useRef9, useState as useState16 } from "react";
20509
20734
 
20510
20735
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/columns.ts
20511
20736
  var TWO_COLUMN_MIN_WIDTH = 100;
@@ -21242,7 +21467,7 @@ function useScopeGate({ components, tokenCount, tokensWidth, onConfirm, onQuit }
21242
21467
  return seed;
21243
21468
  });
21244
21469
  const seededGroupsRef = useRef9(closures.size > 0 || cycleParticipants.size > 0);
21245
- useEffect11(() => {
21470
+ useEffect13(() => {
21246
21471
  if (seededGroupsRef.current) return;
21247
21472
  if (closures.size === 0 && cycleParticipants.size === 0) return;
21248
21473
  seededGroupsRef.current = true;
@@ -21333,7 +21558,7 @@ function useScopeGate({ components, tokenCount, tokensWidth, onConfirm, onQuit }
21333
21558
  entryCount: 0
21334
21559
  });
21335
21560
  const panelLayout = useMemo3(() => computePanelLayout(visibleCount), [visibleCount]);
21336
- useEffect11(() => {
21561
+ useEffect13(() => {
21337
21562
  setNav((prev) => {
21338
21563
  const maxIdx = Math.max(0, visibleRows.length - 1);
21339
21564
  const nextCursor = Math.min(prev.cursor, maxIdx);
@@ -21694,23 +21919,55 @@ var HELP_SECTIONS = [
21694
21919
  }
21695
21920
  ];
21696
21921
  function ScopeGateScreen(props) {
21697
- if (props.components.length === 0) {
21698
- 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." }) });
21699
- }
21922
+ if (props.components.length === 0) return /* @__PURE__ */ jsx29(NoComponents, {});
21700
21923
  return /* @__PURE__ */ jsx29(ScopeGateView, { ...props });
21701
21924
  }
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
+ }
21702
21941
  function ScopeGateView({ components, tokensPath, onConfirm, onQuit }) {
21703
21942
  const tokens = useMemo4(() => {
21704
21943
  const loaded = tokensPath ? loadTokenRows(tokensPath) : void 0;
21705
21944
  return loaded?.ok ? loaded.rows : [];
21706
21945
  }, [tokensPath]);
21707
21946
  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
+ }, []);
21708
21955
  const gate = useScopeGate({
21709
21956
  components,
21710
21957
  tokenCount: tokens.length,
21711
21958
  tokensWidth: longest.path + longest.value + 10,
21712
- onConfirm,
21713
- onQuit
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
+ }
21714
21971
  });
21715
21972
  const { search, graph, columnPlan, panelLayout, counters } = gate;
21716
21973
  if (gate.showHelp) {
@@ -21808,7 +22065,8 @@ function ScopeGateView({ components, tokensPath, onConfirm, onQuit }) {
21808
22065
  }
21809
22066
 
21810
22067
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate-flow.ts
21811
- import { useEffect as useEffect12, useMemo as useMemo5, useRef as useRef10, useState as useState17 } from "react";
22068
+ init_debug_store();
22069
+ import { useEffect as useEffect15, useMemo as useMemo5, useRef as useRef10, useState as useState17 } from "react";
21812
22070
 
21813
22071
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts
21814
22072
  async function checkGenerationCache(input) {
@@ -21857,7 +22115,21 @@ function useScopeGateFlow(input, deps = realDeps3) {
21857
22115
  const loaded = useMemo5(() => sessionId ? deps.load(sessionId) : void 0, [sessionId]);
21858
22116
  const cacheCheck = useRef10(void 0);
21859
22117
  const [confirmed, setConfirmed] = useState17();
21860
- useEffect12(() => {
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(() => {
21861
22133
  if (!input || !loaded?.ok || cacheCheck.current) return;
21862
22134
  cacheCheck.current = deps.checkCache(input.cache);
21863
22135
  }, [input, loaded]);
@@ -21869,6 +22141,41 @@ function useScopeGateFlow(input, deps = realDeps3) {
21869
22141
  }
21870
22142
 
21871
22143
  // 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
+ }
21872
22179
  function initialProgress2() {
21873
22180
  return { components: null, mapTokens: "idle", mapTokensEligible: null };
21874
22181
  }
@@ -21924,7 +22231,8 @@ function GenerationScreen({
21924
22231
  }
21925
22232
 
21926
22233
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts
21927
- import { useEffect as useEffect13, useRef as useRef11, useState as useState18 } from "react";
22234
+ init_debug_store();
22235
+ import { useEffect as useEffect16, useRef as useRef11, useState as useState18 } from "react";
21928
22236
 
21929
22237
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
21930
22238
  import { resolve as resolve25 } from "node:path";
@@ -22090,17 +22398,30 @@ function applyProgressEvent2(event, previous, total) {
22090
22398
  function useGeneration(input) {
22091
22399
  const [state2, setState] = useState18();
22092
22400
  const current = useRef11();
22093
- useEffect13(() => {
22401
+ useEffect16(() => {
22094
22402
  current.current = input;
22095
22403
  if (!input) {
22096
22404
  setState(void 0);
22097
22405
  return;
22098
22406
  }
22099
22407
  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
+ });
22100
22415
  void runGeneration(input, (progress) => {
22416
+ lastProgress = progress;
22101
22417
  if (current.current === input) setState({ status: "running", progress });
22102
22418
  }).then((result) => {
22103
- if (current.current === input) setState({ status: "done", 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 });
22104
22425
  });
22105
22426
  return () => {
22106
22427
  if (current.current === input) current.current = void 0;
@@ -22571,7 +22892,7 @@ function PreviewValidationErrorScreen({
22571
22892
  }
22572
22893
 
22573
22894
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/generate-review-step.tsx
22574
- import { useCallback as useCallback5, useEffect as useEffect20, useMemo as useMemo6, useRef as useRef16, useState as useState26 } from "react";
22895
+ import { useCallback as useCallback5, useEffect as useEffect24, useMemo as useMemo6, useRef as useRef17, useState as useState26 } from "react";
22575
22896
  import figures8 from "figures";
22576
22897
 
22577
22898
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/review-json-panel.ts
@@ -22832,7 +23153,7 @@ function enumerateCycleBreaks(cycle, components) {
22832
23153
  import { Box as Box32, Text as Text34 } from "ink";
22833
23154
 
22834
23155
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/components/FieldEditor.tsx
22835
- import React13, { useEffect as useEffect14, useLayoutEffect as useLayoutEffect2, useState as useState19 } from "react";
23156
+ import React13, { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useState as useState19 } from "react";
22836
23157
  import figures6 from "figures";
22837
23158
  import { Box as Box26, measureElement, Text as Text27 } from "ink";
22838
23159
 
@@ -24390,7 +24711,7 @@ function FieldEditor({
24390
24711
  }
24391
24712
  return Math.max(start + 1, end2);
24392
24713
  };
24393
- useEffect14(() => {
24714
+ useEffect17(() => {
24394
24715
  if (focusLevel === "field" || selectedRowIdx < 0) return;
24395
24716
  setListScrollStart((previous) => {
24396
24717
  if (initialFocusTarget && !initialFocusScrollApplied.current) {
@@ -25462,7 +25783,7 @@ function finalizeReviewSession(extractSessionId, components) {
25462
25783
  }
25463
25784
 
25464
25785
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-session.ts
25465
- import { useCallback as useCallback2, useEffect as useEffect16, useRef as useRef13, useState as useState21 } from "react";
25786
+ import { useCallback as useCallback2, useEffect as useEffect19, useRef as useRef13, useState as useState21 } from "react";
25466
25787
 
25467
25788
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/history.ts
25468
25789
  var DEFAULT_MAX_DEPTH = 50;
@@ -25518,7 +25839,7 @@ function createHistoryStack(seed, maxDepth = DEFAULT_MAX_DEPTH) {
25518
25839
  }
25519
25840
 
25520
25841
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-finalize-preview.ts
25521
- import { useEffect as useEffect15, useRef as useRef12, useState as useState20 } from "react";
25842
+ import { useEffect as useEffect18, useRef as useRef12, useState as useState20 } from "react";
25522
25843
 
25523
25844
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/run-live-preview.ts
25524
25845
  var TimeoutError = class extends Error {
@@ -25678,7 +25999,7 @@ function useFinalizePreview(opts) {
25678
25999
  const [scrollOffset, setScrollOffset] = useState20(0);
25679
26000
  const generationRef = useRef12(0);
25680
26001
  const acceptedKey = [...acceptedKeys].sort().join("\0");
25681
- useEffect15(() => {
26002
+ useEffect18(() => {
25682
26003
  if (!open) {
25683
26004
  setStatus("idle");
25684
26005
  setRemoved([]);
@@ -25741,7 +26062,7 @@ function useReviewSession({
25741
26062
  }));
25742
26063
  return { result, catalog };
25743
26064
  }, [loadSession, tokensPath]);
25744
- useEffect16(() => {
26065
+ useEffect19(() => {
25745
26066
  let disposed = false;
25746
26067
  void (async () => {
25747
26068
  try {
@@ -25794,7 +26115,7 @@ function useReviewSession({
25794
26115
  function useReviewMetadata({ components, selectedIdx, extractSessionId }) {
25795
26116
  const [reviewMetadata, setReviewMetadata] = useState21(null);
25796
26117
  const [componentRationale, setComponentRationale] = useState21(null);
25797
- useEffect16(() => {
26118
+ useEffect19(() => {
25798
26119
  const current = components[selectedIdx];
25799
26120
  if (!current) {
25800
26121
  setReviewMetadata(null);
@@ -25823,10 +26144,16 @@ function useReviewMetadata({ components, selectedIdx, extractSessionId }) {
25823
26144
  }, [components, extractSessionId, selectedIdx]);
25824
26145
  return { reviewMetadata, componentRationale };
25825
26146
  }
25826
- function useReviewHistory({ loading, components, createSnapshot, applySnapshot }) {
26147
+ function useReviewHistory({
26148
+ loading,
26149
+ components,
26150
+ createSnapshot,
26151
+ applySnapshot,
26152
+ onAction
26153
+ }) {
25827
26154
  const historyRef = useRef13(null);
25828
26155
  const historySeededRef = useRef13(false);
25829
- useEffect16(() => {
26156
+ useEffect19(() => {
25830
26157
  if (loading || historySeededRef.current) return;
25831
26158
  historySeededRef.current = true;
25832
26159
  historyRef.current = createHistoryStack(createSnapshot(components));
@@ -25834,14 +26161,19 @@ function useReviewHistory({ loading, components, createSnapshot, applySnapshot }
25834
26161
  const pushHistorySnapshot = (entries, label) => {
25835
26162
  if (!historyRef.current) return;
25836
26163
  historyRef.current.push(createSnapshot(entries), label);
26164
+ onAction?.(label);
25837
26165
  };
25838
26166
  const handleUndo = () => {
25839
26167
  const snapshot = historyRef.current?.undo();
25840
- if (snapshot) applySnapshot(snapshot);
26168
+ if (!snapshot) return;
26169
+ applySnapshot(snapshot);
26170
+ onAction?.("undo");
25841
26171
  };
25842
26172
  const handleRedo = () => {
25843
26173
  const snapshot = historyRef.current?.redo();
25844
- if (snapshot) applySnapshot(snapshot);
26174
+ if (!snapshot) return;
26175
+ applySnapshot(snapshot);
26176
+ onAction?.("redo");
25845
26177
  };
25846
26178
  const resetHistory = (snapshot) => {
25847
26179
  historyRef.current?.reset(snapshot);
@@ -25877,7 +26209,7 @@ function useReviewFinalize({
25877
26209
  }
25878
26210
 
25879
26211
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-editor.ts
25880
- import { useEffect as useEffect17, useRef as useRef14, useState as useState22 } from "react";
26212
+ import { useEffect as useEffect20, useRef as useRef14, useState as useState22 } from "react";
25881
26213
 
25882
26214
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/token-suggestions.ts
25883
26215
  function collectTokenSuggestions(entry, availableTokens = []) {
@@ -25930,7 +26262,7 @@ function useReviewEditor({
25930
26262
  const [tokenReviewEditSelection, setTokenReviewEditSelection] = useState22(/* @__PURE__ */ new Set());
25931
26263
  const tokenReviewSuggestedRef = useRef14(/* @__PURE__ */ new Map());
25932
26264
  const pendingGRef = useRef14(false);
25933
- useEffect17(() => {
26265
+ useEffect20(() => {
25934
26266
  setTokenReviewRow(0);
25935
26267
  setTokenReviewEditing(false);
25936
26268
  setTokenReviewEditCursor(0);
@@ -26342,7 +26674,7 @@ function handleJsonPanelInput(input, key, state2) {
26342
26674
  }
26343
26675
 
26344
26676
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-review-preview.ts
26345
- import { useCallback as useCallback4, useEffect as useEffect19, useState as useState25 } from "react";
26677
+ import { useCallback as useCallback4, useEffect as useEffect22, useState as useState25 } from "react";
26346
26678
 
26347
26679
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/preview-annotations.ts
26348
26680
  function applyPreviewAnnotations(preview, localNames) {
@@ -26377,7 +26709,7 @@ function applyPreviewAnnotations(preview, localNames) {
26377
26709
  }
26378
26710
 
26379
26711
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/use-live-preview.ts
26380
- import { useCallback as useCallback3, useEffect as useEffect18, useRef as useRef15, useState as useState24 } from "react";
26712
+ import { useCallback as useCallback3, useEffect as useEffect21, useRef as useRef15, useState as useState24 } from "react";
26381
26713
  var DEFAULT_DEBOUNCE_MS = 500;
26382
26714
  function useLivePreview(opts) {
26383
26715
  const debounceMs = opts.debounceMs ?? DEFAULT_DEBOUNCE_MS;
@@ -26388,14 +26720,14 @@ function useLivePreview(opts) {
26388
26720
  const latestRef = useRef15(0);
26389
26721
  const inflightRef = useRef15(0);
26390
26722
  const optsRef = useRef15(opts);
26391
- useEffect18(() => {
26723
+ useEffect21(() => {
26392
26724
  optsRef.current = opts;
26393
26725
  });
26394
26726
  const disabledRef = useRef15(disabled);
26395
- useEffect18(() => {
26727
+ useEffect21(() => {
26396
26728
  disabledRef.current = disabled;
26397
26729
  }, [disabled]);
26398
- useEffect18(() => {
26730
+ useEffect21(() => {
26399
26731
  return () => {
26400
26732
  if (timerRef.current) {
26401
26733
  clearTimeout(timerRef.current);
@@ -26509,13 +26841,13 @@ function useReviewPreview({
26509
26841
  deleteAllComponents
26510
26842
  });
26511
26843
  const [spinnerTick, setSpinnerTick] = useState25(0);
26512
- useEffect19(() => {
26844
+ useEffect22(() => {
26513
26845
  if (livePreviewHook.status !== "running") return;
26514
26846
  const id = setInterval(() => setSpinnerTick((tick) => tick + 1), 80);
26515
26847
  return () => clearInterval(id);
26516
26848
  }, [livePreviewHook.status]);
26517
26849
  const livePreviewSpinner = SPINNER_FRAMES[spinnerTick % SPINNER_FRAMES.length];
26518
- useEffect19(() => {
26850
+ useEffect22(() => {
26519
26851
  if (loading) return;
26520
26852
  if (!livePreview) return;
26521
26853
  if (components.length === 0) return;
@@ -26524,6 +26856,117 @@ function useReviewPreview({
26524
26856
  return { previewAnnotations, removedComponents, livePreviewHook, livePreviewSpinner };
26525
26857
  }
26526
26858
 
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
+
26527
26970
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/components/LivePreviewSummary.tsx
26528
26971
  import { Box as Box37, Text as Text39 } from "ink";
26529
26972
  import { jsx as jsx47, jsxs as jsxs37 } from "react/jsx-runtime";
@@ -26811,6 +27254,7 @@ function GenerateReviewStepView({
26811
27254
  tokensPath,
26812
27255
  onExtraLoaded: setLoadedSlotCycles
26813
27256
  });
27257
+ const reviewLog = useReviewLog({ loading, loadError, components });
26814
27258
  const [nav, setNav] = useState26({
26815
27259
  cursorRowIdx: 0,
26816
27260
  sidebarScrollOffset: 0
@@ -26828,7 +27272,7 @@ function GenerateReviewStepView({
26828
27272
  setFinalizeError
26829
27273
  } = reviewSurface;
26830
27274
  const [removedBannerCollapsed, setRemovedBannerCollapsed] = useState26(false);
26831
- const removedBannerDefaultedRef = useRef16(false);
27275
+ const removedBannerDefaultedRef = useRef17(false);
26832
27276
  const [cyclePanelScroll, setCyclePanelScroll] = useState26(0);
26833
27277
  const [cyclesCursor, setCyclesCursor] = useState26(0);
26834
27278
  const cyclePanel = useOverlayPanel({
@@ -26848,7 +27292,7 @@ function GenerateReviewStepView({
26848
27292
  const [breakCursor, setBreakCursor] = useState26(0);
26849
27293
  const [breakConfirm, setBreakConfirm] = useState26(false);
26850
27294
  const [expandedGroups, setExpandedGroups] = useState26(/* @__PURE__ */ new Set());
26851
- const seededGroupsRef = useRef16(false);
27295
+ const seededGroupsRef = useRef17(false);
26852
27296
  const {
26853
27297
  searchOpen,
26854
27298
  setSearchOpen,
@@ -26872,7 +27316,7 @@ function GenerateReviewStepView({
26872
27316
  const [pendingEditorFocus, setPendingEditorFocus] = useState26(null);
26873
27317
  const [autoRejected, setAutoRejected] = useState26([]);
26874
27318
  const [undoSnapshot, setUndoSnapshot] = useState26(null);
26875
- const autoRejectFiredRef = useRef16(false);
27319
+ const autoRejectFiredRef = useRef17(false);
26876
27320
  const [showReloadDialog, setShowReloadDialog] = useState26(false);
26877
27321
  const acceptedCountForPreview = components.filter((c2) => c2.status === "accepted").length;
26878
27322
  const { previewAnnotations, removedComponents, livePreviewHook, livePreviewSpinner } = useReviewPreview({
@@ -26904,7 +27348,10 @@ function GenerateReviewStepView({
26904
27348
  cmaToken,
26905
27349
  host,
26906
27350
  components,
26907
- onFinalize
27351
+ onFinalize: (accepted, rejected, unresolved) => {
27352
+ reviewLog.finish({ accepted, rejected, unresolved });
27353
+ onFinalize(accepted, rejected, unresolved);
27354
+ }
26908
27355
  });
26909
27356
  const recomputeCycles = (currentComponents) => {
26910
27357
  try {
@@ -26935,7 +27382,7 @@ function GenerateReviewStepView({
26935
27382
  [components]
26936
27383
  );
26937
27384
  const closures = useMemo6(() => computeAllClosures(componentGraph), [componentGraph]);
26938
- useEffect20(() => {
27385
+ useEffect24(() => {
26939
27386
  if (seededGroupsRef.current) return;
26940
27387
  if (closures.size === 0 && slotCycles.length === 0) return;
26941
27388
  seededGroupsRef.current = true;
@@ -26962,7 +27409,7 @@ function GenerateReviewStepView({
26962
27409
  suggestedBreak: cycle.edges.length > 0 ? suggestCycleBreakEdge2(cycle, cycleView.pushBlocking) : null
26963
27410
  }));
26964
27411
  }, [slotCycles, cycleView]);
26965
- useEffect20(() => {
27412
+ useEffect24(() => {
26966
27413
  const decision = computeAutoRejectDecision({
26967
27414
  loading,
26968
27415
  autoRejectFired: autoRejectFiredRef.current,
@@ -27003,10 +27450,11 @@ function GenerateReviewStepView({
27003
27450
  autoRejected,
27004
27451
  undoSnapshot
27005
27452
  }),
27006
- applySnapshot: applyHistorySnapshot
27453
+ applySnapshot: applyHistorySnapshot,
27454
+ onAction: reviewLog.record
27007
27455
  });
27008
- const autoRejectPushedRef = useRef16(false);
27009
- useEffect20(() => {
27456
+ const autoRejectPushedRef = useRef17(false);
27457
+ useEffect24(() => {
27010
27458
  if (loading) return;
27011
27459
  if (!historySeededRef.current) return;
27012
27460
  if (!autoRejectFiredRef.current) return;
@@ -27090,7 +27538,7 @@ function GenerateReviewStepView({
27090
27538
  const panelHeight = leftPanelHeight + 2;
27091
27539
  const panelContentHeight = Math.max(1, panelHeight - 3);
27092
27540
  const cycleViewportHeight = Math.max(1, panelHeight - 4);
27093
- useEffect20(() => {
27541
+ useEffect24(() => {
27094
27542
  if (selectableRowPositions.length === 0) return;
27095
27543
  const cursorInRange = selectableRowPositions.includes(cursorRowIdx);
27096
27544
  const maxScroll = Math.max(0, visibleRowsMemo.length - visibleCount);
@@ -28035,10 +28483,10 @@ function normalizePath(input) {
28035
28483
  }
28036
28484
 
28037
28485
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
28038
- import { useEffect as useEffect21, useState as useState27 } from "react";
28486
+ import { useEffect as useEffect25, useState as useState27 } from "react";
28039
28487
  function useBlinkingCursor() {
28040
28488
  const [visible, setVisible] = useState27(true);
28041
- useEffect21(() => {
28489
+ useEffect25(() => {
28042
28490
  const interval = setInterval(() => setVisible((current) => !current), 500);
28043
28491
  return () => clearInterval(interval);
28044
28492
  }, []);
@@ -28154,12 +28602,12 @@ function countedThings({ components, tokens }, counts = {}) {
28154
28602
  }
28155
28603
 
28156
28604
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-timed-spinner.tsx
28157
- import { useEffect as useEffect22, useState as useState29 } from "react";
28605
+ import { useEffect as useEffect26, useState as useState29 } from "react";
28158
28606
  import { Spinner as Spinner2 } from "@inkjs/ui";
28159
28607
  import { jsx as jsx53 } from "react/jsx-runtime";
28160
28608
  function useTimedSpinner() {
28161
28609
  const [elapsedSeconds, setElapsedSeconds] = useState29(0);
28162
- useEffect22(() => {
28610
+ useEffect26(() => {
28163
28611
  const timer = setInterval(() => setElapsedSeconds((current) => current + 1), 1e3);
28164
28612
  return () => {
28165
28613
  clearInterval(timer);
@@ -28217,7 +28665,7 @@ function PushingStep({ progress, produced, counts }) {
28217
28665
  }
28218
28666
 
28219
28667
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/WizardPreviewStep.tsx
28220
- import { useEffect as useEffect23, useState as useState30, useMemo as useMemo7 } from "react";
28668
+ import { useEffect as useEffect27, useState as useState30, useMemo as useMemo7 } from "react";
28221
28669
  import { Box as Box44, Text as Text46 } from "ink";
28222
28670
 
28223
28671
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/preview-diff.ts
@@ -28612,7 +29060,7 @@ function WizardPreviewStep({
28612
29060
  const activeLines = diffExpanded ? diffLines : summaryLines;
28613
29061
  const maxScroll = Math.max(0, activeLines.length - viewportHeight);
28614
29062
  const boundedScrollOffset = Math.min(scrollOffset, maxScroll);
28615
- useEffect23(() => {
29063
+ useEffect27(() => {
28616
29064
  setScrollOffset((previous) => Math.min(previous, maxScroll));
28617
29065
  }, [maxScroll]);
28618
29066
  useImmediateInput((input, key) => {
@@ -28702,6 +29150,194 @@ function buildRunTeaserLine(runId) {
28702
29150
  return `Run saved as ${runId}.`;
28703
29151
  }
28704
29152
 
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
+
28705
29341
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/screen.tsx
28706
29342
  import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
28707
29343
  function canEditFromPreview(cdf) {
@@ -28715,6 +29351,7 @@ function FlowScreen({
28715
29351
  generatePromptPath,
28716
29352
  onExit
28717
29353
  }) {
29354
+ useFlowLog(state2);
28718
29355
  const produced = producedOf(state2);
28719
29356
  const counts = { components: state2.generatedAcceptedCount, tokens: state2.tokenCount };
28720
29357
  const things = countedThings(produced, counts);
@@ -28830,7 +29467,7 @@ function FlowScreen({
28830
29467
  }
28831
29468
 
28832
29469
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
28833
- import { useEffect as useEffect24, useRef as useRef17, useSyncExternalStore } from "react";
29470
+ import { useEffect as useEffect29, useRef as useRef19, useSyncExternalStore } from "react";
28834
29471
 
28835
29472
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
28836
29473
  import { appendFileSync, writeFileSync } from "node:fs";
@@ -29572,7 +30209,7 @@ function createFlowController(start, deps) {
29572
30209
 
29573
30210
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
29574
30211
  function useFlow(start, options = {}) {
29575
- const controller = useRef17();
30212
+ const controller = useRef19();
29576
30213
  if (start && !controller.current) {
29577
30214
  try {
29578
30215
  startWizardLog();
@@ -29589,14 +30226,14 @@ function useFlow(start, options = {}) {
29589
30226
  (listener) => current?.subscribe(listener) ?? (() => void 0),
29590
30227
  () => current?.getState()
29591
30228
  );
29592
- useEffect24(() => {
30229
+ useEffect29(() => {
29593
30230
  if (!start) controller.current = void 0;
29594
30231
  }, [start]);
29595
30232
  return current && state2 ? { controller: current, state: state2 } : void 0;
29596
30233
  }
29597
30234
 
29598
30235
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
29599
- import { useEffect as useEffect25, useState as useState31 } from "react";
30236
+ import { useEffect as useEffect30, useState as useState31 } from "react";
29600
30237
  import { Box as Box46, Text as Text47, useInput as useInput13 } from "ink";
29601
30238
  init_debug_store();
29602
30239
 
@@ -29670,7 +30307,7 @@ function Section({ title, rows }) {
29670
30307
  }
29671
30308
  function HelpScreen({ onDone }) {
29672
30309
  const [info, setInfo] = useState31();
29673
- useEffect25(() => {
30310
+ useEffect30(() => {
29674
30311
  startDebugRun({ flow: "help", step: "01-help", menuOption: "Help", inputs: {} });
29675
30312
  void readHelpInfo().then(setInfo);
29676
30313
  }, []);
@@ -29767,43 +30404,10 @@ import { useState as useState36 } from "react";
29767
30404
  import { Box as Box51, Text as Text53, useInput as useInput17 } from "ink";
29768
30405
 
29769
30406
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentsScreen.tsx
29770
- import { useEffect as useEffect27, useRef as useRef18, useState as useState34 } from "react";
30407
+ import { useEffect as useEffect32, useRef as useRef20, useState as useState34 } from "react";
29771
30408
  import { Box as Box49, Text as Text51, useInput as useInput15 } from "ink";
29772
30409
  init_debug_store();
29773
30410
 
29774
- // packages/experience-design-system-cli/src/tui/settings/shared/debug-trail.ts
29775
- init_config();
29776
- import { existsSync as existsSync10 } from "node:fs";
29777
- function diffSnapshots(before, after) {
29778
- const names = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])];
29779
- const changed_fields = names.filter((name) => before[name] !== after[name]);
29780
- return { changed: changed_fields.length > 0, changed_fields };
29781
- }
29782
- var DEFAULT_TRAIL_LIMIT = 30;
29783
- function createTrail(limit = DEFAULT_TRAIL_LIMIT) {
29784
- const actions = [];
29785
- return {
29786
- record(action) {
29787
- actions.push(action);
29788
- if (actions.length > limit) actions.shift();
29789
- },
29790
- entries: () => [...actions]
29791
- };
29792
- }
29793
- var MIN_SECRET_LENGTH = 6;
29794
- function scrubError(error, secrets) {
29795
- let message = error instanceof Error ? error.message : String(error);
29796
- for (const secret of secrets) {
29797
- if (secret.length < MIN_SECRET_LENGTH) continue;
29798
- for (const form of /* @__PURE__ */ new Set([secret, encodeURIComponent(secret)])) message = message.split(form).join("[redacted]");
29799
- }
29800
- return message;
29801
- }
29802
- function describeSettingsFile() {
29803
- const path5 = configFilePath();
29804
- return { path: path5, eds_home_set: Boolean(process.env["EDS_HOME"]), exists: existsSync10(path5) };
29805
- }
29806
-
29807
30411
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts
29808
30412
  import { execFile as execFile2 } from "node:child_process";
29809
30413
  import { access as access5, constants } from "node:fs/promises";
@@ -29888,7 +30492,7 @@ async function testAgent(name, binary, model) {
29888
30492
  timeoutMs: PROMPT_TIMEOUT_MS
29889
30493
  })
29890
30494
  );
29891
- const seconds = ((Date.now() - started) / 1e3).toFixed(1);
30495
+ const seconds2 = ((Date.now() - started) / 1e3).toFixed(1);
29892
30496
  if (result.timedOut) {
29893
30497
  return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
29894
30498
  }
@@ -29896,7 +30500,7 @@ async function testAgent(name, binary, model) {
29896
30500
  const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
29897
30501
  return [...checks, fail3("prompt", reason)];
29898
30502
  }
29899
- return [...checks, pass("prompt", `answered in ${seconds}s`)];
30503
+ return [...checks, pass("prompt", `answered in ${seconds2}s`)];
29900
30504
  }
29901
30505
  function statusFromChecks(name, checks, savedBinary) {
29902
30506
  if (checks.length === 0) return "checking";
@@ -30096,7 +30700,7 @@ async function writeAgentConfig(config) {
30096
30700
  }
30097
30701
 
30098
30702
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentDetail.tsx
30099
- import { useEffect as useEffect26, useState as useState33 } from "react";
30703
+ import { useEffect as useEffect31, useState as useState33 } from "react";
30100
30704
  import { Box as Box48, Text as Text50 } from "ink";
30101
30705
 
30102
30706
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentStatusBadge.tsx
@@ -30159,7 +30763,7 @@ function AgentDetail({
30159
30763
  const [testing, setTesting] = useState33(false);
30160
30764
  const [notice, setNotice] = useState33(null);
30161
30765
  const [checks, setChecks] = useState33(void 0);
30162
- useEffect26(() => {
30766
+ useEffect31(() => {
30163
30767
  let active = true;
30164
30768
  setChecks(void 0);
30165
30769
  const timer = setTimeout(() => {
@@ -30244,7 +30848,7 @@ function AgentsScreen({ onDone }) {
30244
30848
  const [saving, setSaving] = useState34(false);
30245
30849
  const [loadError, setLoadError] = useState34(null);
30246
30850
  const [checks, setChecks] = useState34({});
30247
- const visit = useRef18({
30851
+ const visit = useRef20({
30248
30852
  trail: createTrail(),
30249
30853
  before: void 0,
30250
30854
  environment: void 0,
@@ -30257,7 +30861,7 @@ function AgentsScreen({ onDone }) {
30257
30861
  );
30258
30862
  }
30259
30863
  };
30260
- useEffect27(() => {
30864
+ useEffect32(() => {
30261
30865
  readAgentConfig().then((loaded) => {
30262
30866
  setConfig(loaded);
30263
30867
  inspectAll(loaded);
@@ -30434,7 +31038,7 @@ function AgentsScreen({ onDone }) {
30434
31038
  }
30435
31039
 
30436
31040
  // packages/experience-design-system-cli/src/tui/settings/configuration/project/ProjectScreen.tsx
30437
- import { useEffect as useEffect28, useRef as useRef19, useState as useState35 } from "react";
31041
+ import { useEffect as useEffect33, useRef as useRef21, useState as useState35 } from "react";
30438
31042
  import { Box as Box50, Text as Text52, useInput as useInput16 } from "ink";
30439
31043
  init_debug_store();
30440
31044
 
@@ -30492,14 +31096,14 @@ function ProjectScreen({ onDone }) {
30492
31096
  const [saving, setSaving] = useState35(false);
30493
31097
  const [notice, setNotice] = useState35(null);
30494
31098
  const [loadError, setLoadError] = useState35(null);
30495
- const visit = useRef19({
31099
+ const visit = useRef21({
30496
31100
  trail: createTrail(),
30497
31101
  before: void 0,
30498
31102
  persisted: void 0,
30499
31103
  error: ""
30500
31104
  }).current;
30501
- const scrub = (err) => scrubError(err, [config?.cmaToken ?? ""]);
30502
- useEffect28(() => {
31105
+ const scrub2 = (err) => scrubError(err, [config?.cmaToken ?? ""]);
31106
+ useEffect33(() => {
30503
31107
  readCredentials().then((cfg) => {
30504
31108
  setConfig(cfg);
30505
31109
  visit.before = snapshotOf(cfg);
@@ -30566,7 +31170,7 @@ function ProjectScreen({ onDone }) {
30566
31170
  if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
30567
31171
  setNotice({ kind: "success", text: "Project settings saved" });
30568
31172
  }).catch((err) => {
30569
- visit.error = scrub(err);
31173
+ visit.error = scrub2(err);
30570
31174
  visit.trail.record("save failed");
30571
31175
  setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
30572
31176
  }).finally(() => setSaving(false));
@@ -30651,7 +31255,7 @@ function ConfigurationScreen({ onDone }) {
30651
31255
  }
30652
31256
 
30653
31257
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
30654
- import { useEffect as useEffect29, useState as useState37 } from "react";
31258
+ import { useEffect as useEffect34, useState as useState37 } from "react";
30655
31259
  import { Box as Box52, Text as Text54, useInput as useInput18 } from "ink";
30656
31260
 
30657
31261
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
@@ -30675,7 +31279,7 @@ import { Fragment as Fragment20, jsx as jsx64, jsxs as jsxs52 } from "react/jsx-
30675
31279
  function OptInAnalyticsScreen({ onDone }) {
30676
31280
  const [loading, setLoading] = useState37(true);
30677
31281
  const [enabled, setEnabled] = useState37(true);
30678
- useEffect29(() => {
31282
+ useEffect34(() => {
30679
31283
  readAnalyticsSetting().then((setting) => {
30680
31284
  setEnabled(setting.enabled);
30681
31285
  setLoading(false);
@@ -30729,7 +31333,7 @@ function OptInAnalyticsScreen({ onDone }) {
30729
31333
  }
30730
31334
 
30731
31335
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
30732
- import { useEffect as useEffect30, useRef as useRef20, useState as useState38 } from "react";
31336
+ import { useEffect as useEffect35, useRef as useRef22, useState as useState38 } from "react";
30733
31337
  import { Box as Box53, Text as Text55, useInput as useInput19 } from "ink";
30734
31338
  init_debug_mode_store();
30735
31339
  init_debug_store();
@@ -30746,8 +31350,8 @@ function DebugModeScreen({ onDone }) {
30746
31350
  RETENTION_CHOICES[RETENTION_CHOICES.length - 1]
30747
31351
  );
30748
31352
  const [notice, setNotice] = useState38(null);
30749
- const visit = useRef20({ trail: createTrail(), before: void 0, error: "" }).current;
30750
- useEffect30(() => {
31353
+ const visit = useRef22({ trail: createTrail(), before: void 0, error: "" }).current;
31354
+ useEffect35(() => {
30751
31355
  readDebugModeSetting().then((loaded) => {
30752
31356
  setSetting(loaded);
30753
31357
  setPending(loaded.retentionDays);
@@ -30902,7 +31506,7 @@ function App({ importOptions, inkClear }) {
30902
31506
  const [flowStart, setFlowStart] = useState39();
30903
31507
  const flow = useFlow(flowStart, { beforeStepChange: inkClear });
30904
31508
  const [importDefaults, setImportDefaults] = useState39();
30905
- useEffect31(() => {
31509
+ useEffect36(() => {
30906
31510
  if (screen !== "import") {
30907
31511
  setImportDefaults(void 0);
30908
31512
  return;
@@ -30975,7 +31579,7 @@ function App({ importOptions, inkClear }) {
30975
31579
  }
30976
31580
  });
30977
31581
  };
30978
- useEffect31(() => {
31582
+ useEffect36(() => {
30979
31583
  if (!tokensOnlyRun || tokensOnly?.status !== "done" || !tokensOnly.result.ok) return;
30980
31584
  const { credentialsSkipped, input, tokens } = tokensOnlyRun;
30981
31585
  const { tokensPath, tokenSessionId, tokenCount } = tokensOnly.result;
@@ -30997,12 +31601,12 @@ function App({ importOptions, inkClear }) {
30997
31601
  }
30998
31602
  });
30999
31603
  }, [tokensOnly, tokensOnlyRun]);
31000
- useEffect31(() => {
31604
+ useEffect36(() => {
31001
31605
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
31002
31606
  setExtractionRun(void 0);
31003
31607
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
31004
31608
  }, [extraction, extractionRun]);
31005
- useEffect31(() => {
31609
+ useEffect36(() => {
31006
31610
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
31007
31611
  const { extraction: produced, input, generatePromptPath } = scopeRun;
31008
31612
  setGenerationInput({
@@ -31020,7 +31624,7 @@ function App({ importOptions, inkClear }) {
31020
31624
  ...generatePromptPath ? { generatePromptPath } : {}
31021
31625
  });
31022
31626
  }, [scopeFlow, scopeRun, generationInput]);
31023
- useEffect31(() => {
31627
+ useEffect36(() => {
31024
31628
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
31025
31629
  const { credentialsSkipped, extraction: produced, input, generatePromptPath } = scopeRun;
31026
31630
  inkClear();
@@ -31189,6 +31793,7 @@ function App({ importOptions, inkClear }) {
31189
31793
  return /* @__PURE__ */ jsx66(
31190
31794
  CredentialsScreen,
31191
31795
  {
31796
+ mode: target,
31192
31797
  initial: importDefaults.credentials,
31193
31798
  tokensOnly: target === "tokens",
31194
31799
  onBack: () => goBackFrom("credentials"),