@contentful/experience-design-system-cli 2.37.1-dev-build-daf73756.0 → 2.37.1-dev-build-a1acf318.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
@@ -837,7 +837,7 @@ async function runAgent(options) {
837
837
  promptLen: prompt.length,
838
838
  promptHead: prompt.slice(0, 500)
839
839
  });
840
- return new Promise((resolve27) => {
840
+ return new Promise((resolve28) => {
841
841
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
842
842
  const child = spawn(binary, args, {
843
843
  stdio: ["pipe", "pipe", "pipe"],
@@ -886,7 +886,7 @@ async function runAgent(options) {
886
886
  stderrLen: stderr.length,
887
887
  stderrTail: stderr.slice(-1e3)
888
888
  });
889
- resolve27(result);
889
+ resolve28(result);
890
890
  });
891
891
  });
892
892
  }
@@ -908,7 +908,7 @@ async function checkAgentAuth(agent) {
908
908
  return "not-found";
909
909
  if (agent !== "claude")
910
910
  return "ok";
911
- return new Promise((resolve27) => {
911
+ return new Promise((resolve28) => {
912
912
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
913
913
  let stdout = "";
914
914
  let done = false;
@@ -917,7 +917,7 @@ async function checkAgentAuth(agent) {
917
917
  return;
918
918
  done = true;
919
919
  child.kill("SIGTERM");
920
- resolve27("unauthenticated");
920
+ resolve28("unauthenticated");
921
921
  }, 5e3);
922
922
  child.stdout?.on("data", (chunk) => {
923
923
  stdout += chunk.toString();
@@ -928,14 +928,14 @@ async function checkAgentAuth(agent) {
928
928
  done = true;
929
929
  clearTimeout(timer);
930
930
  if (code !== 0) {
931
- resolve27("unauthenticated");
931
+ resolve28("unauthenticated");
932
932
  return;
933
933
  }
934
934
  try {
935
935
  const status = JSON.parse(stdout);
936
- resolve27(status.loggedIn ? "ok" : "unauthenticated");
936
+ resolve28(status.loggedIn ? "ok" : "unauthenticated");
937
937
  } catch {
938
- resolve27("unauthenticated");
938
+ resolve28("unauthenticated");
939
939
  }
940
940
  });
941
941
  });
@@ -945,9 +945,9 @@ async function binaryIsOnPath(binary) {
945
945
  const fs = await import("node:fs/promises");
946
946
  return fs.access(binary).then(() => true, () => false);
947
947
  }
948
- return new Promise((resolve27) => {
948
+ return new Promise((resolve28) => {
949
949
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
950
- child.on("close", (code) => resolve27(code === 0));
950
+ child.on("close", (code) => resolve28(code === 0));
951
951
  });
952
952
  }
953
953
  var init_check_agent_auth = __esm({
@@ -2329,8 +2329,8 @@ var init_debug_store = __esm({
2329
2329
  });
2330
2330
 
2331
2331
  // packages/experience-design-system-cli/app.tsx
2332
- import { join as join25 } from "node:path";
2333
- import { useEffect as useEffect26, useState as useState33 } from "react";
2332
+ import { join as join26 } from "node:path";
2333
+ import { useEffect as useEffect28, useState as useState37 } from "react";
2334
2334
 
2335
2335
  // packages/experience-design-system-cli/src/tui/home/home.tsx
2336
2336
  import { useEffect as useEffect2, useState as useState2 } from "react";
@@ -4647,30 +4647,8 @@ function applyScopeDecisions(db, sessionId, decisions) {
4647
4647
  const placeholders = accepted.map(() => "?").join(",");
4648
4648
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
4649
4649
  }
4650
- removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
4651
4650
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
4652
4651
  }
4653
- function removeSlotAllowedComponents(db, sessionId, edges, rejectedNames) {
4654
- if (edges.length === 0 && rejectedNames.length === 0)
4655
- return;
4656
- const componentId = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
4657
- const removeEdge = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND allowed_component = ?");
4658
- const removeEverywhere = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND allowed_component = ?");
4659
- db.exec("BEGIN");
4660
- try {
4661
- for (const edge of edges) {
4662
- const row = componentId.get(sessionId, edge.parent);
4663
- if (row)
4664
- removeEdge.run(sessionId, row.component_id, edge.child);
4665
- }
4666
- for (const name of rejectedNames)
4667
- removeEverywhere.run(sessionId, name);
4668
- db.exec("COMMIT");
4669
- } catch (e) {
4670
- db.exec("ROLLBACK");
4671
- throw e;
4672
- }
4673
- }
4674
4652
  function findLatestSessionForCommand(db, command) {
4675
4653
  return getLatestCompletedSessionForCommand(db, command);
4676
4654
  }
@@ -8475,10 +8453,10 @@ function extractVueSlotsFromSetup(options) {
8475
8453
  if (!body)
8476
8454
  return [];
8477
8455
  const slotsByName = /* @__PURE__ */ new Map();
8478
- for (const access6 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
8479
- if (access6.getExpression().getText() !== slotsName)
8456
+ for (const access7 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
8457
+ if (access7.getExpression().getText() !== slotsName)
8480
8458
  continue;
8481
- const slotName = access6.getName();
8459
+ const slotName = access7.getName();
8482
8460
  if (!slotsByName.has(slotName)) {
8483
8461
  slotsByName.set(slotName, {
8484
8462
  name: slotName,
@@ -13868,7 +13846,7 @@ function errorMessage(error) {
13868
13846
  return error instanceof Error && error.message ? error.message : String(error);
13869
13847
  }
13870
13848
  function defaultSleep(delayMs) {
13871
- return new Promise((resolve27) => setTimeout(resolve27, delayMs));
13849
+ return new Promise((resolve28) => setTimeout(resolve28, delayMs));
13872
13850
  }
13873
13851
 
13874
13852
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -14109,7 +14087,7 @@ var ApiClient = class {
14109
14087
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
14110
14088
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
14111
14089
  const jitter = Math.random() * baseDelay * 0.15;
14112
- await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
14090
+ await new Promise((resolve28) => setTimeout(resolve28, baseDelay + jitter));
14113
14091
  }
14114
14092
  }
14115
14093
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -14594,6 +14572,7 @@ function readTokensFromPath2(request) {
14594
14572
  init_agents();
14595
14573
  init_agent_name();
14596
14574
  init_models();
14575
+ init_binaries();
14597
14576
  init_is_agent_name();
14598
14577
  init_agent_supports_bedrock();
14599
14578
  init_check_agent_auth();
@@ -16418,7 +16397,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
16418
16397
  const message = error instanceof Error ? error.message : String(error);
16419
16398
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
16420
16399
  throw error;
16421
- await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
16400
+ await new Promise((resolve28) => setTimeout(resolve28, Math.min(250 * attempt, 2e3)));
16422
16401
  }
16423
16402
  }
16424
16403
  }
@@ -18932,7 +18911,7 @@ function buildVisibleRows(props) {
18932
18911
  if (visited.has(target)) continue;
18933
18912
  visited.add(target);
18934
18913
  const isCycleMember = cycleParticipants.has(target);
18935
- out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
18914
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
18936
18915
  queue.push({ name: target, depth: cur.depth + 1 });
18937
18916
  }
18938
18917
  }
@@ -18979,8 +18958,7 @@ function buildVisibleRows(props) {
18979
18958
  sharedSuffix,
18980
18959
  cycleChild: child.isCycleMember || void 0,
18981
18960
  itemIdx: childRec?.idx ?? -1,
18982
- rootName: key,
18983
- parentName: child.parent
18961
+ rootName: key
18984
18962
  });
18985
18963
  });
18986
18964
  }
@@ -19063,19 +19041,13 @@ function buildVisibleRows(props) {
19063
19041
  injectedChildren.push({
19064
19042
  name: target,
19065
19043
  depth: parentDepth + 1,
19066
- isCycleChild: true,
19067
- parent: parentName
19044
+ isCycleChild: true
19068
19045
  });
19069
19046
  }
19070
19047
  };
19071
19048
  emitCycleChildrenOf(root, 0);
19072
19049
  for (const c2 of closureChildren) {
19073
- injectedChildren.push({
19074
- name: c2.name,
19075
- depth: c2.depth,
19076
- isCycleChild: false,
19077
- parent: c2.path[c2.path.length - 2] ?? root
19078
- });
19050
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
19079
19051
  emitCycleChildrenOf(c2.name, c2.depth);
19080
19052
  }
19081
19053
  const isLastAtDepth = (idx) => {
@@ -19109,8 +19081,7 @@ function buildVisibleRows(props) {
19109
19081
  sharedSuffix,
19110
19082
  cycleChild: child.isCycleChild || void 0,
19111
19083
  itemIdx: childRec?.idx ?? -1,
19112
- rootName: root,
19113
- parentName: child.parent
19084
+ rootName: root
19114
19085
  });
19115
19086
  });
19116
19087
  }
@@ -19268,7 +19239,7 @@ function GroupedSidebar(props) {
19268
19239
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
19269
19240
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
19270
19241
  const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
19271
- const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "empty" || row.kind === "cycle");
19242
+ const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "cycle");
19272
19243
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
19273
19244
  const isCycleRow = row.kind === "cycle";
19274
19245
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -19298,7 +19269,7 @@ function GroupedSidebar(props) {
19298
19269
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
19299
19270
  bold: isSelected || labelStyle.bold,
19300
19271
  inverse: false,
19301
- underline: isSelected && focused,
19272
+ underline: isSelected && !focused,
19302
19273
  wrap: wrapLabels ? "wrap" : "truncate",
19303
19274
  children: [
19304
19275
  " ",
@@ -19957,7 +19928,6 @@ function resolveKey(mode, key, ctx) {
19957
19928
  function resolveMain(key, ctx) {
19958
19929
  const { input } = key;
19959
19930
  const inMain = ctx.focusedColumn === "main";
19960
- if (key.ctrl && input === "z") return { type: "undo" };
19961
19931
  if (input === "q" || key.escape) {
19962
19932
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
19963
19933
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -20227,42 +20197,21 @@ function rejectNeedsConfirmation(graph, name, state2) {
20227
20197
  const ancestors = toReject.filter((n) => n !== name);
20228
20198
  return ancestors.length + toDeselect.length >= 2;
20229
20199
  }
20230
- function removeSlotChild(components, edge) {
20231
- return components.map(
20232
- (component) => component.name === edge.parent ? {
20233
- ...component,
20234
- slots: component.slots?.map((slot) => ({
20235
- ...slot,
20236
- allowedComponents: slot.allowedComponents.filter((name) => name !== edge.child)
20237
- }))
20238
- } : component
20239
- );
20240
- }
20241
- function withoutSlotChildren(components, removedEdges) {
20242
- return removedEdges.reduce(removeSlotChild, components);
20243
- }
20244
- function partitionDecisions(components, state2, removedEdges) {
20200
+ function partitionDecisions(components, state2) {
20245
20201
  const accepted = [];
20246
20202
  const rejected = [];
20247
20203
  for (const c2 of components) {
20248
20204
  if (state2.get(c2.name) === "accepted") accepted.push(c2.name);
20249
20205
  else rejected.push(c2.name);
20250
20206
  }
20251
- const rejectedNames = new Set(rejected);
20252
- const excludedSlotEdges = removedEdges.filter((e) => !rejectedNames.has(e.parent) && !rejectedNames.has(e.child));
20253
- return { accepted, rejected, excludedSlotEdges };
20207
+ return { accepted, rejected };
20254
20208
  }
20255
20209
 
20256
20210
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
20257
- function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20211
+ function useScopeGate({ components, onConfirm, onQuit }) {
20258
20212
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
20259
20213
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
20260
20214
  const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
20261
- const [removedEdges, setRemovedEdges] = useState12([]);
20262
- const components = useMemo2(
20263
- () => withoutSlotChildren(loadedComponents, removedEdges),
20264
- [loadedComponents, removedEdges]
20265
- );
20266
20215
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
20267
20216
  const [focusedColumn, setFocusedColumn] = useState12("main");
20268
20217
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -20435,14 +20384,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20435
20384
  return void 0;
20436
20385
  }
20437
20386
  };
20438
- const focusedNestedEdge = () => {
20439
- const row = visibleRows[safeCursor];
20440
- if (row?.kind !== "group-child" || !row.parentName || row.itemIdx < 0) return void 0;
20441
- const child = groupedItems[row.itemIdx]?.key;
20442
- return child ? { parent: row.parentName, child } : void 0;
20443
- };
20444
- const removeFromParentSlot = (edge) => setRemovedEdges((edges) => [...edges, edge]);
20445
- const undoSlotRemoval = () => setRemovedEdges((edges) => edges.slice(0, -1));
20446
20387
  const jumpCursorTo = (name) => {
20447
20388
  let idx = -1;
20448
20389
  for (let i = 0; i < visibleRows.length; i++) {
@@ -20542,7 +20483,7 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20542
20483
  onQuit();
20543
20484
  return;
20544
20485
  case "confirm":
20545
- onConfirm(partitionDecisions(components, decisions, removedEdges));
20486
+ onConfirm(partitionDecisions(components, decisions));
20546
20487
  return;
20547
20488
  case "close-help":
20548
20489
  setShowHelp(false);
@@ -20595,11 +20536,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20595
20536
  return;
20596
20537
  }
20597
20538
  case "reject": {
20598
- const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
20599
- if (edge) {
20600
- removeFromParentSlot(edge);
20601
- return;
20602
- }
20603
20539
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
20604
20540
  if (key) requestReject(key);
20605
20541
  return;
@@ -20607,9 +20543,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20607
20543
  case "toggle-all":
20608
20544
  decide({ type: "toggle-all" });
20609
20545
  return;
20610
- case "undo":
20611
- undoSlotRemoval();
20612
- return;
20613
20546
  case "accept-unflagged":
20614
20547
  decide({ type: "accept-unflagged" });
20615
20548
  return;
@@ -23242,8 +23175,8 @@ function FieldEditor({
23242
23175
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE.warning, children: [
23243
23176
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE.warning, children: "FIELD EDITOR \u2014 no fields" }),
23244
23177
  /* @__PURE__ */ jsx27(Text23, { color: PALETTE.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify." }),
23245
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "There is nothing to edit here." }),
23246
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: active ? "[Esc] go back to the list" : "In the list: [r] reject this component \xB7 [a] accept it" })
23178
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "You can add fields manually below or reject this component." }),
23179
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "Enter to save \xB7 Esc to discard" })
23247
23180
  ] });
23248
23181
  }
23249
23182
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -23458,7 +23391,7 @@ function FieldEditor({
23458
23391
  children: [
23459
23392
  hasEmptyProperties && /* @__PURE__ */ jsx27(Text23, { color: PALETTE.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify. Reject this component or add fields manually." }),
23460
23393
  header,
23461
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
23394
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
23462
23395
  PropRow,
23463
23396
  {
23464
23397
  prop: currentProp,
@@ -24375,7 +24308,6 @@ function finalizeReviewSession(extractSessionId, components) {
24375
24308
  db.exec("ROLLBACK");
24376
24309
  throw error;
24377
24310
  }
24378
- removeSlotAllowedComponents(db, extractSessionId, [], toReject);
24379
24311
  } finally {
24380
24312
  db.close();
24381
24313
  }
@@ -26107,50 +26039,33 @@ function GenerateReviewStepView({
26107
26039
  const cycle = cycleRows[cyclesCursor];
26108
26040
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
26109
26041
  }, [cycleRows, cyclesCursor, components]);
26110
- const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
26042
+ const handleBreakEdge = (edge) => {
26043
+ const target = components.find((component) => component.key === edge.fromComponent);
26044
+ const slot = target?.entry.$slots?.[edge.slotName];
26045
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
26046
+ const nextEntry = {
26047
+ ...target.entry,
26048
+ $slots: {
26049
+ ...target.entry.$slots,
26050
+ [edge.slotName]: {
26051
+ ...slot,
26052
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
26053
+ }
26054
+ }
26055
+ };
26111
26056
  const next = components.map(
26112
- (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
26057
+ (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
26113
26058
  );
26114
26059
  setComponents(next);
26115
26060
  const db = openPipelineDb();
26116
26061
  try {
26117
- storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
26062
+ storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
26118
26063
  } finally {
26119
26064
  db.close();
26120
26065
  }
26121
26066
  recomputeCycles(next);
26122
26067
  livePreviewHook.trigger();
26123
- pushHistorySnapshot(next, historyLabel);
26124
- };
26125
- const handleBreakEdge = (edge) => {
26126
- const target = components.find((component) => component.key === edge.fromComponent);
26127
- const slot = target?.entry.$slots?.[edge.slotName];
26128
- if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
26129
- saveSlotChange(
26130
- target.key,
26131
- {
26132
- ...target.entry,
26133
- $slots: {
26134
- ...target.entry.$slots,
26135
- [edge.slotName]: {
26136
- ...slot,
26137
- $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
26138
- }
26139
- }
26140
- },
26141
- "break-cycle-edge"
26142
- );
26143
- };
26144
- const handleRemoveSlotChild = (parentKey, childKey) => {
26145
- const parent = components.find((component) => component.key === parentKey);
26146
- if (!parent?.entry.$slots) return;
26147
- const slots = Object.fromEntries(
26148
- Object.entries(parent.entry.$slots).map(([slotName, slot]) => [
26149
- slotName,
26150
- Array.isArray(slot.$allowedComponents) ? { ...slot, $allowedComponents: slot.$allowedComponents.filter((value) => value !== childKey) } : slot
26151
- ])
26152
- );
26153
- saveSlotChange(parentKey, { ...parent.entry, $slots: slots }, "remove-slot-child");
26068
+ pushHistorySnapshot(next, "break-cycle-edge");
26154
26069
  };
26155
26070
  const handleRejectComponent = (key) => {
26156
26071
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -26480,11 +26395,6 @@ function GenerateReviewStepView({
26480
26395
  if (input === "r") {
26481
26396
  const current = components[selectedIdx];
26482
26397
  if (!current) return;
26483
- const row = visibleRowsMemo[cursorRowIdx];
26484
- if (row?.kind === "group-child" && row.parentName) {
26485
- handleRemoveSlotChild(row.parentName, current.key);
26486
- return;
26487
- }
26488
26398
  handleRejectComponent(current.key);
26489
26399
  return;
26490
26400
  }
@@ -28121,7 +28031,7 @@ var realSaveDeps = () => ({
28121
28031
  writeFile: (path5, contents) => writeFile7(path5, contents),
28122
28032
  appendRun,
28123
28033
  buildSourceFingerprint,
28124
- sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
28034
+ sleep: (ms) => new Promise((resolve28) => setTimeout(resolve28, ms)),
28125
28035
  warn: (message) => process.stderr.write(message)
28126
28036
  });
28127
28037
  async function runPrintFiles(input, deps, onPatch) {
@@ -28511,12 +28421,44 @@ init_config();
28511
28421
  init_debug_store();
28512
28422
  init_debug_mode_store();
28513
28423
  init_version();
28424
+
28425
+ // packages/experience-design-system-cli/src/tui/help/file-locations.ts
28426
+ import { join as join25, resolve as resolve27 } from "node:path";
28427
+ function describeFileLocations({
28428
+ contentfulBaseDir,
28429
+ debugModeEnabled,
28430
+ currentSessionDir: currentSessionDir2
28431
+ }) {
28432
+ if (!debugModeEnabled) {
28433
+ return {
28434
+ debugLogs: "none while Debug Mode is off",
28435
+ importFiles: `${join25("<project>", ".contentful")}/ (tokens.json, components.json)`
28436
+ };
28437
+ }
28438
+ const base = contentfulBaseDir ? resolve27(contentfulBaseDir) : "<project>";
28439
+ const session = currentSessionDir2 ?? join25(base, ".contentful", "<date>-session-<n>");
28440
+ return {
28441
+ debugLogs: join25(session, "debug"),
28442
+ importFiles: `${join25(session, "dsi-import-<n>")}/ (tokens.json, components.json)`
28443
+ };
28444
+ }
28445
+
28446
+ // packages/experience-design-system-cli/src/tui/help/help-info.ts
28514
28447
  async function readHelpInfo() {
28515
- const debugMode = await readDebugModeSetting();
28448
+ const [debugMode, settings] = await Promise.all([readDebugModeSetting(), readSettings2()]);
28449
+ const base = settings["contentfulBaseDir"];
28450
+ const locations = describeFileLocations({
28451
+ contentfulBaseDir: typeof base === "string" ? base : "",
28452
+ debugModeEnabled: debugMode.enabled,
28453
+ currentSessionDir: currentSessionDir()
28454
+ });
28516
28455
  return {
28517
28456
  storage: [
28518
28457
  { label: "Config folder", value: configRoot2() },
28519
- { label: "Settings file", value: configFilePath2() }
28458
+ { label: "Settings file", value: configFilePath2() },
28459
+ { label: "Agent settings", value: `${configFilePath2()} (keys: agent, agentModel, agents)` },
28460
+ { label: "Debug logs", value: locations.debugLogs },
28461
+ { label: "Import files", value: locations.importFiles }
28520
28462
  ],
28521
28463
  troubleshooting: [
28522
28464
  { label: "CLI version", value: readPackageVersion() },
@@ -28537,7 +28479,7 @@ function Section({ title, rows }) {
28537
28479
  return /* @__PURE__ */ jsxs43(Box42, { flexDirection: "column", children: [
28538
28480
  /* @__PURE__ */ jsx53(Text44, { bold: true, color: PALETTE.accent, children: title }),
28539
28481
  rows.map((row) => /* @__PURE__ */ jsxs43(Box42, { gap: 1, children: [
28540
- /* @__PURE__ */ jsx53(Box42, { width: 14, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
28482
+ /* @__PURE__ */ jsx53(Box42, { width: 16, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
28541
28483
  /* @__PURE__ */ jsx53(Text44, { children: row.value })
28542
28484
  ] }, row.label))
28543
28485
  ] });
@@ -28637,200 +28579,757 @@ function SettingsScreen({
28637
28579
  }
28638
28580
 
28639
28581
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28640
- import { useEffect as useEffect22, useState as useState29 } from "react";
28641
- import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28642
- import TextInput4 from "ink-text-input";
28582
+ import { useState as useState33 } from "react";
28583
+ import { Box as Box48, Text as Text51, useInput as useInput14 } from "ink";
28584
+
28585
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
28586
+ import { useEffect as useEffect23, useState as useState30 } from "react";
28587
+ import { Box as Box45, Text as Text48, useInput as useInput12 } from "ink";
28588
+ init_debug_store();
28643
28589
 
28644
28590
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28645
28591
  init_config();
28646
28592
  var readV1Store = readSettings2;
28647
28593
  var writeV1Store = writeSettings2;
28648
28594
 
28649
- // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
28650
- async function readCredentials() {
28595
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-store.ts
28596
+ var DEFAULT_AGENT3 = "claude";
28597
+ var AGENT_LABELS = {
28598
+ claude: "Claude Code",
28599
+ codex: "OpenAI Codex",
28600
+ opencode: "OpenCode",
28601
+ cursor: "Cursor",
28602
+ copilot: "GitHub Copilot"
28603
+ };
28604
+ var AGENT_HINTS = {
28605
+ claude: "claude",
28606
+ codex: "codex",
28607
+ opencode: "opencode",
28608
+ cursor: "cursor-agent",
28609
+ copilot: "copilot"
28610
+ };
28611
+ var asString = (value) => typeof value === "string" ? value : "";
28612
+ function emptyAgents() {
28613
+ return Object.fromEntries(AGENT_NAMES.map((name) => [name, { model: "", binary: "" }]));
28614
+ }
28615
+ async function readAgentConfig() {
28651
28616
  const store = await readV1Store();
28652
- return {
28653
- spaceId: store.spaceId || "",
28654
- environmentId: store.environmentId || "",
28655
- cmaToken: store.cmaToken || "",
28656
- host: store.host || "",
28657
- defaultComponentDir: store.defaultComponentDir || "",
28658
- defaultTokenFile: store.defaultTokenFile || "",
28659
- contentfulBaseDir: store.contentfulBaseDir || ""
28660
- };
28617
+ const stored = asString(store["agent"]);
28618
+ const defaultAgent = isAgentName(stored) ? stored : DEFAULT_AGENT3;
28619
+ const agents = emptyAgents();
28620
+ const saved = store["agents"];
28621
+ if (saved && typeof saved === "object") {
28622
+ for (const name of AGENT_NAMES) {
28623
+ const entry = saved[name];
28624
+ if (entry && typeof entry === "object") {
28625
+ const fields = entry;
28626
+ agents[name] = { model: asString(fields["model"]), binary: asString(fields["binary"]) };
28627
+ }
28628
+ }
28629
+ }
28630
+ const legacyModel = asString(store["agentModel"]);
28631
+ if (legacyModel && !agents[defaultAgent].model)
28632
+ agents[defaultAgent] = { ...agents[defaultAgent], model: legacyModel };
28633
+ return { defaultAgent, agents };
28661
28634
  }
28662
- async function writeCredentials(config) {
28635
+ async function writeAgentConfig(config) {
28663
28636
  const existing = await readV1Store();
28664
- const merged = {
28665
- ...existing,
28666
- ...config
28667
- };
28668
- Object.keys(merged).forEach((k) => {
28669
- if (!merged[k]) delete merged[k];
28670
- });
28637
+ const merged = { ...existing };
28638
+ const agents = {};
28639
+ for (const name of AGENT_NAMES) {
28640
+ const model = config.agents[name].model.trim();
28641
+ const binary = config.agents[name].binary.trim();
28642
+ if (model || binary) agents[name] = { ...model ? { model } : {}, ...binary ? { binary } : {} };
28643
+ }
28644
+ merged["agent"] = config.defaultAgent;
28645
+ const defaultModel = agents[config.defaultAgent]?.model;
28646
+ if (defaultModel) merged["agentModel"] = defaultModel;
28647
+ else delete merged["agentModel"];
28648
+ if (Object.keys(agents).length > 0) merged["agents"] = agents;
28649
+ else delete merged["agents"];
28671
28650
  await writeV1Store(merged);
28672
28651
  }
28673
28652
 
28674
- // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28675
- init_debug_store();
28676
- import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28677
- var FIELD_ORDER = [
28678
- "spaceId",
28679
- "environmentId",
28680
- "cmaToken",
28681
- "host",
28682
- "defaultComponentDir",
28683
- "defaultTokenFile",
28684
- "contentfulBaseDir"
28685
- ];
28686
- function debugFields(config) {
28687
- return {
28688
- space_id: config?.spaceId ?? "",
28689
- environment_id: config?.environmentId ?? "",
28690
- cma_token: config?.cmaToken ?? "",
28691
- host: config?.host ?? "",
28692
- default_component_dir: config?.defaultComponentDir ?? "",
28693
- default_token_file: config?.defaultTokenFile ?? "",
28694
- contentful_base_dir: config?.contentfulBaseDir ?? ""
28695
- };
28653
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-status.ts
28654
+ import { execFile as execFile2 } from "node:child_process";
28655
+ import { access as access6, constants } from "node:fs/promises";
28656
+ var VERSION_TIMEOUT_MS = 5e3;
28657
+ var PROMPT_TIMEOUT_MS = 6e4;
28658
+ var TEST_PROMPT = "Reply with the single word: ok";
28659
+ var INSTALL_HINTS = {
28660
+ claude: "npm install -g @anthropic-ai/claude-code",
28661
+ codex: "npm install -g @openai/codex",
28662
+ opencode: "npm install -g opencode-ai",
28663
+ cursor: "install Cursor\u2019s `cursor-agent` command",
28664
+ copilot: "npm install -g @github/copilot"
28665
+ };
28666
+ var LOGIN_HINTS = {
28667
+ claude: "run `claude login`",
28668
+ codex: "set OPENAI_API_KEY, or sign in with a ChatGPT account",
28669
+ opencode: "run `opencode auth`",
28670
+ cursor: "sign in from Cursor",
28671
+ copilot: "run `copilot` and sign in"
28672
+ };
28673
+ function effectiveBinary(name, savedBinary) {
28674
+ return savedBinary.trim() || AGENT_BINARIES[name];
28675
+ }
28676
+ function defaultModelLabel(name) {
28677
+ const model = DEFAULT_MODELS[name];
28678
+ return model && model !== "Auto" ? model : "chosen by the agent";
28679
+ }
28680
+ var fail3 = (step, detail) => ({ step, ok: false, detail });
28681
+ var pass = (step, detail) => ({ step, ok: true, detail });
28682
+ function resolveOnPath(binary) {
28683
+ if (binary.includes("/")) {
28684
+ return access6(binary, constants.X_OK).then(
28685
+ () => binary,
28686
+ () => null
28687
+ );
28688
+ }
28689
+ return new Promise((resolve28) => {
28690
+ execFile2(
28691
+ process.platform === "win32" ? "where" : "which",
28692
+ [binary],
28693
+ (error, stdout) => resolve28(error ? null : stdout.split("\n")[0]?.trim() ?? null)
28694
+ );
28695
+ });
28696
28696
  }
28697
- var FIELD_LABELS = {
28698
- spaceId: "Space ID",
28699
- environmentId: "Environment ID",
28700
- cmaToken: "CMA Token",
28701
- host: "API Host",
28702
- defaultComponentDir: "Default component directory",
28703
- defaultTokenFile: "Default token file",
28704
- contentfulBaseDir: "Root Project Directory"
28697
+ function readVersion(binary) {
28698
+ return new Promise((resolve28) => {
28699
+ execFile2(binary, ["--version"], { timeout: VERSION_TIMEOUT_MS }, (error, stdout) => {
28700
+ const line = stdout.split("\n")[0]?.trim() ?? "";
28701
+ if (!error && line) resolve28(pass("version", line));
28702
+ else resolve28(fail3("version", "runs, but did not report a version"));
28703
+ });
28704
+ });
28705
+ }
28706
+ async function inspectAgent(name, binary) {
28707
+ const target = effectiveBinary(name, binary);
28708
+ const found = await resolveOnPath(target);
28709
+ if (!found) return [fail3("path", `\`${target}\` was not found or is not executable`)];
28710
+ const checks = [pass("path", found)];
28711
+ checks.push(await readVersion(found));
28712
+ if (name === "claude") {
28713
+ const auth = await withBinaryEnv(name, found, () => checkAgentAuth(name));
28714
+ checks.push(
28715
+ auth === "ok" ? pass("login", "logged in") : fail3("login", auth === "not-found" ? "binary not found" : `not logged in: ${LOGIN_HINTS.claude}`)
28716
+ );
28717
+ }
28718
+ return checks;
28719
+ }
28720
+ async function testAgent(name, binary, model) {
28721
+ const checks = await inspectAgent(name, binary);
28722
+ if (!checks.every((check) => check.step === "version" || check.ok)) return checks;
28723
+ const target = effectiveBinary(name, binary);
28724
+ const found = await resolveOnPath(target) ?? target;
28725
+ const started = Date.now();
28726
+ const result = await withBinaryEnv(
28727
+ name,
28728
+ found,
28729
+ () => createLocalCliAgentInvoker().invoke({
28730
+ agent: name,
28731
+ ...model.trim() ? { model: model.trim() } : {},
28732
+ prompt: TEST_PROMPT,
28733
+ timeoutMs: PROMPT_TIMEOUT_MS
28734
+ })
28735
+ );
28736
+ const seconds = ((Date.now() - started) / 1e3).toFixed(1);
28737
+ if (result.timedOut) {
28738
+ return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
28739
+ }
28740
+ if (result.exitCode !== 0) {
28741
+ const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
28742
+ return [...checks, fail3("prompt", reason)];
28743
+ }
28744
+ return [...checks, pass("prompt", `answered in ${seconds}s`)];
28745
+ }
28746
+ function statusFromChecks(name, checks, savedBinary) {
28747
+ if (checks.length === 0) return "checking";
28748
+ if (checks.some((check) => check.step === "path" && !check.ok)) {
28749
+ return savedBinary.trim() ? "not-found" : "not-configured";
28750
+ }
28751
+ const prompt = checks.find((check) => check.step === "prompt");
28752
+ if (prompt) {
28753
+ if (prompt.ok) return "ready";
28754
+ return prompt.timedOut ? "timed-out" : "test-failed";
28755
+ }
28756
+ const login = checks.find((check) => check.step === "login");
28757
+ if (login) return login.ok ? "ready" : "not-logged-in";
28758
+ return name === "claude" ? "ready" : "unknown";
28759
+ }
28760
+ function setupHint(name, status) {
28761
+ if (status === "not-configured") return `${INSTALL_HINTS[name]}, or set its command path in settings`;
28762
+ if (status === "not-found") return `${INSTALL_HINTS[name]}, or correct the command path in settings`;
28763
+ if (status === "not-logged-in") return LOGIN_HINTS[name];
28764
+ if (status === "test-failed") return `read the test message; if it is a login problem, ${LOGIN_HINTS[name]}`;
28765
+ if (status === "timed-out") return "it may be slow or waiting for input; run the test again, or try it in a terminal";
28766
+ if (status === "unknown") return "run a full test to confirm it is logged in";
28767
+ return "";
28768
+ }
28769
+ function testOutcome(checks) {
28770
+ const prompt = checks?.find((check) => check.step === "prompt");
28771
+ if (!prompt) return void 0;
28772
+ if (prompt.ok) return { ok: true, text: `Test passed: ${prompt.detail}` };
28773
+ if (prompt.timedOut) return { ok: false, text: `Test timed out: ${prompt.detail}` };
28774
+ return { ok: false, text: `Test failed: ${prompt.detail}` };
28775
+ }
28776
+ var LIST_STATUS = {
28777
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
28778
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
28779
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
28780
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
28781
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
28782
+ "test-failed": { symbol: "\u2717", text: "test failed", tone: "bad" },
28783
+ "timed-out": { symbol: "\u2717", text: "test timed out", tone: "bad" },
28784
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
28705
28785
  };
28706
- var FIELD_HINTS = {
28707
- contentfulBaseDir: "(where .contentful goes)"
28786
+ function modelLine(name, savedModel) {
28787
+ const model = savedModel.trim();
28788
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
28789
+ }
28790
+ function panelRows(name, checks, settings) {
28791
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
28792
+ const status = statusFromChecks(name, checks, settings.binary);
28793
+ const path5 = checks.find((check) => check.step === "path");
28794
+ if (!path5?.ok) {
28795
+ const rows2 = [
28796
+ {
28797
+ label: "Command",
28798
+ value: settings.binary.trim() ? path5?.detail ?? "not found" : "not found on your PATH",
28799
+ tone: settings.binary.trim() ? "bad" : "muted"
28800
+ }
28801
+ ];
28802
+ const hint2 = setupHint(name, status);
28803
+ if (hint2) rows2.push({ label: "Setup", value: hint2, tone: "muted" });
28804
+ return rows2;
28805
+ }
28806
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
28807
+ const version = checks.find((check) => check.step === "version");
28808
+ if (version?.ok) rows.push({ label: "Version", value: version.detail, tone: "ok" });
28809
+ rows.push({ label: "Model", value: modelLine(name, settings.model), tone: "muted" });
28810
+ const hint = setupHint(name, status);
28811
+ if (hint) rows.push({ label: "Setup", value: hint, tone: "muted" });
28812
+ return rows;
28813
+ }
28814
+ function statusRows(_name, checks, savedBinary) {
28815
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
28816
+ const find = (step) => checks.find((check) => check.step === step);
28817
+ const path5 = find("path");
28818
+ if (!path5?.ok) {
28819
+ if (savedBinary.trim()) return [{ label: "Command", value: path5?.detail ?? "not found", tone: "bad" }];
28820
+ return [{ label: "Command", value: "not configured (not on the PATH)", tone: "muted" }];
28821
+ }
28822
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
28823
+ const version = find("version");
28824
+ if (version) {
28825
+ rows.push({
28826
+ label: "Version",
28827
+ value: version.ok ? version.detail : "could not be read",
28828
+ tone: version.ok ? "ok" : "muted"
28829
+ });
28830
+ }
28831
+ const login = find("login");
28832
+ const prompt = find("prompt");
28833
+ if (login) {
28834
+ rows.push({ label: "Login", value: login.detail, tone: login.ok ? "ok" : "bad" });
28835
+ } else if (prompt) {
28836
+ rows.push({
28837
+ label: "Login",
28838
+ value: prompt.ok ? "confirmed by the test" : prompt.timedOut ? "unknown (the test timed out)" : "see the test result",
28839
+ tone: prompt.ok ? "ok" : prompt.timedOut ? "muted" : "bad"
28840
+ });
28841
+ } else {
28842
+ rows.push({ label: "Login", value: "not checked (use Run test)", tone: "muted" });
28843
+ }
28844
+ if (prompt) rows.push({ label: "Test", value: prompt.detail, tone: prompt.ok ? "ok" : "bad" });
28845
+ return rows;
28846
+ }
28847
+ async function withBinaryEnv(name, binary, run) {
28848
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
28849
+ const previous = process.env[key];
28850
+ process.env[key] = binary;
28851
+ try {
28852
+ return await run();
28853
+ } finally {
28854
+ if (previous === void 0) delete process.env[key];
28855
+ else process.env[key] = previous;
28856
+ }
28857
+ }
28858
+
28859
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28860
+ import { useEffect as useEffect22, useState as useState29 } from "react";
28861
+ import { Box as Box44, Text as Text47, useInput as useInput11 } from "ink";
28862
+ import TextInput4 from "ink-text-input";
28863
+
28864
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
28865
+ import { Text as Text46 } from "ink";
28866
+ import { jsx as jsx55 } from "react/jsx-runtime";
28867
+ var TONE_COLOR = {
28868
+ ok: PALETTE.success,
28869
+ bad: PALETTE.error,
28870
+ muted: PALETTE.muted
28708
28871
  };
28709
- var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28710
- function ConfigurationScreen({ onDone }) {
28711
- const [stage, setStage] = useState29("loading");
28712
- const [config, setConfig] = useState29(null);
28713
- const [activeField, setActiveField] = useState29("spaceId");
28714
- const [notice, setNotice] = useState29(null);
28715
- const [lastSaved, setLastSaved] = useState29(null);
28872
+ function AgentStatusBadge({
28873
+ name,
28874
+ checks,
28875
+ binary
28876
+ }) {
28877
+ const { symbol, text, tone } = LIST_STATUS[checks ? statusFromChecks(name, checks, binary) : "checking"];
28878
+ return /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[tone], children: `${symbol} ${text}` });
28879
+ }
28880
+
28881
+ // packages/experience-design-system-cli/src/tui/settings/agents/apply-binary-overrides.ts
28882
+ var shellValues = /* @__PURE__ */ new Map();
28883
+ function applyBinaryOverrides(config) {
28884
+ for (const name of AGENT_NAMES) {
28885
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
28886
+ const binary = config.agents[name].binary.trim();
28887
+ if (binary) {
28888
+ if (!shellValues.has(key)) shellValues.set(key, process.env[key]);
28889
+ process.env[key] = binary;
28890
+ } else if (shellValues.has(key)) {
28891
+ const shellValue = shellValues.get(key);
28892
+ if (shellValue === void 0) delete process.env[key];
28893
+ else process.env[key] = shellValue;
28894
+ shellValues.delete(key);
28895
+ }
28896
+ }
28897
+ }
28898
+
28899
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28900
+ import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
28901
+ var FOCUS_ORDER = ["binary", "model", "test"];
28902
+ var FIELDS2 = ["binary", "model"];
28903
+ var FIELD_LABEL = { binary: "Command path", model: "Model" };
28904
+ var LABEL_WIDTH = "Command path".length;
28905
+ var LABEL_GAP = 2;
28906
+ var POINTER_WIDTH = 2;
28907
+ var fieldHint = (name, field) => field === "binary" ? `(empty: \`${AGENT_HINTS[name]}\` from the PATH)` : `(empty: ${defaultModelLabel(name)})`;
28908
+ function Row2({
28909
+ pointer,
28910
+ label,
28911
+ labelProps,
28912
+ children
28913
+ }) {
28914
+ return /* @__PURE__ */ jsxs45(Box44, { children: [
28915
+ /* @__PURE__ */ jsx56(Box44, { width: POINTER_WIDTH, flexShrink: 0, children: pointer }),
28916
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH + LABEL_GAP, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, ...labelProps, children: label }) }),
28917
+ children
28918
+ ] });
28919
+ }
28920
+ function Section2({
28921
+ title,
28922
+ note,
28923
+ interactive = false,
28924
+ children
28925
+ }) {
28926
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", marginTop: 1, children: [
28927
+ /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28928
+ /* @__PURE__ */ jsx56(Text47, { bold: true, color: interactive ? PALETTE.accent : PALETTE.muted, children: title }),
28929
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: `\xB7 ${note}` })
28930
+ ] }),
28931
+ children
28932
+ ] });
28933
+ }
28934
+ function AgentDetail({
28935
+ name,
28936
+ config,
28937
+ setConfig,
28938
+ onBack
28939
+ }) {
28940
+ const settings = config.agents[name];
28941
+ const [focusIndex, setFocusIndex] = useState29(0);
28716
28942
  const [editing, setEditing] = useState29(false);
28717
28943
  const [valueBeforeEdit, setValueBeforeEdit] = useState29("");
28944
+ const [saving, setSaving] = useState29(false);
28945
+ const [testing, setTesting] = useState29(false);
28946
+ const [notice, setNotice] = useState29(null);
28947
+ const [checks, setChecks] = useState29(void 0);
28718
28948
  useEffect22(() => {
28719
- readCredentials().then((cfg) => {
28720
- setConfig(cfg);
28721
- setStage("form");
28949
+ let active = true;
28950
+ setChecks(void 0);
28951
+ void inspectAgent(name, settings.binary).then((result) => active && setChecks(result));
28952
+ return () => {
28953
+ active = false;
28954
+ };
28955
+ }, [name, settings.binary]);
28956
+ const setField = (field, value) => {
28957
+ setConfig({ ...config, agents: { ...config.agents, [name]: { ...settings, [field]: value } } });
28958
+ setNotice(null);
28959
+ };
28960
+ const save = () => {
28961
+ setSaving(true);
28962
+ setNotice(null);
28963
+ writeAgentConfig(config).then(() => {
28964
+ applyBinaryOverrides(config);
28965
+ setNotice({ kind: "success", text: `Saved: ${AGENT_LABELS[name]} settings are written to config.json` });
28966
+ }).catch(
28967
+ (err) => setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` })
28968
+ ).finally(() => setSaving(false));
28969
+ };
28970
+ const runTest = () => {
28971
+ setTesting(true);
28972
+ setNotice(null);
28973
+ testAgent(name, settings.binary, settings.model).then((result) => {
28974
+ setChecks(result);
28975
+ const outcome = testOutcome(result);
28976
+ setNotice(
28977
+ outcome ? { kind: outcome.ok ? "success" : "error", text: outcome.text } : { kind: "error", text: "Test not run: the agent could not be started (see Status)" }
28978
+ );
28979
+ }).catch(
28980
+ (err) => setNotice({ kind: "error", text: `Test could not run: ${err instanceof Error ? err.message : String(err)}` })
28981
+ ).finally(() => setTesting(false));
28982
+ };
28983
+ const focused = FOCUS_ORDER[focusIndex];
28984
+ const focusedField = focused === "test" ? null : focused;
28985
+ useInput11((input, key) => {
28986
+ if (saving || testing) return;
28987
+ if (editing) {
28988
+ if (key.escape && focusedField) {
28989
+ setField(focusedField, valueBeforeEdit);
28990
+ setEditing(false);
28991
+ }
28992
+ return;
28993
+ }
28994
+ if (key.escape || input === "q") {
28995
+ onBack();
28996
+ return;
28997
+ }
28998
+ if (input === "s") {
28999
+ save();
29000
+ return;
29001
+ }
29002
+ if (key.upArrow) {
29003
+ setFocusIndex((i) => (i - 1 + FOCUS_ORDER.length) % FOCUS_ORDER.length);
29004
+ return;
29005
+ }
29006
+ if (key.downArrow || key.tab) {
29007
+ setFocusIndex((i) => (i + 1) % FOCUS_ORDER.length);
29008
+ return;
29009
+ }
29010
+ if (input === "c" && focusedField) {
29011
+ setField(focusedField, "");
29012
+ return;
29013
+ }
29014
+ if (key.return) {
29015
+ if (focusedField) {
29016
+ setValueBeforeEdit(settings[focusedField]);
29017
+ setEditing(true);
29018
+ } else {
29019
+ runTest();
29020
+ }
29021
+ }
29022
+ });
29023
+ const status = checks ? statusFromChecks(name, checks, settings.binary) : "checking";
29024
+ const hint = setupHint(name, status);
29025
+ const pointer = (isFocused) => /* @__PURE__ */ jsx56(Text47, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
29026
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29027
+ /* @__PURE__ */ jsx56(Text47, { bold: true, children: AGENT_LABELS[name] }),
29028
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
29029
+ (notice || testing || saving) && /* @__PURE__ */ jsx56(Box44, { marginTop: 1, children: testing || saving ? /* @__PURE__ */ jsx56(Text47, { color: PALETTE.accent, children: testing ? "\u2026 Running the test (up to 60s)" : "\u2026 Saving" }) : notice && /* @__PURE__ */ jsxs45(Text47, { bold: true, color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29030
+ notice.kind === "success" ? "\u2713" : "\u2717",
29031
+ " ",
29032
+ notice.text
29033
+ ] }) }),
29034
+ /* @__PURE__ */ jsxs45(Section2, { title: "CONFIGURE", note: "you can change these", interactive: true, children: [
29035
+ FIELDS2.map((field) => {
29036
+ const isFocused = focused === field;
29037
+ const value = settings[field];
29038
+ const display = isFocused && editing ? /* @__PURE__ */ jsx56(TextInput4, { value, onChange: (next) => setField(field, next), onSubmit: () => setEditing(false) }) : value ? /* @__PURE__ */ jsx56(Text47, { bold: true, children: value }) : /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: fieldHint(name, field) });
29039
+ return /* @__PURE__ */ jsx56(
29040
+ Row2,
29041
+ {
29042
+ pointer: pointer(isFocused),
29043
+ label: FIELD_LABEL[field],
29044
+ labelProps: { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted },
29045
+ children: display
29046
+ },
29047
+ field
29048
+ );
29049
+ }),
29050
+ /* @__PURE__ */ jsx56(
29051
+ Row2,
29052
+ {
29053
+ pointer: pointer(focused === "test"),
29054
+ label: "Run test",
29055
+ labelProps: { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted },
29056
+ children: /* @__PURE__ */ jsx56(Text47, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
29057
+ }
29058
+ )
29059
+ ] }),
29060
+ /* @__PURE__ */ jsxs45(Section2, { title: "STATUS", note: "read only", children: [
29061
+ statusRows(name, checks, settings.binary).map((row) => /* @__PURE__ */ jsx56(Row2, { pointer: null, label: row.label, children: /* @__PURE__ */ jsx56(Text47, { color: TONE_COLOR[row.tone], children: row.value }) }, row.label)),
29062
+ hint && /* @__PURE__ */ jsx56(Row2, { pointer: null, label: "Setup", children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: hint }) })
29063
+ ] }),
29064
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
29065
+ /* @__PURE__ */ jsx56(
29066
+ ControlHints,
29067
+ {
29068
+ hints: editing ? [
29069
+ { keys: "type", label: "edit" },
29070
+ { keys: "\u2190/\u2192", label: "move cursor" },
29071
+ { keys: "\u23CE", label: "done" },
29072
+ { keys: "Esc", label: "cancel edit" }
29073
+ ] : [
29074
+ { keys: "\u2191/\u2193", label: "move" },
29075
+ { keys: "\u23CE", label: focusedField ? "edit" : "run test" },
29076
+ ...focusedField ? [{ keys: "c", label: "clear" }] : [],
29077
+ { keys: "s", label: "save" },
29078
+ { keys: "Esc/q", label: "back without saving" }
29079
+ ]
29080
+ }
29081
+ )
29082
+ ] });
29083
+ }
29084
+
29085
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
29086
+ import { Fragment as Fragment17, jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
29087
+ var NAME_WIDTH = 16;
29088
+ var PANEL_LABEL_WIDTH = "Command".length;
29089
+ function AgentsScreen({ onDone }) {
29090
+ const [config, setConfig] = useState30(null);
29091
+ const [focus, setFocus] = useState30(0);
29092
+ const [open, setOpen] = useState30(null);
29093
+ const [notice, setNotice] = useState30(null);
29094
+ const [saving, setSaving] = useState30(false);
29095
+ const [checks, setChecks] = useState30({});
29096
+ const inspectAll = (loaded) => {
29097
+ for (const name of AGENT_NAMES) {
29098
+ void inspectAgent(name, loaded.agents[name].binary).then(
29099
+ (result) => setChecks((previous) => ({ ...previous, [name]: result }))
29100
+ );
29101
+ }
29102
+ };
29103
+ useEffect23(() => {
29104
+ void readAgentConfig().then((loaded) => {
29105
+ setConfig(loaded);
29106
+ inspectAll(loaded);
28722
29107
  startDebugRun({
28723
- flow: "settings/contentful-configuration",
28724
- step: "01-configuration",
28725
- menuOption: "Configuration",
28726
- inputs: debugFields(cfg)
29108
+ flow: "settings/agents",
29109
+ step: "01-agents",
29110
+ menuOption: "Configuration > Agents",
29111
+ inputs: { default_agent: loaded.defaultAgent }
28727
29112
  });
28728
29113
  });
28729
29114
  }, []);
28730
- function fieldValue(field) {
28731
- if (!config) return "";
28732
- return config[field] || "";
28733
- }
28734
- function setFieldValue(field, value) {
28735
- if (!config) return;
28736
- setConfig({ ...config, [field]: value });
28737
- setNotice(null);
28738
- }
28739
- function handleSave() {
28740
- if (!config) return;
28741
- setStage("saving");
29115
+ const makeDefault = (name) => {
29116
+ if (!config || saving) return;
29117
+ if (name === config.defaultAgent) {
29118
+ setNotice({ kind: "success", text: `${AGENT_LABELS[name]} is already the default agent` });
29119
+ return;
29120
+ }
29121
+ setSaving(true);
28742
29122
  setNotice(null);
28743
- writeCredentials(config).then(() => {
28744
- setLastSaved(config);
28745
- if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28746
- setNotice({ kind: "success", text: "Configuration saved" });
28747
- setStage("form");
28748
- }).catch((err) => {
28749
- setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
28750
- setStage("form");
28751
- });
29123
+ writeAgentConfig({ ...config, defaultAgent: name }).then(() => {
29124
+ setConfig((current) => current ? { ...current, defaultAgent: name } : current);
29125
+ setNotice({ kind: "success", text: `Default agent is now ${AGENT_LABELS[name]}` });
29126
+ }).catch(
29127
+ (err) => setNotice({
29128
+ kind: "error",
29129
+ text: `Default agent not changed: ${err instanceof Error ? err.message : String(err)}`
29130
+ })
29131
+ ).finally(() => setSaving(false));
29132
+ };
29133
+ useInput12((input, key) => {
29134
+ if (!config || open || saving) return;
29135
+ const focused = AGENT_NAMES[focus];
29136
+ if (key.upArrow || key.downArrow || key.tab) setNotice(null);
29137
+ if (key.upArrow) {
29138
+ setFocus((i) => (i - 1 + AGENT_NAMES.length) % AGENT_NAMES.length);
29139
+ return;
29140
+ }
29141
+ if (key.downArrow || key.tab) {
29142
+ setFocus((i) => (i + 1) % AGENT_NAMES.length);
29143
+ return;
29144
+ }
29145
+ if (key.return) {
29146
+ makeDefault(focused);
29147
+ return;
29148
+ }
29149
+ if (key.rightArrow) {
29150
+ setNotice(null);
29151
+ setOpen(focused);
29152
+ return;
29153
+ }
29154
+ if (key.escape || input === "q") {
29155
+ void finishDebugRun({ outputs: { default_agent: config.defaultAgent }, status: "success", exitMethod: "saved" });
29156
+ onDone();
29157
+ }
29158
+ });
29159
+ if (!config) {
29160
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29161
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
29162
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29163
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "Loading..." })
29164
+ ] });
28752
29165
  }
28753
- function quit() {
28754
- void finishDebugRun(
28755
- lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
29166
+ if (open) {
29167
+ return /* @__PURE__ */ jsx57(
29168
+ AgentDetail,
29169
+ {
29170
+ name: open,
29171
+ config,
29172
+ setConfig,
29173
+ onBack: () => {
29174
+ setOpen(null);
29175
+ void readAgentConfig().then((saved) => {
29176
+ setConfig(saved);
29177
+ inspectAll(saved);
29178
+ });
29179
+ }
29180
+ }
28756
29181
  );
28757
- onDone();
28758
29182
  }
28759
- useInput11((input, key) => {
28760
- if (stage === "loading" || stage === "saving") return;
29183
+ const focusedAgent = AGENT_NAMES[focus];
29184
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29185
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
29186
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "The coding agent the CLI runs, and what was found for each one." }),
29187
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29188
+ /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29189
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Default agent" }),
29190
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: AGENT_LABELS[config.defaultAgent] }),
29191
+ saving && /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "\u2026 saving" })
29192
+ ] }),
29193
+ /* @__PURE__ */ jsxs46(Box45, { marginTop: 1, gap: 1, children: [
29194
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29195
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29196
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "AGENT" }) }),
29197
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "STATUS" })
29198
+ ] }),
29199
+ AGENT_NAMES.map((name) => {
29200
+ const isFocused = focusedAgent === name;
29201
+ return /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29202
+ /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " }),
29203
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: name === config.defaultAgent ? "\u2605" : " " }),
29204
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[name] }) }),
29205
+ /* @__PURE__ */ jsx57(AgentStatusBadge, { name, checks: checks[name], binary: config.agents[name].binary })
29206
+ ] }, name);
29207
+ }),
29208
+ /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", marginTop: 1, children: [
29209
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: `\u2500 ${AGENT_LABELS[focusedAgent]} ${"\u2500".repeat(30)}` }),
29210
+ panelRows(focusedAgent, checks[focusedAgent], config.agents[focusedAgent]).map((row) => /* @__PURE__ */ jsxs46(Box45, { gap: 1, paddingLeft: 1, children: [
29211
+ /* @__PURE__ */ jsx57(Box45, { width: PANEL_LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: row.label }) }),
29212
+ /* @__PURE__ */ jsx57(Text48, { color: TONE_COLOR[row.tone], children: row.value })
29213
+ ] }, row.label))
29214
+ ] }),
29215
+ notice && /* @__PURE__ */ jsxs46(Fragment17, { children: [
29216
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29217
+ /* @__PURE__ */ jsxs46(Text48, { bold: true, color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29218
+ notice.kind === "success" ? "\u2713" : "\u2717",
29219
+ " ",
29220
+ notice.text
29221
+ ] })
29222
+ ] }),
29223
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29224
+ /* @__PURE__ */ jsx57(
29225
+ ControlHints,
29226
+ {
29227
+ hints: [
29228
+ { keys: "\u2191/\u2193", label: "move" },
29229
+ { keys: "\u23CE", label: "make default" },
29230
+ { keys: "\u2192", label: "settings and test" },
29231
+ { keys: "Esc/q", label: "back" }
29232
+ ]
29233
+ }
29234
+ )
29235
+ ] });
29236
+ }
29237
+
29238
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx
29239
+ import { useEffect as useEffect24, useState as useState32 } from "react";
29240
+ import { Box as Box47, Text as Text50 } from "ink";
29241
+ init_debug_store();
29242
+
29243
+ // packages/experience-design-system-cli/src/tui/settings/shared/FieldForm.tsx
29244
+ import { useState as useState31 } from "react";
29245
+ import { Box as Box46, Text as Text49, useInput as useInput13 } from "ink";
29246
+ import TextInput5 from "ink-text-input";
29247
+ import { Fragment as Fragment18, jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
29248
+ function FieldForm({
29249
+ title,
29250
+ subtitle,
29251
+ fields,
29252
+ values,
29253
+ onChange,
29254
+ onSave,
29255
+ onQuit,
29256
+ notice,
29257
+ busy = false,
29258
+ footer
29259
+ }) {
29260
+ const [active, setActive] = useState31(0);
29261
+ const [editing, setEditing] = useState31(false);
29262
+ const [valueBeforeEdit, setValueBeforeEdit] = useState31("");
29263
+ const labelWidth = Math.max(...fields.map((field) => field.label.length));
29264
+ const current = fields[active];
29265
+ useInput13((input, key) => {
29266
+ if (busy) return;
28761
29267
  if (editing) {
28762
29268
  if (key.escape) {
28763
- setFieldValue(activeField, valueBeforeEdit);
29269
+ onChange(current.key, valueBeforeEdit);
28764
29270
  setEditing(false);
28765
29271
  }
28766
29272
  return;
28767
29273
  }
28768
29274
  if (key.escape || input === "q") {
28769
- quit();
29275
+ onQuit();
28770
29276
  return;
28771
29277
  }
28772
29278
  if (input === "s") {
28773
- handleSave();
29279
+ onSave();
28774
29280
  return;
28775
29281
  }
28776
29282
  if (input === "c") {
28777
- setFieldValue(activeField, "");
29283
+ onChange(current.key, "");
28778
29284
  return;
28779
29285
  }
28780
29286
  if (key.tab || key.downArrow) {
28781
- const idx = FIELD_ORDER.indexOf(activeField);
28782
- setActiveField(FIELD_ORDER[(idx + 1) % FIELD_ORDER.length]);
29287
+ setActive((i) => (i + 1) % fields.length);
28783
29288
  return;
28784
29289
  }
28785
29290
  if (key.upArrow) {
28786
- const idx = FIELD_ORDER.indexOf(activeField);
28787
- setActiveField(FIELD_ORDER[(idx - 1 + FIELD_ORDER.length) % FIELD_ORDER.length]);
29291
+ setActive((i) => (i - 1 + fields.length) % fields.length);
28788
29292
  return;
28789
29293
  }
28790
29294
  if (key.return) {
28791
- setValueBeforeEdit(fieldValue(activeField));
29295
+ setValueBeforeEdit(values[current.key]);
28792
29296
  setEditing(true);
28793
29297
  }
28794
29298
  });
28795
- if (stage === "loading") {
28796
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28797
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
28798
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28799
- /* @__PURE__ */ jsx55(Text46, { color: PALETTE.accent, children: "Loading..." })
28800
- ] });
28801
- }
28802
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28803
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
28804
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28805
- /* @__PURE__ */ jsx55(Box44, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
28806
- const isActive = activeField === field;
28807
- const value = fieldValue(field);
28808
- const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28809
- return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28810
- /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28811
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28812
- isActive && editing ? /* @__PURE__ */ jsx55(
28813
- TextInput4,
29299
+ return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29300
+ /* @__PURE__ */ jsx58(Text49, { bold: true, children: title }),
29301
+ subtitle && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: subtitle }),
29302
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29303
+ /* @__PURE__ */ jsx58(Box46, { flexDirection: "column", children: fields.map((field, index) => {
29304
+ const isActive = index === active;
29305
+ const value = values[field.key];
29306
+ const display = field.masked ? "\u2022".repeat(value.length) : value;
29307
+ return /* @__PURE__ */ jsxs47(Box46, { gap: 1, children: [
29308
+ /* @__PURE__ */ jsx58(Text49, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
29309
+ /* @__PURE__ */ jsx58(Box46, { width: labelWidth, flexShrink: 0, children: /* @__PURE__ */ jsx58(Text49, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: field.label }) }),
29310
+ isActive && editing ? /* @__PURE__ */ jsx58(
29311
+ TextInput5,
28814
29312
  {
28815
29313
  value,
28816
- onChange: (next) => setFieldValue(field, next),
29314
+ onChange: (next) => onChange(field.key, next),
28817
29315
  onSubmit: () => setEditing(false),
28818
- mask: field === "cmaToken" ? "\u2022" : void 0
29316
+ mask: field.masked ? "\u2022" : void 0
28819
29317
  }
28820
- ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28821
- FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28822
- ] }, field);
29318
+ ) : /* @__PURE__ */ jsx58(Text49, { bold: !!display, children: display || (field.hint ? "" : /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "(empty)" })) }),
29319
+ field.hint && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: field.hint })
29320
+ ] }, field.key);
28823
29321
  }) }),
28824
- notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
28825
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28826
- /* @__PURE__ */ jsxs45(Text46, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29322
+ notice && /* @__PURE__ */ jsxs47(Fragment18, { children: [
29323
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29324
+ /* @__PURE__ */ jsxs47(Text49, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
28827
29325
  notice.kind === "success" ? "\u2713" : "\u2717",
28828
29326
  " ",
28829
29327
  notice.text
28830
29328
  ] })
28831
29329
  ] }),
28832
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28833
- /* @__PURE__ */ jsx55(
29330
+ footer,
29331
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29332
+ /* @__PURE__ */ jsx58(
28834
29333
  ControlHints,
28835
29334
  {
28836
29335
  hints: editing ? [
@@ -28843,7 +29342,168 @@ function ConfigurationScreen({ onDone }) {
28843
29342
  { keys: "\u23CE", label: "edit" },
28844
29343
  { keys: "c", label: "clear" },
28845
29344
  { keys: "s", label: "save" },
28846
- { keys: "Esc/q", label: "quit without saving" }
29345
+ { keys: "Esc/q", label: "back without saving" }
29346
+ ]
29347
+ }
29348
+ )
29349
+ ] });
29350
+ }
29351
+
29352
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
29353
+ async function readCredentials() {
29354
+ const store = await readV1Store();
29355
+ return {
29356
+ spaceId: store.spaceId || "",
29357
+ environmentId: store.environmentId || "",
29358
+ cmaToken: store.cmaToken || "",
29359
+ host: store.host || "",
29360
+ defaultComponentDir: store.defaultComponentDir || "",
29361
+ defaultTokenFile: store.defaultTokenFile || "",
29362
+ contentfulBaseDir: store.contentfulBaseDir || ""
29363
+ };
29364
+ }
29365
+ async function writeCredentials(config) {
29366
+ const existing = await readV1Store();
29367
+ const merged = {
29368
+ ...existing,
29369
+ ...config
29370
+ };
29371
+ Object.keys(merged).forEach((k) => {
29372
+ if (!merged[k]) delete merged[k];
29373
+ });
29374
+ await writeV1Store(merged);
29375
+ }
29376
+
29377
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx
29378
+ import { jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
29379
+ var FIELDS3 = [
29380
+ { key: "spaceId", label: "Space ID" },
29381
+ { key: "environmentId", label: "Environment ID" },
29382
+ { key: "cmaToken", label: "CMA Token", masked: true },
29383
+ { key: "host", label: "API Host" },
29384
+ { key: "defaultComponentDir", label: "Default component directory" },
29385
+ { key: "defaultTokenFile", label: "Default token file" },
29386
+ { key: "contentfulBaseDir", label: "Root Project Directory", hint: "(where .contentful goes)" }
29387
+ ];
29388
+ function debugFields(config) {
29389
+ return {
29390
+ space_id: config?.spaceId ?? "",
29391
+ environment_id: config?.environmentId ?? "",
29392
+ cma_token: config?.cmaToken ?? "",
29393
+ host: config?.host ?? "",
29394
+ default_component_dir: config?.defaultComponentDir ?? "",
29395
+ default_token_file: config?.defaultTokenFile ?? "",
29396
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
29397
+ };
29398
+ }
29399
+ var valuesOf = (config) => Object.fromEntries(FIELDS3.map(({ key }) => [key, config[key] || ""]));
29400
+ function ProjectConfigScreen({ onDone }) {
29401
+ const [config, setConfig] = useState32(null);
29402
+ const [saving, setSaving] = useState32(false);
29403
+ const [notice, setNotice] = useState32(null);
29404
+ const [lastSaved, setLastSaved] = useState32(null);
29405
+ useEffect24(() => {
29406
+ void readCredentials().then((cfg) => {
29407
+ setConfig(cfg);
29408
+ startDebugRun({
29409
+ flow: "settings/contentful-configuration",
29410
+ step: "01-configuration",
29411
+ menuOption: "Configuration > Project",
29412
+ inputs: debugFields(cfg)
29413
+ });
29414
+ });
29415
+ }, []);
29416
+ if (!config) {
29417
+ return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29418
+ /* @__PURE__ */ jsx59(Text50, { bold: true, children: "Project" }),
29419
+ /* @__PURE__ */ jsx59(Text50, { children: " " }),
29420
+ /* @__PURE__ */ jsx59(Text50, { color: PALETTE.accent, children: "Loading..." })
29421
+ ] });
29422
+ }
29423
+ const save = () => {
29424
+ setSaving(true);
29425
+ setNotice(null);
29426
+ writeCredentials(config).then(() => {
29427
+ setLastSaved(config);
29428
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
29429
+ setNotice({ kind: "success", text: "Project settings saved" });
29430
+ }).catch((err) => {
29431
+ setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
29432
+ }).finally(() => setSaving(false));
29433
+ };
29434
+ const quit = () => {
29435
+ void finishDebugRun(
29436
+ lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
29437
+ );
29438
+ onDone();
29439
+ };
29440
+ return /* @__PURE__ */ jsx59(
29441
+ FieldForm,
29442
+ {
29443
+ title: "Project",
29444
+ subtitle: "The Contentful space and where the CLI keeps its files.",
29445
+ fields: FIELDS3,
29446
+ values: valuesOf(config),
29447
+ onChange: (key, value) => {
29448
+ setConfig({ ...config, [key]: value });
29449
+ setNotice(null);
29450
+ },
29451
+ onSave: save,
29452
+ onQuit: quit,
29453
+ notice,
29454
+ busy: saving
29455
+ }
29456
+ );
29457
+ }
29458
+
29459
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
29460
+ import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
29461
+ var SECTIONS = [
29462
+ {
29463
+ id: "project",
29464
+ label: "Project",
29465
+ description: "Contentful space, credentials, defaults and where .contentful goes"
29466
+ },
29467
+ { id: "agents", label: "Agents", description: "Which coding agent the CLI uses, and each agent\u2019s settings" }
29468
+ ];
29469
+ function ConfigurationScreen({ onDone }) {
29470
+ const [focus, setFocus] = useState33(0);
29471
+ const [open, setOpen] = useState33(null);
29472
+ const close = () => setOpen(null);
29473
+ useInput14((input, key) => {
29474
+ if (open) return;
29475
+ if (key.upArrow) {
29476
+ setFocus((i) => (i - 1 + SECTIONS.length) % SECTIONS.length);
29477
+ return;
29478
+ }
29479
+ if (key.downArrow || key.tab) {
29480
+ setFocus((i) => (i + 1) % SECTIONS.length);
29481
+ return;
29482
+ }
29483
+ if (key.return) {
29484
+ setOpen(SECTIONS[focus].id);
29485
+ return;
29486
+ }
29487
+ if (key.escape || input === "q") onDone();
29488
+ });
29489
+ if (open === "project") return /* @__PURE__ */ jsx60(ProjectConfigScreen, { onDone: close });
29490
+ if (open === "agents") return /* @__PURE__ */ jsx60(AgentsScreen, { onDone: close });
29491
+ return /* @__PURE__ */ jsxs49(Box48, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29492
+ /* @__PURE__ */ jsx60(Text51, { bold: true, children: "Configuration" }),
29493
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
29494
+ SECTIONS.map((section, index) => /* @__PURE__ */ jsxs49(Box48, { gap: 1, children: [
29495
+ /* @__PURE__ */ jsx60(Text51, { color: index === focus ? PALETTE.accent : void 0, children: index === focus ? "\u276F" : " " }),
29496
+ /* @__PURE__ */ jsx60(Box48, { width: 9, flexShrink: 0, children: /* @__PURE__ */ jsx60(Text51, { bold: index === focus, color: index === focus ? PALETTE.accent : void 0, children: section.label }) }),
29497
+ /* @__PURE__ */ jsx60(Text51, { color: PALETTE.muted, children: section.description })
29498
+ ] }, section.id)),
29499
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
29500
+ /* @__PURE__ */ jsx60(
29501
+ ControlHints,
29502
+ {
29503
+ hints: [
29504
+ { keys: "\u2191/\u2193", label: "move" },
29505
+ { keys: "\u23CE", label: "open" },
29506
+ { keys: "Esc/q", label: "back" }
28847
29507
  ]
28848
29508
  }
28849
29509
  )
@@ -28851,8 +29511,8 @@ function ConfigurationScreen({ onDone }) {
28851
29511
  }
28852
29512
 
28853
29513
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28854
- import { useEffect as useEffect23, useState as useState30 } from "react";
28855
- import { Box as Box45, Text as Text47, useInput as useInput12 } from "ink";
29514
+ import { useEffect as useEffect25, useState as useState34 } from "react";
29515
+ import { Box as Box49, Text as Text52, useInput as useInput15 } from "ink";
28856
29516
 
28857
29517
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
28858
29518
  async function readAnalyticsSetting() {
@@ -28871,11 +29531,11 @@ async function writeAnalyticsSetting(setting) {
28871
29531
 
28872
29532
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28873
29533
  init_debug_store();
28874
- import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
29534
+ import { Fragment as Fragment19, jsx as jsx61, jsxs as jsxs50 } from "react/jsx-runtime";
28875
29535
  function OptInAnalyticsScreen({ onDone }) {
28876
- const [loading, setLoading] = useState30(true);
28877
- const [enabled, setEnabled] = useState30(true);
28878
- useEffect23(() => {
29536
+ const [loading, setLoading] = useState34(true);
29537
+ const [enabled, setEnabled] = useState34(true);
29538
+ useEffect25(() => {
28879
29539
  readAnalyticsSetting().then((setting) => {
28880
29540
  setEnabled(setting.enabled);
28881
29541
  setLoading(false);
@@ -28887,7 +29547,7 @@ function OptInAnalyticsScreen({ onDone }) {
28887
29547
  });
28888
29548
  });
28889
29549
  }, []);
28890
- useInput12((input, key) => {
29550
+ useInput15((input, key) => {
28891
29551
  if (loading) return;
28892
29552
  if (key.return || input === " ") {
28893
29553
  setEnabled((current) => {
@@ -28902,21 +29562,21 @@ function OptInAnalyticsScreen({ onDone }) {
28902
29562
  onDone();
28903
29563
  }
28904
29564
  });
28905
- return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28906
- /* @__PURE__ */ jsx56(Text47, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
28907
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28908
- loading ? /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs46(Fragment18, { children: [
28909
- /* @__PURE__ */ jsxs46(Text47, { children: [
29565
+ return /* @__PURE__ */ jsxs50(Box49, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29566
+ /* @__PURE__ */ jsx61(Text52, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
29567
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29568
+ loading ? /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs50(Fragment19, { children: [
29569
+ /* @__PURE__ */ jsxs50(Text52, { children: [
28910
29570
  "Share anonymous usage data:",
28911
29571
  " ",
28912
- /* @__PURE__ */ jsx56(Text47, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
29572
+ /* @__PURE__ */ jsx61(Text52, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
28913
29573
  ] }),
28914
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28915
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
28916
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
29574
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29575
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
29576
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
28917
29577
  ] }),
28918
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28919
- /* @__PURE__ */ jsx56(
29578
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29579
+ /* @__PURE__ */ jsx61(
28920
29580
  ControlHints,
28921
29581
  {
28922
29582
  hints: [
@@ -28929,15 +29589,15 @@ function OptInAnalyticsScreen({ onDone }) {
28929
29589
  }
28930
29590
 
28931
29591
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28932
- import { useEffect as useEffect24, useState as useState31 } from "react";
28933
- import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
29592
+ import { useEffect as useEffect26, useState as useState35 } from "react";
29593
+ import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
28934
29594
  init_version();
28935
29595
  init_debug_store();
28936
- import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
29596
+ import { jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
28937
29597
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28938
29598
  function UpgradeScreen({ onDone }) {
28939
- const [upgradeCheck, setUpgradeCheck] = useState31();
28940
- useEffect24(() => {
29599
+ const [upgradeCheck, setUpgradeCheck] = useState35();
29600
+ useEffect26(() => {
28941
29601
  startDebugRun({
28942
29602
  flow: "upgrade",
28943
29603
  step: "01-upgrade",
@@ -28946,7 +29606,7 @@ function UpgradeScreen({ onDone }) {
28946
29606
  });
28947
29607
  checkForUpgrade().then(setUpgradeCheck).catch(() => setUpgradeCheck({ status: "error" }));
28948
29608
  }, []);
28949
- useInput13((_input, key) => {
29609
+ useInput16((_input, key) => {
28950
29610
  if (key.return) {
28951
29611
  void finishDebugRun({
28952
29612
  outputs: upgradeCheck ?? {},
@@ -28957,12 +29617,12 @@ function UpgradeScreen({ onDone }) {
28957
29617
  return;
28958
29618
  }
28959
29619
  });
28960
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28961
- /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Upgrade" }),
28962
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
29620
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29621
+ /* @__PURE__ */ jsx62(Text53, { bold: true, children: "Upgrade" }),
29622
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
28963
29623
  renderBody(upgradeCheck),
28964
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
28965
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.accent, children: [
29624
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
29625
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.accent, children: [
28966
29626
  FOCUS_MARKER,
28967
29627
  " Go Back"
28968
29628
  ] })
@@ -28970,47 +29630,47 @@ function UpgradeScreen({ onDone }) {
28970
29630
  }
28971
29631
  function renderBody(upgradeCheck) {
28972
29632
  if (!upgradeCheck) {
28973
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Checking for updates\u2026" });
29633
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Checking for updates\u2026" });
28974
29634
  }
28975
29635
  if (upgradeCheck.status === "error") {
28976
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
29636
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
28977
29637
  }
28978
29638
  if (upgradeCheck.status === "up-to-date") {
28979
- return /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.success, children: [
29639
+ return /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.success, children: [
28980
29640
  "You're already on the latest version (v",
28981
29641
  upgradeCheck.current,
28982
29642
  ")."
28983
29643
  ] });
28984
29644
  }
28985
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", children: [
28986
- /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.muted, children: [
28987
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.success, children: [
29645
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", children: [
29646
+ /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.muted, children: [
29647
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.success, children: [
28988
29648
  "v",
28989
29649
  upgradeCheck.latest
28990
29650
  ] }),
28991
29651
  " ",
28992
29652
  "is available (you're on ",
28993
- /* @__PURE__ */ jsxs47(Text48, { bold: true, children: [
29653
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, children: [
28994
29654
  "v",
28995
29655
  upgradeCheck.current
28996
29656
  ] }),
28997
29657
  "). Exit this program, cd into the root of your local clone of contentful/experience-design-system-sdk-public, then run:"
28998
29658
  ] }),
28999
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
29000
- /* @__PURE__ */ jsx57(Box46, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx57(Text48, { bold: true, children: cmd }, cmd)) })
29659
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
29660
+ /* @__PURE__ */ jsx62(Box50, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx62(Text53, { bold: true, children: cmd }, cmd)) })
29001
29661
  ] });
29002
29662
  }
29003
29663
 
29004
29664
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
29005
- import { useEffect as useEffect25, useState as useState32 } from "react";
29006
- import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
29665
+ import { useEffect as useEffect27, useState as useState36 } from "react";
29666
+ import { Box as Box51, Text as Text54, useInput as useInput17 } from "ink";
29007
29667
  init_debug_mode_store();
29008
29668
  init_debug_store();
29009
- import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
29669
+ import { jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
29010
29670
  function DebugModeScreen({ onDone }) {
29011
- const [loading, setLoading] = useState32(true);
29012
- const [enabled, setEnabled] = useState32(true);
29013
- useEffect25(() => {
29671
+ const [loading, setLoading] = useState36(true);
29672
+ const [enabled, setEnabled] = useState36(true);
29673
+ useEffect27(() => {
29014
29674
  readDebugModeSetting().then((setting) => {
29015
29675
  setEnabled(setting.enabled);
29016
29676
  setLoading(false);
@@ -29022,7 +29682,7 @@ function DebugModeScreen({ onDone }) {
29022
29682
  });
29023
29683
  });
29024
29684
  }, []);
29025
- useInput14((input, key) => {
29685
+ useInput17((input, key) => {
29026
29686
  if (loading) return;
29027
29687
  if (key.return || input === " ") {
29028
29688
  setEnabled((current) => {
@@ -29037,16 +29697,16 @@ function DebugModeScreen({ onDone }) {
29037
29697
  onDone();
29038
29698
  }
29039
29699
  });
29040
- return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29041
- /* @__PURE__ */ jsx58(Text49, { bold: true, children: "Settings \u203A Debug Mode" }),
29042
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
29043
- loading ? /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs48(Text49, { children: [
29700
+ return /* @__PURE__ */ jsxs52(Box51, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29701
+ /* @__PURE__ */ jsx63(Text54, { bold: true, children: "Settings \u203A Debug Mode" }),
29702
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
29703
+ loading ? /* @__PURE__ */ jsx63(Text54, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs52(Text54, { children: [
29044
29704
  "Debug logging:",
29045
29705
  " ",
29046
- /* @__PURE__ */ jsx58(Text49, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
29706
+ /* @__PURE__ */ jsx63(Text54, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
29047
29707
  ] }),
29048
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
29049
- /* @__PURE__ */ jsx58(
29708
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
29709
+ /* @__PURE__ */ jsx63(
29050
29710
  ControlHints,
29051
29711
  {
29052
29712
  hints: [
@@ -29059,18 +29719,18 @@ function DebugModeScreen({ onDone }) {
29059
29719
  }
29060
29720
 
29061
29721
  // packages/experience-design-system-cli/app.tsx
29062
- import { Fragment as Fragment19, jsx as jsx59 } from "react/jsx-runtime";
29722
+ import { Fragment as Fragment20, jsx as jsx64 } from "react/jsx-runtime";
29063
29723
  function App({ importOptions, inkClear }) {
29064
- const [screen, setScreen] = useState33("start");
29065
- const [importExitCode, setImportExitCode] = useState33();
29724
+ const [screen, setScreen] = useState37("start");
29725
+ const [importExitCode, setImportExitCode] = useState37();
29066
29726
  const showImportResult = importExitCode !== void 0;
29067
- const [projectPath, setProjectPath] = useState33();
29068
- const [tokensPath, setTokensPath] = useState33();
29069
- const [scannedFiles, setScannedFiles] = useState33();
29070
- const [pendingLaunch, setPendingLaunch] = useState33();
29071
- const [extractionRun, setExtractionRun] = useState33();
29727
+ const [projectPath, setProjectPath] = useState37();
29728
+ const [tokensPath, setTokensPath] = useState37();
29729
+ const [scannedFiles, setScannedFiles] = useState37();
29730
+ const [pendingLaunch, setPendingLaunch] = useState37();
29731
+ const [extractionRun, setExtractionRun] = useState37();
29072
29732
  const extraction = useExtraction(extractionRun?.input);
29073
- const [scopeRun, setScopeRun] = useState33();
29733
+ const [scopeRun, setScopeRun] = useState37();
29074
29734
  const scopeFlow = useScopeGateFlow(
29075
29735
  scopeRun && {
29076
29736
  sessionId: scopeRun.extraction.sessionId,
@@ -29085,12 +29745,12 @@ function App({ importOptions, inkClear }) {
29085
29745
  }
29086
29746
  }
29087
29747
  );
29088
- const [generationInput, setGenerationInput] = useState33();
29748
+ const [generationInput, setGenerationInput] = useState37();
29089
29749
  const generation = useGeneration(generationInput);
29090
- const [flowStart, setFlowStart] = useState33();
29750
+ const [flowStart, setFlowStart] = useState37();
29091
29751
  const flow = useFlow(flowStart, { beforeStepChange: inkClear });
29092
- const [importDefaults, setImportDefaults] = useState33();
29093
- useEffect26(() => {
29752
+ const [importDefaults, setImportDefaults] = useState37();
29753
+ useEffect28(() => {
29094
29754
  if (screen !== "import") {
29095
29755
  setImportDefaults(void 0);
29096
29756
  return;
@@ -29108,7 +29768,7 @@ function App({ importOptions, inkClear }) {
29108
29768
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
29109
29769
  const state2 = await inspectTokens({
29110
29770
  rawTokensPath: tokens,
29111
- contentfulDir: join25(resolveUserPath(projectPath2), ".contentful"),
29771
+ contentfulDir: join26(resolveUserPath(projectPath2), ".contentful"),
29112
29772
  cache: importOptions.cache
29113
29773
  });
29114
29774
  if (state2.kind === "cached") {
@@ -29150,12 +29810,12 @@ function App({ importOptions, inkClear }) {
29150
29810
  }
29151
29811
  });
29152
29812
  };
29153
- useEffect26(() => {
29813
+ useEffect28(() => {
29154
29814
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
29155
29815
  setExtractionRun(void 0);
29156
29816
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
29157
29817
  }, [extraction, extractionRun]);
29158
- useEffect26(() => {
29818
+ useEffect28(() => {
29159
29819
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
29160
29820
  const { extraction: produced, input, generatePromptPath } = scopeRun;
29161
29821
  setGenerationInput({
@@ -29173,7 +29833,7 @@ function App({ importOptions, inkClear }) {
29173
29833
  ...generatePromptPath ? { generatePromptPath } : {}
29174
29834
  });
29175
29835
  }, [scopeFlow, scopeRun, generationInput]);
29176
- useEffect26(() => {
29836
+ useEffect28(() => {
29177
29837
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
29178
29838
  const { credentialsSkipped, tokenStrategy, extraction: produced, input, generatePromptPath } = scopeRun;
29179
29839
  inkClear();
@@ -29216,9 +29876,9 @@ function App({ importOptions, inkClear }) {
29216
29876
  };
29217
29877
  switch (screen) {
29218
29878
  case "import":
29219
- if (showImportResult) return /* @__PURE__ */ jsx59(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
29879
+ if (showImportResult) return /* @__PURE__ */ jsx64(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
29220
29880
  if (flow && flowStart) {
29221
- return /* @__PURE__ */ jsx59(
29881
+ return /* @__PURE__ */ jsx64(
29222
29882
  FlowScreen,
29223
29883
  {
29224
29884
  state: flow.state,
@@ -29228,12 +29888,12 @@ function App({ importOptions, inkClear }) {
29228
29888
  }
29229
29889
  );
29230
29890
  }
29231
- if (importDefaults === void 0) return /* @__PURE__ */ jsx59(Fragment19, {});
29891
+ if (importDefaults === void 0) return /* @__PURE__ */ jsx64(Fragment20, {});
29232
29892
  if (projectPath === void 0) {
29233
- return /* @__PURE__ */ jsx59(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
29893
+ return /* @__PURE__ */ jsx64(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
29234
29894
  }
29235
29895
  if (tokensPath === void 0) {
29236
- return /* @__PURE__ */ jsx59(
29896
+ return /* @__PURE__ */ jsx64(
29237
29897
  TokenInputScreen,
29238
29898
  {
29239
29899
  initialPath: importDefaults.tokenFile,
@@ -29243,7 +29903,7 @@ function App({ importOptions, inkClear }) {
29243
29903
  );
29244
29904
  }
29245
29905
  if (scannedFiles === void 0) {
29246
- return /* @__PURE__ */ jsx59(
29906
+ return /* @__PURE__ */ jsx64(
29247
29907
  PathValidationScreen,
29248
29908
  {
29249
29909
  projectPath,
@@ -29255,10 +29915,10 @@ function App({ importOptions, inkClear }) {
29255
29915
  }
29256
29916
  if (extractionRun) {
29257
29917
  if (extraction?.status === "done" && !extraction.result.ok) {
29258
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
29918
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
29259
29919
  }
29260
29920
  if (extraction?.status === "running") {
29261
- return /* @__PURE__ */ jsx59(
29921
+ return /* @__PURE__ */ jsx64(
29262
29922
  ExtractionScreen,
29263
29923
  {
29264
29924
  progress: extraction.progress,
@@ -29267,14 +29927,14 @@ function App({ importOptions, inkClear }) {
29267
29927
  }
29268
29928
  );
29269
29929
  }
29270
- return /* @__PURE__ */ jsx59(Fragment19, {});
29930
+ return /* @__PURE__ */ jsx64(Fragment20, {});
29271
29931
  }
29272
29932
  if (scopeRun && scopeFlow) {
29273
29933
  if (scopeFlow.status === "failed") {
29274
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
29934
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
29275
29935
  }
29276
29936
  if (scopeFlow.status === "deciding") {
29277
- return /* @__PURE__ */ jsx59(
29937
+ return /* @__PURE__ */ jsx64(
29278
29938
  ScopeGateScreen,
29279
29939
  {
29280
29940
  components: scopeFlow.load.components,
@@ -29284,7 +29944,7 @@ function App({ importOptions, inkClear }) {
29284
29944
  );
29285
29945
  }
29286
29946
  if (generation?.status === "done" && !generation.result.ok) {
29287
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
29947
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
29288
29948
  }
29289
29949
  if (generation?.status === "running") {
29290
29950
  const hasRawTokens = scopeRun.input.rawTokensPath !== "";
@@ -29292,7 +29952,7 @@ function App({ importOptions, inkClear }) {
29292
29952
  hasRawTokens,
29293
29953
  mapTokensEligible: generation.progress.mapTokensEligible
29294
29954
  });
29295
- return /* @__PURE__ */ jsx59(
29955
+ return /* @__PURE__ */ jsx64(
29296
29956
  GenerationScreen,
29297
29957
  {
29298
29958
  progress: generation.progress,
@@ -29304,10 +29964,10 @@ function App({ importOptions, inkClear }) {
29304
29964
  }
29305
29965
  );
29306
29966
  }
29307
- return /* @__PURE__ */ jsx59(Fragment19, {});
29967
+ return /* @__PURE__ */ jsx64(Fragment20, {});
29308
29968
  }
29309
29969
  if (pendingLaunch?.cached) {
29310
- return /* @__PURE__ */ jsx59(
29970
+ return /* @__PURE__ */ jsx64(
29311
29971
  TokenReuseScreen,
29312
29972
  {
29313
29973
  tokensPath: pendingLaunch.cached.tokensPath,
@@ -29318,7 +29978,7 @@ function App({ importOptions, inkClear }) {
29318
29978
  }
29319
29979
  );
29320
29980
  }
29321
- return /* @__PURE__ */ jsx59(
29981
+ return /* @__PURE__ */ jsx64(
29322
29982
  CredentialsScreen,
29323
29983
  {
29324
29984
  initial: importDefaults.credentials,
@@ -29327,19 +29987,19 @@ function App({ importOptions, inkClear }) {
29327
29987
  }
29328
29988
  );
29329
29989
  case "help":
29330
- return /* @__PURE__ */ jsx59(HelpScreen, { onDone: goToStart });
29990
+ return /* @__PURE__ */ jsx64(HelpScreen, { onDone: goToStart });
29331
29991
  case "upgrade":
29332
- return /* @__PURE__ */ jsx59(UpgradeScreen, { onDone: goToStart });
29992
+ return /* @__PURE__ */ jsx64(UpgradeScreen, { onDone: goToStart });
29333
29993
  case "settings":
29334
- return /* @__PURE__ */ jsx59(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
29994
+ return /* @__PURE__ */ jsx64(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
29335
29995
  case "settings-configuration":
29336
- return /* @__PURE__ */ jsx59(ConfigurationScreen, { onDone: goToSettings });
29996
+ return /* @__PURE__ */ jsx64(ConfigurationScreen, { onDone: goToSettings });
29337
29997
  case "settings-opt-in-analytics":
29338
- return /* @__PURE__ */ jsx59(OptInAnalyticsScreen, { onDone: goToSettings });
29998
+ return /* @__PURE__ */ jsx64(OptInAnalyticsScreen, { onDone: goToSettings });
29339
29999
  case "settings-debug-mode":
29340
- return /* @__PURE__ */ jsx59(DebugModeScreen, { onDone: goToSettings });
30000
+ return /* @__PURE__ */ jsx64(DebugModeScreen, { onDone: goToSettings });
29341
30001
  case "start":
29342
- return /* @__PURE__ */ jsx59(HomeScreen, { onNavigate: setScreen });
30002
+ return /* @__PURE__ */ jsx64(HomeScreen, { onNavigate: setScreen });
29343
30003
  }
29344
30004
  }
29345
30005
  async function runApp(renderApp, importOptions) {
@@ -29347,7 +30007,7 @@ async function runApp(renderApp, importOptions) {
29347
30007
  instance.clear?.();
29348
30008
  process.stdout.write("\x1B[H\x1B[0J");
29349
30009
  };
29350
- const instance = renderApp(/* @__PURE__ */ jsx59(App, { importOptions, inkClear }));
30010
+ const instance = renderApp(/* @__PURE__ */ jsx64(App, { importOptions, inkClear }));
29351
30011
  await instance.waitUntilExit();
29352
30012
  }
29353
30013
  export {