@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/index.js CHANGED
@@ -1500,7 +1500,7 @@ async function runAgent(options) {
1500
1500
  promptLen: prompt.length,
1501
1501
  promptHead: prompt.slice(0, 500)
1502
1502
  });
1503
- return new Promise((resolve27) => {
1503
+ return new Promise((resolve28) => {
1504
1504
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
1505
1505
  const child = spawn(binary, args, {
1506
1506
  stdio: ["pipe", "pipe", "pipe"],
@@ -1549,7 +1549,7 @@ async function runAgent(options) {
1549
1549
  stderrLen: stderr.length,
1550
1550
  stderrTail: stderr.slice(-1e3)
1551
1551
  });
1552
- resolve27(result);
1552
+ resolve28(result);
1553
1553
  });
1554
1554
  });
1555
1555
  }
@@ -1571,7 +1571,7 @@ async function checkAgentAuth(agent) {
1571
1571
  return "not-found";
1572
1572
  if (agent !== "claude")
1573
1573
  return "ok";
1574
- return new Promise((resolve27) => {
1574
+ return new Promise((resolve28) => {
1575
1575
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
1576
1576
  let stdout = "";
1577
1577
  let done = false;
@@ -1580,7 +1580,7 @@ async function checkAgentAuth(agent) {
1580
1580
  return;
1581
1581
  done = true;
1582
1582
  child.kill("SIGTERM");
1583
- resolve27("unauthenticated");
1583
+ resolve28("unauthenticated");
1584
1584
  }, 5e3);
1585
1585
  child.stdout?.on("data", (chunk) => {
1586
1586
  stdout += chunk.toString();
@@ -1591,14 +1591,14 @@ async function checkAgentAuth(agent) {
1591
1591
  done = true;
1592
1592
  clearTimeout(timer);
1593
1593
  if (code !== 0) {
1594
- resolve27("unauthenticated");
1594
+ resolve28("unauthenticated");
1595
1595
  return;
1596
1596
  }
1597
1597
  try {
1598
1598
  const status = JSON.parse(stdout);
1599
- resolve27(status.loggedIn ? "ok" : "unauthenticated");
1599
+ resolve28(status.loggedIn ? "ok" : "unauthenticated");
1600
1600
  } catch {
1601
- resolve27("unauthenticated");
1601
+ resolve28("unauthenticated");
1602
1602
  }
1603
1603
  });
1604
1604
  });
@@ -1608,9 +1608,9 @@ async function binaryIsOnPath(binary) {
1608
1608
  const fs = await import("node:fs/promises");
1609
1609
  return fs.access(binary).then(() => true, () => false);
1610
1610
  }
1611
- return new Promise((resolve27) => {
1611
+ return new Promise((resolve28) => {
1612
1612
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
1613
- child.on("close", (code) => resolve27(code === 0));
1613
+ child.on("close", (code) => resolve28(code === 0));
1614
1614
  });
1615
1615
  }
1616
1616
  var init_check_agent_auth = __esm({
@@ -3765,30 +3765,8 @@ function applyScopeDecisions(db, sessionId, decisions) {
3765
3765
  const placeholders = accepted.map(() => "?").join(",");
3766
3766
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
3767
3767
  }
3768
- removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
3769
3768
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
3770
3769
  }
3771
- function removeSlotAllowedComponents(db, sessionId, edges, rejectedNames) {
3772
- if (edges.length === 0 && rejectedNames.length === 0)
3773
- return;
3774
- const componentId = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
3775
- const removeEdge = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND allowed_component = ?");
3776
- const removeEverywhere = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND allowed_component = ?");
3777
- db.exec("BEGIN");
3778
- try {
3779
- for (const edge of edges) {
3780
- const row = componentId.get(sessionId, edge.parent);
3781
- if (row)
3782
- removeEdge.run(sessionId, row.component_id, edge.child);
3783
- }
3784
- for (const name of rejectedNames)
3785
- removeEverywhere.run(sessionId, name);
3786
- db.exec("COMMIT");
3787
- } catch (e) {
3788
- db.exec("ROLLBACK");
3789
- throw e;
3790
- }
3791
- }
3792
3770
  function findLatestSessionForCommand(db, command) {
3793
3771
  return getLatestCompletedSessionForCommand(db, command);
3794
3772
  }
@@ -7938,10 +7916,10 @@ function extractVueSlotsFromSetup(options) {
7938
7916
  if (!body)
7939
7917
  return [];
7940
7918
  const slotsByName = /* @__PURE__ */ new Map();
7941
- for (const access6 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
7942
- if (access6.getExpression().getText() !== slotsName)
7919
+ for (const access7 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
7920
+ if (access7.getExpression().getText() !== slotsName)
7943
7921
  continue;
7944
- const slotName = access6.getName();
7922
+ const slotName = access7.getName();
7945
7923
  if (!slotsByName.has(slotName)) {
7946
7924
  slotsByName.set(slotName, {
7947
7925
  name: slotName,
@@ -14355,7 +14333,7 @@ function errorMessage(error) {
14355
14333
  return error instanceof Error && error.message ? error.message : String(error);
14356
14334
  }
14357
14335
  function defaultSleep(delayMs) {
14358
- return new Promise((resolve27) => setTimeout(resolve27, delayMs));
14336
+ return new Promise((resolve28) => setTimeout(resolve28, delayMs));
14359
14337
  }
14360
14338
  var MAX_RETRY_AFTER_MS;
14361
14339
  var init_http_utils = __esm({
@@ -14631,7 +14609,7 @@ var init_api_client = __esm({
14631
14609
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
14632
14610
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
14633
14611
  const jitter = Math.random() * baseDelay * 0.15;
14634
- await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
14612
+ await new Promise((resolve28) => setTimeout(resolve28, baseDelay + jitter));
14635
14613
  }
14636
14614
  }
14637
14615
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -18549,7 +18527,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
18549
18527
  const message = error instanceof Error ? error.message : String(error);
18550
18528
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
18551
18529
  throw error;
18552
- await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
18530
+ await new Promise((resolve28) => setTimeout(resolve28, Math.min(250 * attempt, 2e3)));
18553
18531
  }
18554
18532
  }
18555
18533
  }
@@ -19468,6 +19446,7 @@ var init_src4 = __esm({
19468
19446
  init_agents();
19469
19447
  init_agent_name();
19470
19448
  init_models();
19449
+ init_binaries();
19471
19450
  init_is_agent_name();
19472
19451
  init_agent_supports_bedrock();
19473
19452
  init_check_agent_auth();
@@ -19587,6 +19566,97 @@ var init_v1_store = __esm({
19587
19566
  }
19588
19567
  });
19589
19568
 
19569
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-store.ts
19570
+ function emptyAgents() {
19571
+ return Object.fromEntries(AGENT_NAMES.map((name) => [name, { model: "", binary: "" }]));
19572
+ }
19573
+ async function readAgentConfig() {
19574
+ const store = await readV1Store();
19575
+ const stored = asString(store["agent"]);
19576
+ const defaultAgent = isAgentName(stored) ? stored : DEFAULT_AGENT3;
19577
+ const agents = emptyAgents();
19578
+ const saved = store["agents"];
19579
+ if (saved && typeof saved === "object") {
19580
+ for (const name of AGENT_NAMES) {
19581
+ const entry = saved[name];
19582
+ if (entry && typeof entry === "object") {
19583
+ const fields = entry;
19584
+ agents[name] = { model: asString(fields["model"]), binary: asString(fields["binary"]) };
19585
+ }
19586
+ }
19587
+ }
19588
+ const legacyModel = asString(store["agentModel"]);
19589
+ if (legacyModel && !agents[defaultAgent].model)
19590
+ agents[defaultAgent] = { ...agents[defaultAgent], model: legacyModel };
19591
+ return { defaultAgent, agents };
19592
+ }
19593
+ async function writeAgentConfig(config) {
19594
+ const existing = await readV1Store();
19595
+ const merged = { ...existing };
19596
+ const agents = {};
19597
+ for (const name of AGENT_NAMES) {
19598
+ const model = config.agents[name].model.trim();
19599
+ const binary = config.agents[name].binary.trim();
19600
+ if (model || binary) agents[name] = { ...model ? { model } : {}, ...binary ? { binary } : {} };
19601
+ }
19602
+ merged["agent"] = config.defaultAgent;
19603
+ const defaultModel = agents[config.defaultAgent]?.model;
19604
+ if (defaultModel) merged["agentModel"] = defaultModel;
19605
+ else delete merged["agentModel"];
19606
+ if (Object.keys(agents).length > 0) merged["agents"] = agents;
19607
+ else delete merged["agents"];
19608
+ await writeV1Store(merged);
19609
+ }
19610
+ var DEFAULT_AGENT3, AGENT_LABELS, AGENT_HINTS, asString;
19611
+ var init_agent_store = __esm({
19612
+ "packages/experience-design-system-cli/src/tui/settings/agents/agent-store.ts"() {
19613
+ "use strict";
19614
+ init_src4();
19615
+ init_v1_store();
19616
+ DEFAULT_AGENT3 = "claude";
19617
+ AGENT_LABELS = {
19618
+ claude: "Claude Code",
19619
+ codex: "OpenAI Codex",
19620
+ opencode: "OpenCode",
19621
+ cursor: "Cursor",
19622
+ copilot: "GitHub Copilot"
19623
+ };
19624
+ AGENT_HINTS = {
19625
+ claude: "claude",
19626
+ codex: "codex",
19627
+ opencode: "opencode",
19628
+ cursor: "cursor-agent",
19629
+ copilot: "copilot"
19630
+ };
19631
+ asString = (value) => typeof value === "string" ? value : "";
19632
+ }
19633
+ });
19634
+
19635
+ // packages/experience-design-system-cli/src/tui/settings/agents/apply-binary-overrides.ts
19636
+ function applyBinaryOverrides(config) {
19637
+ for (const name of AGENT_NAMES) {
19638
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
19639
+ const binary = config.agents[name].binary.trim();
19640
+ if (binary) {
19641
+ if (!shellValues.has(key)) shellValues.set(key, process.env[key]);
19642
+ process.env[key] = binary;
19643
+ } else if (shellValues.has(key)) {
19644
+ const shellValue = shellValues.get(key);
19645
+ if (shellValue === void 0) delete process.env[key];
19646
+ else process.env[key] = shellValue;
19647
+ shellValues.delete(key);
19648
+ }
19649
+ }
19650
+ }
19651
+ var shellValues;
19652
+ var init_apply_binary_overrides = __esm({
19653
+ "packages/experience-design-system-cli/src/tui/settings/agents/apply-binary-overrides.ts"() {
19654
+ "use strict";
19655
+ init_src4();
19656
+ shellValues = /* @__PURE__ */ new Map();
19657
+ }
19658
+ });
19659
+
19590
19660
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
19591
19661
  async function readAnalyticsSetting() {
19592
19662
  const store = await readV1Store();
@@ -22312,7 +22382,7 @@ function buildVisibleRows(props) {
22312
22382
  if (visited.has(target)) continue;
22313
22383
  visited.add(target);
22314
22384
  const isCycleMember = cycleParticipants.has(target);
22315
- out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
22385
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
22316
22386
  queue.push({ name: target, depth: cur.depth + 1 });
22317
22387
  }
22318
22388
  }
@@ -22359,8 +22429,7 @@ function buildVisibleRows(props) {
22359
22429
  sharedSuffix,
22360
22430
  cycleChild: child.isCycleMember || void 0,
22361
22431
  itemIdx: childRec?.idx ?? -1,
22362
- rootName: key,
22363
- parentName: child.parent
22432
+ rootName: key
22364
22433
  });
22365
22434
  });
22366
22435
  }
@@ -22443,19 +22512,13 @@ function buildVisibleRows(props) {
22443
22512
  injectedChildren.push({
22444
22513
  name: target,
22445
22514
  depth: parentDepth + 1,
22446
- isCycleChild: true,
22447
- parent: parentName
22515
+ isCycleChild: true
22448
22516
  });
22449
22517
  }
22450
22518
  };
22451
22519
  emitCycleChildrenOf(root, 0);
22452
22520
  for (const c2 of closureChildren) {
22453
- injectedChildren.push({
22454
- name: c2.name,
22455
- depth: c2.depth,
22456
- isCycleChild: false,
22457
- parent: c2.path[c2.path.length - 2] ?? root
22458
- });
22521
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
22459
22522
  emitCycleChildrenOf(c2.name, c2.depth);
22460
22523
  }
22461
22524
  const isLastAtDepth = (idx) => {
@@ -22489,8 +22552,7 @@ function buildVisibleRows(props) {
22489
22552
  sharedSuffix,
22490
22553
  cycleChild: child.isCycleChild || void 0,
22491
22554
  itemIdx: childRec?.idx ?? -1,
22492
- rootName: root,
22493
- parentName: child.parent
22555
+ rootName: root
22494
22556
  });
22495
22557
  });
22496
22558
  }
@@ -22648,7 +22710,7 @@ function GroupedSidebar(props) {
22648
22710
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
22649
22711
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
22650
22712
  const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
22651
- 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");
22713
+ 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");
22652
22714
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
22653
22715
  const isCycleRow = row.kind === "cycle";
22654
22716
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -22678,7 +22740,7 @@ function GroupedSidebar(props) {
22678
22740
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
22679
22741
  bold: isSelected || labelStyle.bold,
22680
22742
  inverse: false,
22681
- underline: isSelected && focused,
22743
+ underline: isSelected && !focused,
22682
22744
  wrap: wrapLabels ? "wrap" : "truncate",
22683
22745
  children: [
22684
22746
  " ",
@@ -23429,7 +23491,6 @@ function resolveKey(mode, key, ctx) {
23429
23491
  function resolveMain(key, ctx) {
23430
23492
  const { input } = key;
23431
23493
  const inMain = ctx.focusedColumn === "main";
23432
- if (key.ctrl && input === "z") return { type: "undo" };
23433
23494
  if (input === "q" || key.escape) {
23434
23495
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
23435
23496
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -23740,30 +23801,14 @@ function rejectNeedsConfirmation(graph, name, state2) {
23740
23801
  const ancestors = toReject.filter((n) => n !== name);
23741
23802
  return ancestors.length + toDeselect.length >= 2;
23742
23803
  }
23743
- function removeSlotChild(components, edge) {
23744
- return components.map(
23745
- (component) => component.name === edge.parent ? {
23746
- ...component,
23747
- slots: component.slots?.map((slot) => ({
23748
- ...slot,
23749
- allowedComponents: slot.allowedComponents.filter((name) => name !== edge.child)
23750
- }))
23751
- } : component
23752
- );
23753
- }
23754
- function withoutSlotChildren(components, removedEdges) {
23755
- return removedEdges.reduce(removeSlotChild, components);
23756
- }
23757
- function partitionDecisions(components, state2, removedEdges) {
23804
+ function partitionDecisions(components, state2) {
23758
23805
  const accepted = [];
23759
23806
  const rejected = [];
23760
23807
  for (const c2 of components) {
23761
23808
  if (state2.get(c2.name) === "accepted") accepted.push(c2.name);
23762
23809
  else rejected.push(c2.name);
23763
23810
  }
23764
- const rejectedNames = new Set(rejected);
23765
- const excludedSlotEdges = removedEdges.filter((e) => !rejectedNames.has(e.parent) && !rejectedNames.has(e.child));
23766
- return { accepted, rejected, excludedSlotEdges };
23811
+ return { accepted, rejected };
23767
23812
  }
23768
23813
  var init_state = __esm({
23769
23814
  "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/state.ts"() {
@@ -23775,15 +23820,10 @@ var init_state = __esm({
23775
23820
 
23776
23821
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
23777
23822
  import { useEffect as useEffect7, useMemo as useMemo2, useRef as useRef4, useState as useState12 } from "react";
23778
- function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
23823
+ function useScopeGate({ components, onConfirm, onQuit }) {
23779
23824
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
23780
23825
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
23781
23826
  const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
23782
- const [removedEdges, setRemovedEdges] = useState12([]);
23783
- const components = useMemo2(
23784
- () => withoutSlotChildren(loadedComponents, removedEdges),
23785
- [loadedComponents, removedEdges]
23786
- );
23787
23827
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
23788
23828
  const [focusedColumn, setFocusedColumn] = useState12("main");
23789
23829
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -23956,14 +23996,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
23956
23996
  return void 0;
23957
23997
  }
23958
23998
  };
23959
- const focusedNestedEdge = () => {
23960
- const row = visibleRows[safeCursor];
23961
- if (row?.kind !== "group-child" || !row.parentName || row.itemIdx < 0) return void 0;
23962
- const child = groupedItems[row.itemIdx]?.key;
23963
- return child ? { parent: row.parentName, child } : void 0;
23964
- };
23965
- const removeFromParentSlot = (edge) => setRemovedEdges((edges) => [...edges, edge]);
23966
- const undoSlotRemoval = () => setRemovedEdges((edges) => edges.slice(0, -1));
23967
23999
  const jumpCursorTo = (name) => {
23968
24000
  let idx = -1;
23969
24001
  for (let i = 0; i < visibleRows.length; i++) {
@@ -24063,7 +24095,7 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
24063
24095
  onQuit();
24064
24096
  return;
24065
24097
  case "confirm":
24066
- onConfirm(partitionDecisions(components, decisions, removedEdges));
24098
+ onConfirm(partitionDecisions(components, decisions));
24067
24099
  return;
24068
24100
  case "close-help":
24069
24101
  setShowHelp(false);
@@ -24116,11 +24148,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
24116
24148
  return;
24117
24149
  }
24118
24150
  case "reject": {
24119
- const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
24120
- if (edge) {
24121
- removeFromParentSlot(edge);
24122
- return;
24123
- }
24124
24151
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
24125
24152
  if (key) requestReject(key);
24126
24153
  return;
@@ -24128,9 +24155,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
24128
24155
  case "toggle-all":
24129
24156
  decide({ type: "toggle-all" });
24130
24157
  return;
24131
- case "undo":
24132
- undoSlotRemoval();
24133
- return;
24134
24158
  case "accept-unflagged":
24135
24159
  decide({ type: "accept-unflagged" });
24136
24160
  return;
@@ -27029,8 +27053,8 @@ function FieldEditor({
27029
27053
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE.warning, children: [
27030
27054
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE.warning, children: "FIELD EDITOR \u2014 no fields" }),
27031
27055
  /* @__PURE__ */ jsx27(Text23, { color: PALETTE.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify." }),
27032
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "There is nothing to edit here." }),
27033
- /* @__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" })
27056
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "You can add fields manually below or reject this component." }),
27057
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE.muted, children: "Enter to save \xB7 Esc to discard" })
27034
27058
  ] });
27035
27059
  }
27036
27060
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -27245,7 +27269,7 @@ function FieldEditor({
27245
27269
  children: [
27246
27270
  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." }),
27247
27271
  header,
27248
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
27272
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
27249
27273
  PropRow,
27250
27274
  {
27251
27275
  prop: currentProp,
@@ -28257,7 +28281,6 @@ function finalizeReviewSession(extractSessionId, components) {
28257
28281
  db.exec("ROLLBACK");
28258
28282
  throw error;
28259
28283
  }
28260
- removeSlotAllowedComponents(db, extractSessionId, [], toReject);
28261
28284
  } finally {
28262
28285
  db.close();
28263
28286
  }
@@ -30036,50 +30059,33 @@ function GenerateReviewStepView({
30036
30059
  const cycle = cycleRows[cyclesCursor];
30037
30060
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
30038
30061
  }, [cycleRows, cyclesCursor, components]);
30039
- const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
30062
+ const handleBreakEdge = (edge) => {
30063
+ const target = components.find((component) => component.key === edge.fromComponent);
30064
+ const slot = target?.entry.$slots?.[edge.slotName];
30065
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
30066
+ const nextEntry = {
30067
+ ...target.entry,
30068
+ $slots: {
30069
+ ...target.entry.$slots,
30070
+ [edge.slotName]: {
30071
+ ...slot,
30072
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
30073
+ }
30074
+ }
30075
+ };
30040
30076
  const next = components.map(
30041
- (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
30077
+ (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
30042
30078
  );
30043
30079
  setComponents(next);
30044
30080
  const db = openPipelineDb();
30045
30081
  try {
30046
- storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
30082
+ storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
30047
30083
  } finally {
30048
30084
  db.close();
30049
30085
  }
30050
30086
  recomputeCycles(next);
30051
30087
  livePreviewHook.trigger();
30052
- pushHistorySnapshot(next, historyLabel);
30053
- };
30054
- const handleBreakEdge = (edge) => {
30055
- const target = components.find((component) => component.key === edge.fromComponent);
30056
- const slot = target?.entry.$slots?.[edge.slotName];
30057
- if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
30058
- saveSlotChange(
30059
- target.key,
30060
- {
30061
- ...target.entry,
30062
- $slots: {
30063
- ...target.entry.$slots,
30064
- [edge.slotName]: {
30065
- ...slot,
30066
- $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
30067
- }
30068
- }
30069
- },
30070
- "break-cycle-edge"
30071
- );
30072
- };
30073
- const handleRemoveSlotChild = (parentKey, childKey) => {
30074
- const parent = components.find((component) => component.key === parentKey);
30075
- if (!parent?.entry.$slots) return;
30076
- const slots = Object.fromEntries(
30077
- Object.entries(parent.entry.$slots).map(([slotName, slot]) => [
30078
- slotName,
30079
- Array.isArray(slot.$allowedComponents) ? { ...slot, $allowedComponents: slot.$allowedComponents.filter((value) => value !== childKey) } : slot
30080
- ])
30081
- );
30082
- saveSlotChange(parentKey, { ...parent.entry, $slots: slots }, "remove-slot-child");
30088
+ pushHistorySnapshot(next, "break-cycle-edge");
30083
30089
  };
30084
30090
  const handleRejectComponent = (key) => {
30085
30091
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -30409,11 +30415,6 @@ function GenerateReviewStepView({
30409
30415
  if (input === "r") {
30410
30416
  const current = components[selectedIdx];
30411
30417
  if (!current) return;
30412
- const row = visibleRowsMemo[cursorRowIdx];
30413
- if (row?.kind === "group-child" && row.parentName) {
30414
- handleRemoveSlotChild(row.parentName, current.key);
30415
- return;
30416
- }
30417
30418
  handleRejectComponent(current.key);
30418
30419
  return;
30419
30420
  }
@@ -32364,7 +32365,7 @@ var init_save = __esm({
32364
32365
  writeFile: (path5, contents) => writeFile7(path5, contents),
32365
32366
  appendRun,
32366
32367
  buildSourceFingerprint,
32367
- sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
32368
+ sleep: (ms) => new Promise((resolve28) => setTimeout(resolve28, ms)),
32368
32369
  warn: (message) => process.stderr.write(message)
32369
32370
  });
32370
32371
  }
@@ -32915,13 +32916,48 @@ var init_debug_store = __esm({
32915
32916
  }
32916
32917
  });
32917
32918
 
32919
+ // packages/experience-design-system-cli/src/tui/help/file-locations.ts
32920
+ import { join as join26, resolve as resolve27 } from "node:path";
32921
+ function describeFileLocations({
32922
+ contentfulBaseDir,
32923
+ debugModeEnabled,
32924
+ currentSessionDir: currentSessionDir2
32925
+ }) {
32926
+ if (!debugModeEnabled) {
32927
+ return {
32928
+ debugLogs: "none while Debug Mode is off",
32929
+ importFiles: `${join26("<project>", ".contentful")}/ (tokens.json, components.json)`
32930
+ };
32931
+ }
32932
+ const base = contentfulBaseDir ? resolve27(contentfulBaseDir) : "<project>";
32933
+ const session = currentSessionDir2 ?? join26(base, ".contentful", "<date>-session-<n>");
32934
+ return {
32935
+ debugLogs: join26(session, "debug"),
32936
+ importFiles: `${join26(session, "dsi-import-<n>")}/ (tokens.json, components.json)`
32937
+ };
32938
+ }
32939
+ var init_file_locations = __esm({
32940
+ "packages/experience-design-system-cli/src/tui/help/file-locations.ts"() {
32941
+ "use strict";
32942
+ }
32943
+ });
32944
+
32918
32945
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
32919
32946
  async function readHelpInfo() {
32920
- const debugMode = await readDebugModeSetting();
32947
+ const [debugMode, settings] = await Promise.all([readDebugModeSetting(), readSettings2()]);
32948
+ const base = settings["contentfulBaseDir"];
32949
+ const locations = describeFileLocations({
32950
+ contentfulBaseDir: typeof base === "string" ? base : "",
32951
+ debugModeEnabled: debugMode.enabled,
32952
+ currentSessionDir: currentSessionDir()
32953
+ });
32921
32954
  return {
32922
32955
  storage: [
32923
32956
  { label: "Config folder", value: configRoot2() },
32924
- { label: "Settings file", value: configFilePath2() }
32957
+ { label: "Settings file", value: configFilePath2() },
32958
+ { label: "Agent settings", value: `${configFilePath2()} (keys: agent, agentModel, agents)` },
32959
+ { label: "Debug logs", value: locations.debugLogs },
32960
+ { label: "Import files", value: locations.importFiles }
32925
32961
  ],
32926
32962
  troubleshooting: [
32927
32963
  { label: "CLI version", value: readPackageVersion() },
@@ -32942,6 +32978,7 @@ var init_help_info = __esm({
32942
32978
  init_debug_store();
32943
32979
  init_debug_mode_store();
32944
32980
  init_version();
32981
+ init_file_locations();
32945
32982
  }
32946
32983
  });
32947
32984
 
@@ -32953,7 +32990,7 @@ function Section({ title, rows }) {
32953
32990
  return /* @__PURE__ */ jsxs43(Box42, { flexDirection: "column", children: [
32954
32991
  /* @__PURE__ */ jsx53(Text44, { bold: true, color: PALETTE.accent, children: title }),
32955
32992
  rows.map((row) => /* @__PURE__ */ jsxs43(Box42, { gap: 1, children: [
32956
- /* @__PURE__ */ jsx53(Box42, { width: 14, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
32993
+ /* @__PURE__ */ jsx53(Box42, { width: 16, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
32957
32994
  /* @__PURE__ */ jsx53(Text44, { children: row.value })
32958
32995
  ] }, row.label))
32959
32996
  ] });
@@ -33068,6 +33105,730 @@ var init_PageContainer3 = __esm({
33068
33105
  }
33069
33106
  });
33070
33107
 
33108
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-status.ts
33109
+ import { execFile as execFile2 } from "node:child_process";
33110
+ import { access as access6, constants } from "node:fs/promises";
33111
+ function effectiveBinary(name, savedBinary) {
33112
+ return savedBinary.trim() || AGENT_BINARIES[name];
33113
+ }
33114
+ function defaultModelLabel(name) {
33115
+ const model = DEFAULT_MODELS[name];
33116
+ return model && model !== "Auto" ? model : "chosen by the agent";
33117
+ }
33118
+ function resolveOnPath(binary) {
33119
+ if (binary.includes("/")) {
33120
+ return access6(binary, constants.X_OK).then(
33121
+ () => binary,
33122
+ () => null
33123
+ );
33124
+ }
33125
+ return new Promise((resolve28) => {
33126
+ execFile2(
33127
+ process.platform === "win32" ? "where" : "which",
33128
+ [binary],
33129
+ (error, stdout) => resolve28(error ? null : stdout.split("\n")[0]?.trim() ?? null)
33130
+ );
33131
+ });
33132
+ }
33133
+ function readVersion(binary) {
33134
+ return new Promise((resolve28) => {
33135
+ execFile2(binary, ["--version"], { timeout: VERSION_TIMEOUT_MS }, (error, stdout) => {
33136
+ const line = stdout.split("\n")[0]?.trim() ?? "";
33137
+ if (!error && line) resolve28(pass("version", line));
33138
+ else resolve28(fail3("version", "runs, but did not report a version"));
33139
+ });
33140
+ });
33141
+ }
33142
+ async function inspectAgent(name, binary) {
33143
+ const target = effectiveBinary(name, binary);
33144
+ const found = await resolveOnPath(target);
33145
+ if (!found) return [fail3("path", `\`${target}\` was not found or is not executable`)];
33146
+ const checks = [pass("path", found)];
33147
+ checks.push(await readVersion(found));
33148
+ if (name === "claude") {
33149
+ const auth = await withBinaryEnv(name, found, () => checkAgentAuth(name));
33150
+ checks.push(
33151
+ auth === "ok" ? pass("login", "logged in") : fail3("login", auth === "not-found" ? "binary not found" : `not logged in: ${LOGIN_HINTS.claude}`)
33152
+ );
33153
+ }
33154
+ return checks;
33155
+ }
33156
+ async function testAgent(name, binary, model) {
33157
+ const checks = await inspectAgent(name, binary);
33158
+ if (!checks.every((check) => check.step === "version" || check.ok)) return checks;
33159
+ const target = effectiveBinary(name, binary);
33160
+ const found = await resolveOnPath(target) ?? target;
33161
+ const started = Date.now();
33162
+ const result = await withBinaryEnv(
33163
+ name,
33164
+ found,
33165
+ () => createLocalCliAgentInvoker().invoke({
33166
+ agent: name,
33167
+ ...model.trim() ? { model: model.trim() } : {},
33168
+ prompt: TEST_PROMPT,
33169
+ timeoutMs: PROMPT_TIMEOUT_MS
33170
+ })
33171
+ );
33172
+ const seconds = ((Date.now() - started) / 1e3).toFixed(1);
33173
+ if (result.timedOut) {
33174
+ return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
33175
+ }
33176
+ if (result.exitCode !== 0) {
33177
+ const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
33178
+ return [...checks, fail3("prompt", reason)];
33179
+ }
33180
+ return [...checks, pass("prompt", `answered in ${seconds}s`)];
33181
+ }
33182
+ function statusFromChecks(name, checks, savedBinary) {
33183
+ if (checks.length === 0) return "checking";
33184
+ if (checks.some((check) => check.step === "path" && !check.ok)) {
33185
+ return savedBinary.trim() ? "not-found" : "not-configured";
33186
+ }
33187
+ const prompt = checks.find((check) => check.step === "prompt");
33188
+ if (prompt) {
33189
+ if (prompt.ok) return "ready";
33190
+ return prompt.timedOut ? "timed-out" : "test-failed";
33191
+ }
33192
+ const login = checks.find((check) => check.step === "login");
33193
+ if (login) return login.ok ? "ready" : "not-logged-in";
33194
+ return name === "claude" ? "ready" : "unknown";
33195
+ }
33196
+ function setupHint(name, status) {
33197
+ if (status === "not-configured") return `${INSTALL_HINTS[name]}, or set its command path in settings`;
33198
+ if (status === "not-found") return `${INSTALL_HINTS[name]}, or correct the command path in settings`;
33199
+ if (status === "not-logged-in") return LOGIN_HINTS[name];
33200
+ if (status === "test-failed") return `read the test message; if it is a login problem, ${LOGIN_HINTS[name]}`;
33201
+ if (status === "timed-out") return "it may be slow or waiting for input; run the test again, or try it in a terminal";
33202
+ if (status === "unknown") return "run a full test to confirm it is logged in";
33203
+ return "";
33204
+ }
33205
+ function testOutcome(checks) {
33206
+ const prompt = checks?.find((check) => check.step === "prompt");
33207
+ if (!prompt) return void 0;
33208
+ if (prompt.ok) return { ok: true, text: `Test passed: ${prompt.detail}` };
33209
+ if (prompt.timedOut) return { ok: false, text: `Test timed out: ${prompt.detail}` };
33210
+ return { ok: false, text: `Test failed: ${prompt.detail}` };
33211
+ }
33212
+ function modelLine(name, savedModel) {
33213
+ const model = savedModel.trim();
33214
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
33215
+ }
33216
+ function panelRows(name, checks, settings) {
33217
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
33218
+ const status = statusFromChecks(name, checks, settings.binary);
33219
+ const path5 = checks.find((check) => check.step === "path");
33220
+ if (!path5?.ok) {
33221
+ const rows2 = [
33222
+ {
33223
+ label: "Command",
33224
+ value: settings.binary.trim() ? path5?.detail ?? "not found" : "not found on your PATH",
33225
+ tone: settings.binary.trim() ? "bad" : "muted"
33226
+ }
33227
+ ];
33228
+ const hint2 = setupHint(name, status);
33229
+ if (hint2) rows2.push({ label: "Setup", value: hint2, tone: "muted" });
33230
+ return rows2;
33231
+ }
33232
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
33233
+ const version = checks.find((check) => check.step === "version");
33234
+ if (version?.ok) rows.push({ label: "Version", value: version.detail, tone: "ok" });
33235
+ rows.push({ label: "Model", value: modelLine(name, settings.model), tone: "muted" });
33236
+ const hint = setupHint(name, status);
33237
+ if (hint) rows.push({ label: "Setup", value: hint, tone: "muted" });
33238
+ return rows;
33239
+ }
33240
+ function statusRows(_name, checks, savedBinary) {
33241
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
33242
+ const find = (step) => checks.find((check) => check.step === step);
33243
+ const path5 = find("path");
33244
+ if (!path5?.ok) {
33245
+ if (savedBinary.trim()) return [{ label: "Command", value: path5?.detail ?? "not found", tone: "bad" }];
33246
+ return [{ label: "Command", value: "not configured (not on the PATH)", tone: "muted" }];
33247
+ }
33248
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
33249
+ const version = find("version");
33250
+ if (version) {
33251
+ rows.push({
33252
+ label: "Version",
33253
+ value: version.ok ? version.detail : "could not be read",
33254
+ tone: version.ok ? "ok" : "muted"
33255
+ });
33256
+ }
33257
+ const login = find("login");
33258
+ const prompt = find("prompt");
33259
+ if (login) {
33260
+ rows.push({ label: "Login", value: login.detail, tone: login.ok ? "ok" : "bad" });
33261
+ } else if (prompt) {
33262
+ rows.push({
33263
+ label: "Login",
33264
+ value: prompt.ok ? "confirmed by the test" : prompt.timedOut ? "unknown (the test timed out)" : "see the test result",
33265
+ tone: prompt.ok ? "ok" : prompt.timedOut ? "muted" : "bad"
33266
+ });
33267
+ } else {
33268
+ rows.push({ label: "Login", value: "not checked (use Run test)", tone: "muted" });
33269
+ }
33270
+ if (prompt) rows.push({ label: "Test", value: prompt.detail, tone: prompt.ok ? "ok" : "bad" });
33271
+ return rows;
33272
+ }
33273
+ async function withBinaryEnv(name, binary, run) {
33274
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
33275
+ const previous = process.env[key];
33276
+ process.env[key] = binary;
33277
+ try {
33278
+ return await run();
33279
+ } finally {
33280
+ if (previous === void 0) delete process.env[key];
33281
+ else process.env[key] = previous;
33282
+ }
33283
+ }
33284
+ var VERSION_TIMEOUT_MS, PROMPT_TIMEOUT_MS, TEST_PROMPT, INSTALL_HINTS, LOGIN_HINTS, fail3, pass, LIST_STATUS;
33285
+ var init_agent_status = __esm({
33286
+ "packages/experience-design-system-cli/src/tui/settings/agents/agent-status.ts"() {
33287
+ "use strict";
33288
+ init_src4();
33289
+ VERSION_TIMEOUT_MS = 5e3;
33290
+ PROMPT_TIMEOUT_MS = 6e4;
33291
+ TEST_PROMPT = "Reply with the single word: ok";
33292
+ INSTALL_HINTS = {
33293
+ claude: "npm install -g @anthropic-ai/claude-code",
33294
+ codex: "npm install -g @openai/codex",
33295
+ opencode: "npm install -g opencode-ai",
33296
+ cursor: "install Cursor\u2019s `cursor-agent` command",
33297
+ copilot: "npm install -g @github/copilot"
33298
+ };
33299
+ LOGIN_HINTS = {
33300
+ claude: "run `claude login`",
33301
+ codex: "set OPENAI_API_KEY, or sign in with a ChatGPT account",
33302
+ opencode: "run `opencode auth`",
33303
+ cursor: "sign in from Cursor",
33304
+ copilot: "run `copilot` and sign in"
33305
+ };
33306
+ fail3 = (step, detail) => ({ step, ok: false, detail });
33307
+ pass = (step, detail) => ({ step, ok: true, detail });
33308
+ LIST_STATUS = {
33309
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
33310
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
33311
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
33312
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
33313
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
33314
+ "test-failed": { symbol: "\u2717", text: "test failed", tone: "bad" },
33315
+ "timed-out": { symbol: "\u2717", text: "test timed out", tone: "bad" },
33316
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
33317
+ };
33318
+ }
33319
+ });
33320
+
33321
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
33322
+ import { Text as Text46 } from "ink";
33323
+ import { jsx as jsx55 } from "react/jsx-runtime";
33324
+ function AgentStatusBadge({
33325
+ name,
33326
+ checks,
33327
+ binary
33328
+ }) {
33329
+ const { symbol, text, tone } = LIST_STATUS[checks ? statusFromChecks(name, checks, binary) : "checking"];
33330
+ return /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[tone], children: `${symbol} ${text}` });
33331
+ }
33332
+ var TONE_COLOR;
33333
+ var init_AgentStatusBadge = __esm({
33334
+ "packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx"() {
33335
+ "use strict";
33336
+ init_theme();
33337
+ init_agent_status();
33338
+ TONE_COLOR = {
33339
+ ok: PALETTE.success,
33340
+ bad: PALETTE.error,
33341
+ muted: PALETTE.muted
33342
+ };
33343
+ }
33344
+ });
33345
+
33346
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
33347
+ import { useEffect as useEffect22, useState as useState29 } from "react";
33348
+ import { Box as Box44, Text as Text47, useInput as useInput11 } from "ink";
33349
+ import TextInput4 from "ink-text-input";
33350
+ import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
33351
+ function Row2({
33352
+ pointer,
33353
+ label,
33354
+ labelProps,
33355
+ children
33356
+ }) {
33357
+ return /* @__PURE__ */ jsxs45(Box44, { children: [
33358
+ /* @__PURE__ */ jsx56(Box44, { width: POINTER_WIDTH, flexShrink: 0, children: pointer }),
33359
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH + LABEL_GAP, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, ...labelProps, children: label }) }),
33360
+ children
33361
+ ] });
33362
+ }
33363
+ function Section2({
33364
+ title,
33365
+ note,
33366
+ interactive = false,
33367
+ children
33368
+ }) {
33369
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", marginTop: 1, children: [
33370
+ /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
33371
+ /* @__PURE__ */ jsx56(Text47, { bold: true, color: interactive ? PALETTE.accent : PALETTE.muted, children: title }),
33372
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: `\xB7 ${note}` })
33373
+ ] }),
33374
+ children
33375
+ ] });
33376
+ }
33377
+ function AgentDetail({
33378
+ name,
33379
+ config,
33380
+ setConfig,
33381
+ onBack
33382
+ }) {
33383
+ const settings = config.agents[name];
33384
+ const [focusIndex, setFocusIndex] = useState29(0);
33385
+ const [editing, setEditing] = useState29(false);
33386
+ const [valueBeforeEdit, setValueBeforeEdit] = useState29("");
33387
+ const [saving, setSaving] = useState29(false);
33388
+ const [testing, setTesting] = useState29(false);
33389
+ const [notice, setNotice] = useState29(null);
33390
+ const [checks, setChecks] = useState29(void 0);
33391
+ useEffect22(() => {
33392
+ let active = true;
33393
+ setChecks(void 0);
33394
+ void inspectAgent(name, settings.binary).then((result) => active && setChecks(result));
33395
+ return () => {
33396
+ active = false;
33397
+ };
33398
+ }, [name, settings.binary]);
33399
+ const setField = (field, value) => {
33400
+ setConfig({ ...config, agents: { ...config.agents, [name]: { ...settings, [field]: value } } });
33401
+ setNotice(null);
33402
+ };
33403
+ const save = () => {
33404
+ setSaving(true);
33405
+ setNotice(null);
33406
+ writeAgentConfig(config).then(() => {
33407
+ applyBinaryOverrides(config);
33408
+ setNotice({ kind: "success", text: `Saved: ${AGENT_LABELS[name]} settings are written to config.json` });
33409
+ }).catch(
33410
+ (err) => setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` })
33411
+ ).finally(() => setSaving(false));
33412
+ };
33413
+ const runTest = () => {
33414
+ setTesting(true);
33415
+ setNotice(null);
33416
+ testAgent(name, settings.binary, settings.model).then((result) => {
33417
+ setChecks(result);
33418
+ const outcome = testOutcome(result);
33419
+ setNotice(
33420
+ outcome ? { kind: outcome.ok ? "success" : "error", text: outcome.text } : { kind: "error", text: "Test not run: the agent could not be started (see Status)" }
33421
+ );
33422
+ }).catch(
33423
+ (err) => setNotice({ kind: "error", text: `Test could not run: ${err instanceof Error ? err.message : String(err)}` })
33424
+ ).finally(() => setTesting(false));
33425
+ };
33426
+ const focused = FOCUS_ORDER[focusIndex];
33427
+ const focusedField = focused === "test" ? null : focused;
33428
+ useInput11((input, key) => {
33429
+ if (saving || testing) return;
33430
+ if (editing) {
33431
+ if (key.escape && focusedField) {
33432
+ setField(focusedField, valueBeforeEdit);
33433
+ setEditing(false);
33434
+ }
33435
+ return;
33436
+ }
33437
+ if (key.escape || input === "q") {
33438
+ onBack();
33439
+ return;
33440
+ }
33441
+ if (input === "s") {
33442
+ save();
33443
+ return;
33444
+ }
33445
+ if (key.upArrow) {
33446
+ setFocusIndex((i) => (i - 1 + FOCUS_ORDER.length) % FOCUS_ORDER.length);
33447
+ return;
33448
+ }
33449
+ if (key.downArrow || key.tab) {
33450
+ setFocusIndex((i) => (i + 1) % FOCUS_ORDER.length);
33451
+ return;
33452
+ }
33453
+ if (input === "c" && focusedField) {
33454
+ setField(focusedField, "");
33455
+ return;
33456
+ }
33457
+ if (key.return) {
33458
+ if (focusedField) {
33459
+ setValueBeforeEdit(settings[focusedField]);
33460
+ setEditing(true);
33461
+ } else {
33462
+ runTest();
33463
+ }
33464
+ }
33465
+ });
33466
+ const status = checks ? statusFromChecks(name, checks, settings.binary) : "checking";
33467
+ const hint = setupHint(name, status);
33468
+ const pointer = (isFocused) => /* @__PURE__ */ jsx56(Text47, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
33469
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33470
+ /* @__PURE__ */ jsx56(Text47, { bold: true, children: AGENT_LABELS[name] }),
33471
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
33472
+ (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: [
33473
+ notice.kind === "success" ? "\u2713" : "\u2717",
33474
+ " ",
33475
+ notice.text
33476
+ ] }) }),
33477
+ /* @__PURE__ */ jsxs45(Section2, { title: "CONFIGURE", note: "you can change these", interactive: true, children: [
33478
+ FIELDS2.map((field) => {
33479
+ const isFocused = focused === field;
33480
+ const value = settings[field];
33481
+ 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) });
33482
+ return /* @__PURE__ */ jsx56(
33483
+ Row2,
33484
+ {
33485
+ pointer: pointer(isFocused),
33486
+ label: FIELD_LABEL[field],
33487
+ labelProps: { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted },
33488
+ children: display
33489
+ },
33490
+ field
33491
+ );
33492
+ }),
33493
+ /* @__PURE__ */ jsx56(
33494
+ Row2,
33495
+ {
33496
+ pointer: pointer(focused === "test"),
33497
+ label: "Run test",
33498
+ labelProps: { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted },
33499
+ children: /* @__PURE__ */ jsx56(Text47, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
33500
+ }
33501
+ )
33502
+ ] }),
33503
+ /* @__PURE__ */ jsxs45(Section2, { title: "STATUS", note: "read only", children: [
33504
+ 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)),
33505
+ hint && /* @__PURE__ */ jsx56(Row2, { pointer: null, label: "Setup", children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: hint }) })
33506
+ ] }),
33507
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
33508
+ /* @__PURE__ */ jsx56(
33509
+ ControlHints,
33510
+ {
33511
+ hints: editing ? [
33512
+ { keys: "type", label: "edit" },
33513
+ { keys: "\u2190/\u2192", label: "move cursor" },
33514
+ { keys: "\u23CE", label: "done" },
33515
+ { keys: "Esc", label: "cancel edit" }
33516
+ ] : [
33517
+ { keys: "\u2191/\u2193", label: "move" },
33518
+ { keys: "\u23CE", label: focusedField ? "edit" : "run test" },
33519
+ ...focusedField ? [{ keys: "c", label: "clear" }] : [],
33520
+ { keys: "s", label: "save" },
33521
+ { keys: "Esc/q", label: "back without saving" }
33522
+ ]
33523
+ }
33524
+ )
33525
+ ] });
33526
+ }
33527
+ var FOCUS_ORDER, FIELDS2, FIELD_LABEL, LABEL_WIDTH, LABEL_GAP, POINTER_WIDTH, fieldHint;
33528
+ var init_AgentDetail = __esm({
33529
+ "packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx"() {
33530
+ "use strict";
33531
+ init_theme();
33532
+ init_control_hints();
33533
+ init_agent_store();
33534
+ init_agent_status();
33535
+ init_AgentStatusBadge();
33536
+ init_apply_binary_overrides();
33537
+ FOCUS_ORDER = ["binary", "model", "test"];
33538
+ FIELDS2 = ["binary", "model"];
33539
+ FIELD_LABEL = { binary: "Command path", model: "Model" };
33540
+ LABEL_WIDTH = "Command path".length;
33541
+ LABEL_GAP = 2;
33542
+ POINTER_WIDTH = 2;
33543
+ fieldHint = (name, field) => field === "binary" ? `(empty: \`${AGENT_HINTS[name]}\` from the PATH)` : `(empty: ${defaultModelLabel(name)})`;
33544
+ }
33545
+ });
33546
+
33547
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
33548
+ import { useEffect as useEffect23, useState as useState30 } from "react";
33549
+ import { Box as Box45, Text as Text48, useInput as useInput12 } from "ink";
33550
+ import { Fragment as Fragment17, jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
33551
+ function AgentsScreen({ onDone }) {
33552
+ const [config, setConfig] = useState30(null);
33553
+ const [focus, setFocus] = useState30(0);
33554
+ const [open, setOpen] = useState30(null);
33555
+ const [notice, setNotice] = useState30(null);
33556
+ const [saving, setSaving] = useState30(false);
33557
+ const [checks, setChecks] = useState30({});
33558
+ const inspectAll = (loaded) => {
33559
+ for (const name of AGENT_NAMES) {
33560
+ void inspectAgent(name, loaded.agents[name].binary).then(
33561
+ (result) => setChecks((previous) => ({ ...previous, [name]: result }))
33562
+ );
33563
+ }
33564
+ };
33565
+ useEffect23(() => {
33566
+ void readAgentConfig().then((loaded) => {
33567
+ setConfig(loaded);
33568
+ inspectAll(loaded);
33569
+ startDebugRun({
33570
+ flow: "settings/agents",
33571
+ step: "01-agents",
33572
+ menuOption: "Configuration > Agents",
33573
+ inputs: { default_agent: loaded.defaultAgent }
33574
+ });
33575
+ });
33576
+ }, []);
33577
+ const makeDefault = (name) => {
33578
+ if (!config || saving) return;
33579
+ if (name === config.defaultAgent) {
33580
+ setNotice({ kind: "success", text: `${AGENT_LABELS[name]} is already the default agent` });
33581
+ return;
33582
+ }
33583
+ setSaving(true);
33584
+ setNotice(null);
33585
+ writeAgentConfig({ ...config, defaultAgent: name }).then(() => {
33586
+ setConfig((current) => current ? { ...current, defaultAgent: name } : current);
33587
+ setNotice({ kind: "success", text: `Default agent is now ${AGENT_LABELS[name]}` });
33588
+ }).catch(
33589
+ (err) => setNotice({
33590
+ kind: "error",
33591
+ text: `Default agent not changed: ${err instanceof Error ? err.message : String(err)}`
33592
+ })
33593
+ ).finally(() => setSaving(false));
33594
+ };
33595
+ useInput12((input, key) => {
33596
+ if (!config || open || saving) return;
33597
+ const focused = AGENT_NAMES[focus];
33598
+ if (key.upArrow || key.downArrow || key.tab) setNotice(null);
33599
+ if (key.upArrow) {
33600
+ setFocus((i) => (i - 1 + AGENT_NAMES.length) % AGENT_NAMES.length);
33601
+ return;
33602
+ }
33603
+ if (key.downArrow || key.tab) {
33604
+ setFocus((i) => (i + 1) % AGENT_NAMES.length);
33605
+ return;
33606
+ }
33607
+ if (key.return) {
33608
+ makeDefault(focused);
33609
+ return;
33610
+ }
33611
+ if (key.rightArrow) {
33612
+ setNotice(null);
33613
+ setOpen(focused);
33614
+ return;
33615
+ }
33616
+ if (key.escape || input === "q") {
33617
+ void finishDebugRun({ outputs: { default_agent: config.defaultAgent }, status: "success", exitMethod: "saved" });
33618
+ onDone();
33619
+ }
33620
+ });
33621
+ if (!config) {
33622
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33623
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
33624
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33625
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "Loading..." })
33626
+ ] });
33627
+ }
33628
+ if (open) {
33629
+ return /* @__PURE__ */ jsx57(
33630
+ AgentDetail,
33631
+ {
33632
+ name: open,
33633
+ config,
33634
+ setConfig,
33635
+ onBack: () => {
33636
+ setOpen(null);
33637
+ void readAgentConfig().then((saved) => {
33638
+ setConfig(saved);
33639
+ inspectAll(saved);
33640
+ });
33641
+ }
33642
+ }
33643
+ );
33644
+ }
33645
+ const focusedAgent = AGENT_NAMES[focus];
33646
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33647
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
33648
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "The coding agent the CLI runs, and what was found for each one." }),
33649
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33650
+ /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
33651
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Default agent" }),
33652
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: AGENT_LABELS[config.defaultAgent] }),
33653
+ saving && /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "\u2026 saving" })
33654
+ ] }),
33655
+ /* @__PURE__ */ jsxs46(Box45, { marginTop: 1, gap: 1, children: [
33656
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33657
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33658
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "AGENT" }) }),
33659
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "STATUS" })
33660
+ ] }),
33661
+ AGENT_NAMES.map((name) => {
33662
+ const isFocused = focusedAgent === name;
33663
+ return /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
33664
+ /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " }),
33665
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: name === config.defaultAgent ? "\u2605" : " " }),
33666
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[name] }) }),
33667
+ /* @__PURE__ */ jsx57(AgentStatusBadge, { name, checks: checks[name], binary: config.agents[name].binary })
33668
+ ] }, name);
33669
+ }),
33670
+ /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", marginTop: 1, children: [
33671
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: `\u2500 ${AGENT_LABELS[focusedAgent]} ${"\u2500".repeat(30)}` }),
33672
+ panelRows(focusedAgent, checks[focusedAgent], config.agents[focusedAgent]).map((row) => /* @__PURE__ */ jsxs46(Box45, { gap: 1, paddingLeft: 1, children: [
33673
+ /* @__PURE__ */ jsx57(Box45, { width: PANEL_LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: row.label }) }),
33674
+ /* @__PURE__ */ jsx57(Text48, { color: TONE_COLOR[row.tone], children: row.value })
33675
+ ] }, row.label))
33676
+ ] }),
33677
+ notice && /* @__PURE__ */ jsxs46(Fragment17, { children: [
33678
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33679
+ /* @__PURE__ */ jsxs46(Text48, { bold: true, color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
33680
+ notice.kind === "success" ? "\u2713" : "\u2717",
33681
+ " ",
33682
+ notice.text
33683
+ ] })
33684
+ ] }),
33685
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33686
+ /* @__PURE__ */ jsx57(
33687
+ ControlHints,
33688
+ {
33689
+ hints: [
33690
+ { keys: "\u2191/\u2193", label: "move" },
33691
+ { keys: "\u23CE", label: "make default" },
33692
+ { keys: "\u2192", label: "settings and test" },
33693
+ { keys: "Esc/q", label: "back" }
33694
+ ]
33695
+ }
33696
+ )
33697
+ ] });
33698
+ }
33699
+ var NAME_WIDTH, PANEL_LABEL_WIDTH;
33700
+ var init_AgentScreens = __esm({
33701
+ "packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx"() {
33702
+ "use strict";
33703
+ init_src4();
33704
+ init_theme();
33705
+ init_control_hints();
33706
+ init_debug_store();
33707
+ init_agent_store();
33708
+ init_agent_status();
33709
+ init_AgentDetail();
33710
+ init_AgentStatusBadge();
33711
+ NAME_WIDTH = 16;
33712
+ PANEL_LABEL_WIDTH = "Command".length;
33713
+ }
33714
+ });
33715
+
33716
+ // packages/experience-design-system-cli/src/tui/settings/shared/FieldForm.tsx
33717
+ import { useState as useState31 } from "react";
33718
+ import { Box as Box46, Text as Text49, useInput as useInput13 } from "ink";
33719
+ import TextInput5 from "ink-text-input";
33720
+ import { Fragment as Fragment18, jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
33721
+ function FieldForm({
33722
+ title,
33723
+ subtitle,
33724
+ fields,
33725
+ values,
33726
+ onChange,
33727
+ onSave,
33728
+ onQuit,
33729
+ notice,
33730
+ busy = false,
33731
+ footer
33732
+ }) {
33733
+ const [active, setActive] = useState31(0);
33734
+ const [editing, setEditing] = useState31(false);
33735
+ const [valueBeforeEdit, setValueBeforeEdit] = useState31("");
33736
+ const labelWidth = Math.max(...fields.map((field) => field.label.length));
33737
+ const current = fields[active];
33738
+ useInput13((input, key) => {
33739
+ if (busy) return;
33740
+ if (editing) {
33741
+ if (key.escape) {
33742
+ onChange(current.key, valueBeforeEdit);
33743
+ setEditing(false);
33744
+ }
33745
+ return;
33746
+ }
33747
+ if (key.escape || input === "q") {
33748
+ onQuit();
33749
+ return;
33750
+ }
33751
+ if (input === "s") {
33752
+ onSave();
33753
+ return;
33754
+ }
33755
+ if (input === "c") {
33756
+ onChange(current.key, "");
33757
+ return;
33758
+ }
33759
+ if (key.tab || key.downArrow) {
33760
+ setActive((i) => (i + 1) % fields.length);
33761
+ return;
33762
+ }
33763
+ if (key.upArrow) {
33764
+ setActive((i) => (i - 1 + fields.length) % fields.length);
33765
+ return;
33766
+ }
33767
+ if (key.return) {
33768
+ setValueBeforeEdit(values[current.key]);
33769
+ setEditing(true);
33770
+ }
33771
+ });
33772
+ return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33773
+ /* @__PURE__ */ jsx58(Text49, { bold: true, children: title }),
33774
+ subtitle && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: subtitle }),
33775
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
33776
+ /* @__PURE__ */ jsx58(Box46, { flexDirection: "column", children: fields.map((field, index) => {
33777
+ const isActive = index === active;
33778
+ const value = values[field.key];
33779
+ const display = field.masked ? "\u2022".repeat(value.length) : value;
33780
+ return /* @__PURE__ */ jsxs47(Box46, { gap: 1, children: [
33781
+ /* @__PURE__ */ jsx58(Text49, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
33782
+ /* @__PURE__ */ jsx58(Box46, { width: labelWidth, flexShrink: 0, children: /* @__PURE__ */ jsx58(Text49, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: field.label }) }),
33783
+ isActive && editing ? /* @__PURE__ */ jsx58(
33784
+ TextInput5,
33785
+ {
33786
+ value,
33787
+ onChange: (next) => onChange(field.key, next),
33788
+ onSubmit: () => setEditing(false),
33789
+ mask: field.masked ? "\u2022" : void 0
33790
+ }
33791
+ ) : /* @__PURE__ */ jsx58(Text49, { bold: !!display, children: display || (field.hint ? "" : /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "(empty)" })) }),
33792
+ field.hint && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: field.hint })
33793
+ ] }, field.key);
33794
+ }) }),
33795
+ notice && /* @__PURE__ */ jsxs47(Fragment18, { children: [
33796
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
33797
+ /* @__PURE__ */ jsxs47(Text49, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
33798
+ notice.kind === "success" ? "\u2713" : "\u2717",
33799
+ " ",
33800
+ notice.text
33801
+ ] })
33802
+ ] }),
33803
+ footer,
33804
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
33805
+ /* @__PURE__ */ jsx58(
33806
+ ControlHints,
33807
+ {
33808
+ hints: editing ? [
33809
+ { keys: "type", label: "edit" },
33810
+ { keys: "\u2190/\u2192", label: "move cursor" },
33811
+ { keys: "\u23CE", label: "done" },
33812
+ { keys: "Esc", label: "cancel edit" }
33813
+ ] : [
33814
+ { keys: "\u2191/\u2193", label: "move" },
33815
+ { keys: "\u23CE", label: "edit" },
33816
+ { keys: "c", label: "clear" },
33817
+ { keys: "s", label: "save" },
33818
+ { keys: "Esc/q", label: "back without saving" }
33819
+ ]
33820
+ }
33821
+ )
33822
+ ] });
33823
+ }
33824
+ var init_FieldForm = __esm({
33825
+ "packages/experience-design-system-cli/src/tui/settings/shared/FieldForm.tsx"() {
33826
+ "use strict";
33827
+ init_theme();
33828
+ init_control_hints();
33829
+ }
33830
+ });
33831
+
33071
33832
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
33072
33833
  async function readCredentials() {
33073
33834
  const store = await readV1Store();
@@ -33099,11 +33860,10 @@ var init_config_store = __esm({
33099
33860
  }
33100
33861
  });
33101
33862
 
33102
- // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
33103
- import { useEffect as useEffect22, useState as useState29 } from "react";
33104
- import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
33105
- import TextInput4 from "ink-text-input";
33106
- import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
33863
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx
33864
+ import { useEffect as useEffect24, useState as useState32 } from "react";
33865
+ import { Box as Box47, Text as Text50 } from "ink";
33866
+ import { jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
33107
33867
  function debugFields(config) {
33108
33868
  return {
33109
33869
  space_id: config?.spaceId ?? "",
@@ -33115,189 +33875,159 @@ function debugFields(config) {
33115
33875
  contentful_base_dir: config?.contentfulBaseDir ?? ""
33116
33876
  };
33117
33877
  }
33118
- function ConfigurationScreen({ onDone }) {
33119
- const [stage, setStage] = useState29("loading");
33120
- const [config, setConfig] = useState29(null);
33121
- const [activeField, setActiveField] = useState29("spaceId");
33122
- const [notice, setNotice] = useState29(null);
33123
- const [lastSaved, setLastSaved] = useState29(null);
33124
- const [editing, setEditing] = useState29(false);
33125
- const [valueBeforeEdit, setValueBeforeEdit] = useState29("");
33126
- useEffect22(() => {
33127
- readCredentials().then((cfg) => {
33878
+ function ProjectConfigScreen({ onDone }) {
33879
+ const [config, setConfig] = useState32(null);
33880
+ const [saving, setSaving] = useState32(false);
33881
+ const [notice, setNotice] = useState32(null);
33882
+ const [lastSaved, setLastSaved] = useState32(null);
33883
+ useEffect24(() => {
33884
+ void readCredentials().then((cfg) => {
33128
33885
  setConfig(cfg);
33129
- setStage("form");
33130
33886
  startDebugRun({
33131
33887
  flow: "settings/contentful-configuration",
33132
33888
  step: "01-configuration",
33133
- menuOption: "Configuration",
33889
+ menuOption: "Configuration > Project",
33134
33890
  inputs: debugFields(cfg)
33135
33891
  });
33136
33892
  });
33137
33893
  }, []);
33138
- function fieldValue(field) {
33139
- if (!config) return "";
33140
- return config[field] || "";
33141
- }
33142
- function setFieldValue(field, value) {
33143
- if (!config) return;
33144
- setConfig({ ...config, [field]: value });
33145
- setNotice(null);
33894
+ if (!config) {
33895
+ return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33896
+ /* @__PURE__ */ jsx59(Text50, { bold: true, children: "Project" }),
33897
+ /* @__PURE__ */ jsx59(Text50, { children: " " }),
33898
+ /* @__PURE__ */ jsx59(Text50, { color: PALETTE.accent, children: "Loading..." })
33899
+ ] });
33146
33900
  }
33147
- function handleSave() {
33148
- if (!config) return;
33149
- setStage("saving");
33901
+ const save = () => {
33902
+ setSaving(true);
33150
33903
  setNotice(null);
33151
33904
  writeCredentials(config).then(() => {
33152
33905
  setLastSaved(config);
33153
33906
  if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
33154
- setNotice({ kind: "success", text: "Configuration saved" });
33155
- setStage("form");
33907
+ setNotice({ kind: "success", text: "Project settings saved" });
33156
33908
  }).catch((err) => {
33157
33909
  setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
33158
- setStage("form");
33159
- });
33160
- }
33161
- function quit() {
33910
+ }).finally(() => setSaving(false));
33911
+ };
33912
+ const quit = () => {
33162
33913
  void finishDebugRun(
33163
33914
  lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
33164
33915
  );
33165
33916
  onDone();
33166
- }
33167
- useInput11((input, key) => {
33168
- if (stage === "loading" || stage === "saving") return;
33169
- if (editing) {
33170
- if (key.escape) {
33171
- setFieldValue(activeField, valueBeforeEdit);
33172
- setEditing(false);
33173
- }
33174
- return;
33175
- }
33176
- if (key.escape || input === "q") {
33177
- quit();
33178
- return;
33179
- }
33180
- if (input === "s") {
33181
- handleSave();
33182
- return;
33183
- }
33184
- if (input === "c") {
33185
- setFieldValue(activeField, "");
33186
- return;
33917
+ };
33918
+ return /* @__PURE__ */ jsx59(
33919
+ FieldForm,
33920
+ {
33921
+ title: "Project",
33922
+ subtitle: "The Contentful space and where the CLI keeps its files.",
33923
+ fields: FIELDS3,
33924
+ values: valuesOf(config),
33925
+ onChange: (key, value) => {
33926
+ setConfig({ ...config, [key]: value });
33927
+ setNotice(null);
33928
+ },
33929
+ onSave: save,
33930
+ onQuit: quit,
33931
+ notice,
33932
+ busy: saving
33187
33933
  }
33188
- if (key.tab || key.downArrow) {
33189
- const idx = FIELD_ORDER.indexOf(activeField);
33190
- setActiveField(FIELD_ORDER[(idx + 1) % FIELD_ORDER.length]);
33934
+ );
33935
+ }
33936
+ var FIELDS3, valuesOf;
33937
+ var init_ProjectConfigScreen = __esm({
33938
+ "packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx"() {
33939
+ "use strict";
33940
+ init_theme();
33941
+ init_debug_store();
33942
+ init_FieldForm();
33943
+ init_config_store();
33944
+ FIELDS3 = [
33945
+ { key: "spaceId", label: "Space ID" },
33946
+ { key: "environmentId", label: "Environment ID" },
33947
+ { key: "cmaToken", label: "CMA Token", masked: true },
33948
+ { key: "host", label: "API Host" },
33949
+ { key: "defaultComponentDir", label: "Default component directory" },
33950
+ { key: "defaultTokenFile", label: "Default token file" },
33951
+ { key: "contentfulBaseDir", label: "Root Project Directory", hint: "(where .contentful goes)" }
33952
+ ];
33953
+ valuesOf = (config) => Object.fromEntries(FIELDS3.map(({ key }) => [key, config[key] || ""]));
33954
+ }
33955
+ });
33956
+
33957
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
33958
+ import { useState as useState33 } from "react";
33959
+ import { Box as Box48, Text as Text51, useInput as useInput14 } from "ink";
33960
+ import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
33961
+ function ConfigurationScreen({ onDone }) {
33962
+ const [focus, setFocus] = useState33(0);
33963
+ const [open, setOpen] = useState33(null);
33964
+ const close = () => setOpen(null);
33965
+ useInput14((input, key) => {
33966
+ if (open) return;
33967
+ if (key.upArrow) {
33968
+ setFocus((i) => (i - 1 + SECTIONS.length) % SECTIONS.length);
33191
33969
  return;
33192
33970
  }
33193
- if (key.upArrow) {
33194
- const idx = FIELD_ORDER.indexOf(activeField);
33195
- setActiveField(FIELD_ORDER[(idx - 1 + FIELD_ORDER.length) % FIELD_ORDER.length]);
33971
+ if (key.downArrow || key.tab) {
33972
+ setFocus((i) => (i + 1) % SECTIONS.length);
33196
33973
  return;
33197
33974
  }
33198
33975
  if (key.return) {
33199
- setValueBeforeEdit(fieldValue(activeField));
33200
- setEditing(true);
33976
+ setOpen(SECTIONS[focus].id);
33977
+ return;
33201
33978
  }
33979
+ if (key.escape || input === "q") onDone();
33202
33980
  });
33203
- if (stage === "loading") {
33204
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33205
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
33206
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33207
- /* @__PURE__ */ jsx55(Text46, { color: PALETTE.accent, children: "Loading..." })
33208
- ] });
33209
- }
33210
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33211
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
33212
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33213
- /* @__PURE__ */ jsx55(Box44, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
33214
- const isActive = activeField === field;
33215
- const value = fieldValue(field);
33216
- const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
33217
- return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
33218
- /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
33219
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
33220
- isActive && editing ? /* @__PURE__ */ jsx55(
33221
- TextInput4,
33222
- {
33223
- value,
33224
- onChange: (next) => setFieldValue(field, next),
33225
- onSubmit: () => setEditing(false),
33226
- mask: field === "cmaToken" ? "\u2022" : void 0
33227
- }
33228
- ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
33229
- FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
33230
- ] }, field);
33231
- }) }),
33232
- notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
33233
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33234
- /* @__PURE__ */ jsxs45(Text46, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
33235
- notice.kind === "success" ? "\u2713" : "\u2717",
33236
- " ",
33237
- notice.text
33238
- ] })
33239
- ] }),
33240
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33241
- /* @__PURE__ */ jsx55(
33981
+ if (open === "project") return /* @__PURE__ */ jsx60(ProjectConfigScreen, { onDone: close });
33982
+ if (open === "agents") return /* @__PURE__ */ jsx60(AgentsScreen, { onDone: close });
33983
+ return /* @__PURE__ */ jsxs49(Box48, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33984
+ /* @__PURE__ */ jsx60(Text51, { bold: true, children: "Configuration" }),
33985
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
33986
+ SECTIONS.map((section, index) => /* @__PURE__ */ jsxs49(Box48, { gap: 1, children: [
33987
+ /* @__PURE__ */ jsx60(Text51, { color: index === focus ? PALETTE.accent : void 0, children: index === focus ? "\u276F" : " " }),
33988
+ /* @__PURE__ */ jsx60(Box48, { width: 9, flexShrink: 0, children: /* @__PURE__ */ jsx60(Text51, { bold: index === focus, color: index === focus ? PALETTE.accent : void 0, children: section.label }) }),
33989
+ /* @__PURE__ */ jsx60(Text51, { color: PALETTE.muted, children: section.description })
33990
+ ] }, section.id)),
33991
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
33992
+ /* @__PURE__ */ jsx60(
33242
33993
  ControlHints,
33243
33994
  {
33244
- hints: editing ? [
33245
- { keys: "type", label: "edit" },
33246
- { keys: "\u2190/\u2192", label: "move cursor" },
33247
- { keys: "\u23CE", label: "done" },
33248
- { keys: "Esc", label: "cancel edit" }
33249
- ] : [
33995
+ hints: [
33250
33996
  { keys: "\u2191/\u2193", label: "move" },
33251
- { keys: "\u23CE", label: "edit" },
33252
- { keys: "c", label: "clear" },
33253
- { keys: "s", label: "save" },
33254
- { keys: "Esc/q", label: "quit without saving" }
33997
+ { keys: "\u23CE", label: "open" },
33998
+ { keys: "Esc/q", label: "back" }
33255
33999
  ]
33256
34000
  }
33257
34001
  )
33258
34002
  ] });
33259
34003
  }
33260
- var FIELD_ORDER, FIELD_LABELS, FIELD_HINTS, LABEL_WIDTH;
34004
+ var SECTIONS;
33261
34005
  var init_ContentfulConfigScreen = __esm({
33262
34006
  "packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx"() {
33263
34007
  "use strict";
33264
34008
  init_theme();
33265
- init_config_store();
33266
- init_debug_store();
33267
34009
  init_control_hints();
33268
- FIELD_ORDER = [
33269
- "spaceId",
33270
- "environmentId",
33271
- "cmaToken",
33272
- "host",
33273
- "defaultComponentDir",
33274
- "defaultTokenFile",
33275
- "contentfulBaseDir"
34010
+ init_AgentScreens();
34011
+ init_ProjectConfigScreen();
34012
+ SECTIONS = [
34013
+ {
34014
+ id: "project",
34015
+ label: "Project",
34016
+ description: "Contentful space, credentials, defaults and where .contentful goes"
34017
+ },
34018
+ { id: "agents", label: "Agents", description: "Which coding agent the CLI uses, and each agent\u2019s settings" }
33276
34019
  ];
33277
- FIELD_LABELS = {
33278
- spaceId: "Space ID",
33279
- environmentId: "Environment ID",
33280
- cmaToken: "CMA Token",
33281
- host: "API Host",
33282
- defaultComponentDir: "Default component directory",
33283
- defaultTokenFile: "Default token file",
33284
- contentfulBaseDir: "Root Project Directory"
33285
- };
33286
- FIELD_HINTS = {
33287
- contentfulBaseDir: "(where .contentful goes)"
33288
- };
33289
- LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
33290
34020
  }
33291
34021
  });
33292
34022
 
33293
34023
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
33294
- import { useEffect as useEffect23, useState as useState30 } from "react";
33295
- import { Box as Box45, Text as Text47, useInput as useInput12 } from "ink";
33296
- import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
34024
+ import { useEffect as useEffect25, useState as useState34 } from "react";
34025
+ import { Box as Box49, Text as Text52, useInput as useInput15 } from "ink";
34026
+ import { Fragment as Fragment19, jsx as jsx61, jsxs as jsxs50 } from "react/jsx-runtime";
33297
34027
  function OptInAnalyticsScreen({ onDone }) {
33298
- const [loading, setLoading] = useState30(true);
33299
- const [enabled, setEnabled] = useState30(true);
33300
- useEffect23(() => {
34028
+ const [loading, setLoading] = useState34(true);
34029
+ const [enabled, setEnabled] = useState34(true);
34030
+ useEffect25(() => {
33301
34031
  readAnalyticsSetting().then((setting) => {
33302
34032
  setEnabled(setting.enabled);
33303
34033
  setLoading(false);
@@ -33309,7 +34039,7 @@ function OptInAnalyticsScreen({ onDone }) {
33309
34039
  });
33310
34040
  });
33311
34041
  }, []);
33312
- useInput12((input, key) => {
34042
+ useInput15((input, key) => {
33313
34043
  if (loading) return;
33314
34044
  if (key.return || input === " ") {
33315
34045
  setEnabled((current) => {
@@ -33324,21 +34054,21 @@ function OptInAnalyticsScreen({ onDone }) {
33324
34054
  onDone();
33325
34055
  }
33326
34056
  });
33327
- return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33328
- /* @__PURE__ */ jsx56(Text47, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
33329
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
33330
- loading ? /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs46(Fragment18, { children: [
33331
- /* @__PURE__ */ jsxs46(Text47, { children: [
34057
+ return /* @__PURE__ */ jsxs50(Box49, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
34058
+ /* @__PURE__ */ jsx61(Text52, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
34059
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
34060
+ loading ? /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs50(Fragment19, { children: [
34061
+ /* @__PURE__ */ jsxs50(Text52, { children: [
33332
34062
  "Share anonymous usage data:",
33333
34063
  " ",
33334
- /* @__PURE__ */ jsx56(Text47, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
34064
+ /* @__PURE__ */ jsx61(Text52, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
33335
34065
  ] }),
33336
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
33337
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
33338
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
34066
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
34067
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
34068
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
33339
34069
  ] }),
33340
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
33341
- /* @__PURE__ */ jsx56(
34070
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
34071
+ /* @__PURE__ */ jsx61(
33342
34072
  ControlHints,
33343
34073
  {
33344
34074
  hints: [
@@ -33360,12 +34090,12 @@ var init_screen11 = __esm({
33360
34090
  });
33361
34091
 
33362
34092
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
33363
- import { useEffect as useEffect24, useState as useState31 } from "react";
33364
- import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
33365
- import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
34093
+ import { useEffect as useEffect26, useState as useState35 } from "react";
34094
+ import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
34095
+ import { jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
33366
34096
  function UpgradeScreen({ onDone }) {
33367
- const [upgradeCheck, setUpgradeCheck] = useState31();
33368
- useEffect24(() => {
34097
+ const [upgradeCheck, setUpgradeCheck] = useState35();
34098
+ useEffect26(() => {
33369
34099
  startDebugRun({
33370
34100
  flow: "upgrade",
33371
34101
  step: "01-upgrade",
@@ -33374,7 +34104,7 @@ function UpgradeScreen({ onDone }) {
33374
34104
  });
33375
34105
  checkForUpgrade().then(setUpgradeCheck).catch(() => setUpgradeCheck({ status: "error" }));
33376
34106
  }, []);
33377
- useInput13((_input, key) => {
34107
+ useInput16((_input, key) => {
33378
34108
  if (key.return) {
33379
34109
  void finishDebugRun({
33380
34110
  outputs: upgradeCheck ?? {},
@@ -33385,12 +34115,12 @@ function UpgradeScreen({ onDone }) {
33385
34115
  return;
33386
34116
  }
33387
34117
  });
33388
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33389
- /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Upgrade" }),
33390
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
34118
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
34119
+ /* @__PURE__ */ jsx62(Text53, { bold: true, children: "Upgrade" }),
34120
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
33391
34121
  renderBody(upgradeCheck),
33392
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
33393
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.accent, children: [
34122
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
34123
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.accent, children: [
33394
34124
  FOCUS_MARKER,
33395
34125
  " Go Back"
33396
34126
  ] })
@@ -33398,34 +34128,34 @@ function UpgradeScreen({ onDone }) {
33398
34128
  }
33399
34129
  function renderBody(upgradeCheck) {
33400
34130
  if (!upgradeCheck) {
33401
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Checking for updates\u2026" });
34131
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Checking for updates\u2026" });
33402
34132
  }
33403
34133
  if (upgradeCheck.status === "error") {
33404
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
34134
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
33405
34135
  }
33406
34136
  if (upgradeCheck.status === "up-to-date") {
33407
- return /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.success, children: [
34137
+ return /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.success, children: [
33408
34138
  "You're already on the latest version (v",
33409
34139
  upgradeCheck.current,
33410
34140
  ")."
33411
34141
  ] });
33412
34142
  }
33413
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", children: [
33414
- /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.muted, children: [
33415
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.success, children: [
34143
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", children: [
34144
+ /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.muted, children: [
34145
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.success, children: [
33416
34146
  "v",
33417
34147
  upgradeCheck.latest
33418
34148
  ] }),
33419
34149
  " ",
33420
34150
  "is available (you're on ",
33421
- /* @__PURE__ */ jsxs47(Text48, { bold: true, children: [
34151
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, children: [
33422
34152
  "v",
33423
34153
  upgradeCheck.current
33424
34154
  ] }),
33425
34155
  "). Exit this program, cd into the root of your local clone of contentful/experience-design-system-sdk-public, then run:"
33426
34156
  ] }),
33427
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
33428
- /* @__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)) })
34157
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
34158
+ /* @__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)) })
33429
34159
  ] });
33430
34160
  }
33431
34161
  var UPGRADE_COMMANDS;
@@ -33441,13 +34171,13 @@ var init_PageContainer4 = __esm({
33441
34171
  });
33442
34172
 
33443
34173
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
33444
- import { useEffect as useEffect25, useState as useState32 } from "react";
33445
- import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
33446
- import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
34174
+ import { useEffect as useEffect27, useState as useState36 } from "react";
34175
+ import { Box as Box51, Text as Text54, useInput as useInput17 } from "ink";
34176
+ import { jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
33447
34177
  function DebugModeScreen({ onDone }) {
33448
- const [loading, setLoading] = useState32(true);
33449
- const [enabled, setEnabled] = useState32(true);
33450
- useEffect25(() => {
34178
+ const [loading, setLoading] = useState36(true);
34179
+ const [enabled, setEnabled] = useState36(true);
34180
+ useEffect27(() => {
33451
34181
  readDebugModeSetting().then((setting) => {
33452
34182
  setEnabled(setting.enabled);
33453
34183
  setLoading(false);
@@ -33459,7 +34189,7 @@ function DebugModeScreen({ onDone }) {
33459
34189
  });
33460
34190
  });
33461
34191
  }, []);
33462
- useInput14((input, key) => {
34192
+ useInput17((input, key) => {
33463
34193
  if (loading) return;
33464
34194
  if (key.return || input === " ") {
33465
34195
  setEnabled((current) => {
@@ -33474,16 +34204,16 @@ function DebugModeScreen({ onDone }) {
33474
34204
  onDone();
33475
34205
  }
33476
34206
  });
33477
- return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33478
- /* @__PURE__ */ jsx58(Text49, { bold: true, children: "Settings \u203A Debug Mode" }),
33479
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
33480
- loading ? /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs48(Text49, { children: [
34207
+ return /* @__PURE__ */ jsxs52(Box51, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
34208
+ /* @__PURE__ */ jsx63(Text54, { bold: true, children: "Settings \u203A Debug Mode" }),
34209
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
34210
+ loading ? /* @__PURE__ */ jsx63(Text54, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs52(Text54, { children: [
33481
34211
  "Debug logging:",
33482
34212
  " ",
33483
- /* @__PURE__ */ jsx58(Text49, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
34213
+ /* @__PURE__ */ jsx63(Text54, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
33484
34214
  ] }),
33485
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
33486
- /* @__PURE__ */ jsx58(
34215
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
34216
+ /* @__PURE__ */ jsx63(
33487
34217
  ControlHints,
33488
34218
  {
33489
34219
  hints: [
@@ -33509,20 +34239,20 @@ var app_exports = {};
33509
34239
  __export(app_exports, {
33510
34240
  runApp: () => runApp
33511
34241
  });
33512
- import { join as join26 } from "node:path";
33513
- import { useEffect as useEffect26, useState as useState33 } from "react";
33514
- import { Fragment as Fragment19, jsx as jsx59 } from "react/jsx-runtime";
34242
+ import { join as join27 } from "node:path";
34243
+ import { useEffect as useEffect28, useState as useState37 } from "react";
34244
+ import { Fragment as Fragment20, jsx as jsx64 } from "react/jsx-runtime";
33515
34245
  function App({ importOptions, inkClear }) {
33516
- const [screen, setScreen] = useState33("start");
33517
- const [importExitCode, setImportExitCode] = useState33();
34246
+ const [screen, setScreen] = useState37("start");
34247
+ const [importExitCode, setImportExitCode] = useState37();
33518
34248
  const showImportResult = importExitCode !== void 0;
33519
- const [projectPath, setProjectPath] = useState33();
33520
- const [tokensPath, setTokensPath] = useState33();
33521
- const [scannedFiles, setScannedFiles] = useState33();
33522
- const [pendingLaunch, setPendingLaunch] = useState33();
33523
- const [extractionRun, setExtractionRun] = useState33();
34249
+ const [projectPath, setProjectPath] = useState37();
34250
+ const [tokensPath, setTokensPath] = useState37();
34251
+ const [scannedFiles, setScannedFiles] = useState37();
34252
+ const [pendingLaunch, setPendingLaunch] = useState37();
34253
+ const [extractionRun, setExtractionRun] = useState37();
33524
34254
  const extraction = useExtraction(extractionRun?.input);
33525
- const [scopeRun, setScopeRun] = useState33();
34255
+ const [scopeRun, setScopeRun] = useState37();
33526
34256
  const scopeFlow = useScopeGateFlow(
33527
34257
  scopeRun && {
33528
34258
  sessionId: scopeRun.extraction.sessionId,
@@ -33537,12 +34267,12 @@ function App({ importOptions, inkClear }) {
33537
34267
  }
33538
34268
  }
33539
34269
  );
33540
- const [generationInput, setGenerationInput] = useState33();
34270
+ const [generationInput, setGenerationInput] = useState37();
33541
34271
  const generation = useGeneration(generationInput);
33542
- const [flowStart, setFlowStart] = useState33();
34272
+ const [flowStart, setFlowStart] = useState37();
33543
34273
  const flow = useFlow(flowStart, { beforeStepChange: inkClear });
33544
- const [importDefaults, setImportDefaults] = useState33();
33545
- useEffect26(() => {
34274
+ const [importDefaults, setImportDefaults] = useState37();
34275
+ useEffect28(() => {
33546
34276
  if (screen !== "import") {
33547
34277
  setImportDefaults(void 0);
33548
34278
  return;
@@ -33560,7 +34290,7 @@ function App({ importOptions, inkClear }) {
33560
34290
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
33561
34291
  const state2 = await inspectTokens({
33562
34292
  rawTokensPath: tokens,
33563
- contentfulDir: join26(resolveUserPath(projectPath2), ".contentful"),
34293
+ contentfulDir: join27(resolveUserPath(projectPath2), ".contentful"),
33564
34294
  cache: importOptions.cache
33565
34295
  });
33566
34296
  if (state2.kind === "cached") {
@@ -33602,12 +34332,12 @@ function App({ importOptions, inkClear }) {
33602
34332
  }
33603
34333
  });
33604
34334
  };
33605
- useEffect26(() => {
34335
+ useEffect28(() => {
33606
34336
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
33607
34337
  setExtractionRun(void 0);
33608
34338
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
33609
34339
  }, [extraction, extractionRun]);
33610
- useEffect26(() => {
34340
+ useEffect28(() => {
33611
34341
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
33612
34342
  const { extraction: produced, input, generatePromptPath } = scopeRun;
33613
34343
  setGenerationInput({
@@ -33625,7 +34355,7 @@ function App({ importOptions, inkClear }) {
33625
34355
  ...generatePromptPath ? { generatePromptPath } : {}
33626
34356
  });
33627
34357
  }, [scopeFlow, scopeRun, generationInput]);
33628
- useEffect26(() => {
34358
+ useEffect28(() => {
33629
34359
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
33630
34360
  const { credentialsSkipped, tokenStrategy, extraction: produced, input, generatePromptPath } = scopeRun;
33631
34361
  inkClear();
@@ -33668,9 +34398,9 @@ function App({ importOptions, inkClear }) {
33668
34398
  };
33669
34399
  switch (screen) {
33670
34400
  case "import":
33671
- if (showImportResult) return /* @__PURE__ */ jsx59(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
34401
+ if (showImportResult) return /* @__PURE__ */ jsx64(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
33672
34402
  if (flow && flowStart) {
33673
- return /* @__PURE__ */ jsx59(
34403
+ return /* @__PURE__ */ jsx64(
33674
34404
  FlowScreen,
33675
34405
  {
33676
34406
  state: flow.state,
@@ -33680,12 +34410,12 @@ function App({ importOptions, inkClear }) {
33680
34410
  }
33681
34411
  );
33682
34412
  }
33683
- if (importDefaults === void 0) return /* @__PURE__ */ jsx59(Fragment19, {});
34413
+ if (importDefaults === void 0) return /* @__PURE__ */ jsx64(Fragment20, {});
33684
34414
  if (projectPath === void 0) {
33685
- return /* @__PURE__ */ jsx59(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
34415
+ return /* @__PURE__ */ jsx64(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
33686
34416
  }
33687
34417
  if (tokensPath === void 0) {
33688
- return /* @__PURE__ */ jsx59(
34418
+ return /* @__PURE__ */ jsx64(
33689
34419
  TokenInputScreen,
33690
34420
  {
33691
34421
  initialPath: importDefaults.tokenFile,
@@ -33695,7 +34425,7 @@ function App({ importOptions, inkClear }) {
33695
34425
  );
33696
34426
  }
33697
34427
  if (scannedFiles === void 0) {
33698
- return /* @__PURE__ */ jsx59(
34428
+ return /* @__PURE__ */ jsx64(
33699
34429
  PathValidationScreen,
33700
34430
  {
33701
34431
  projectPath,
@@ -33707,10 +34437,10 @@ function App({ importOptions, inkClear }) {
33707
34437
  }
33708
34438
  if (extractionRun) {
33709
34439
  if (extraction?.status === "done" && !extraction.result.ok) {
33710
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
34440
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
33711
34441
  }
33712
34442
  if (extraction?.status === "running") {
33713
- return /* @__PURE__ */ jsx59(
34443
+ return /* @__PURE__ */ jsx64(
33714
34444
  ExtractionScreen,
33715
34445
  {
33716
34446
  progress: extraction.progress,
@@ -33719,14 +34449,14 @@ function App({ importOptions, inkClear }) {
33719
34449
  }
33720
34450
  );
33721
34451
  }
33722
- return /* @__PURE__ */ jsx59(Fragment19, {});
34452
+ return /* @__PURE__ */ jsx64(Fragment20, {});
33723
34453
  }
33724
34454
  if (scopeRun && scopeFlow) {
33725
34455
  if (scopeFlow.status === "failed") {
33726
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
34456
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
33727
34457
  }
33728
34458
  if (scopeFlow.status === "deciding") {
33729
- return /* @__PURE__ */ jsx59(
34459
+ return /* @__PURE__ */ jsx64(
33730
34460
  ScopeGateScreen,
33731
34461
  {
33732
34462
  components: scopeFlow.load.components,
@@ -33736,7 +34466,7 @@ function App({ importOptions, inkClear }) {
33736
34466
  );
33737
34467
  }
33738
34468
  if (generation?.status === "done" && !generation.result.ok) {
33739
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
34469
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
33740
34470
  }
33741
34471
  if (generation?.status === "running") {
33742
34472
  const hasRawTokens = scopeRun.input.rawTokensPath !== "";
@@ -33744,7 +34474,7 @@ function App({ importOptions, inkClear }) {
33744
34474
  hasRawTokens,
33745
34475
  mapTokensEligible: generation.progress.mapTokensEligible
33746
34476
  });
33747
- return /* @__PURE__ */ jsx59(
34477
+ return /* @__PURE__ */ jsx64(
33748
34478
  GenerationScreen,
33749
34479
  {
33750
34480
  progress: generation.progress,
@@ -33756,10 +34486,10 @@ function App({ importOptions, inkClear }) {
33756
34486
  }
33757
34487
  );
33758
34488
  }
33759
- return /* @__PURE__ */ jsx59(Fragment19, {});
34489
+ return /* @__PURE__ */ jsx64(Fragment20, {});
33760
34490
  }
33761
34491
  if (pendingLaunch?.cached) {
33762
- return /* @__PURE__ */ jsx59(
34492
+ return /* @__PURE__ */ jsx64(
33763
34493
  TokenReuseScreen,
33764
34494
  {
33765
34495
  tokensPath: pendingLaunch.cached.tokensPath,
@@ -33770,7 +34500,7 @@ function App({ importOptions, inkClear }) {
33770
34500
  }
33771
34501
  );
33772
34502
  }
33773
- return /* @__PURE__ */ jsx59(
34503
+ return /* @__PURE__ */ jsx64(
33774
34504
  CredentialsScreen,
33775
34505
  {
33776
34506
  initial: importDefaults.credentials,
@@ -33779,19 +34509,19 @@ function App({ importOptions, inkClear }) {
33779
34509
  }
33780
34510
  );
33781
34511
  case "help":
33782
- return /* @__PURE__ */ jsx59(HelpScreen, { onDone: goToStart });
34512
+ return /* @__PURE__ */ jsx64(HelpScreen, { onDone: goToStart });
33783
34513
  case "upgrade":
33784
- return /* @__PURE__ */ jsx59(UpgradeScreen, { onDone: goToStart });
34514
+ return /* @__PURE__ */ jsx64(UpgradeScreen, { onDone: goToStart });
33785
34515
  case "settings":
33786
- return /* @__PURE__ */ jsx59(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
34516
+ return /* @__PURE__ */ jsx64(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
33787
34517
  case "settings-configuration":
33788
- return /* @__PURE__ */ jsx59(ConfigurationScreen, { onDone: goToSettings });
34518
+ return /* @__PURE__ */ jsx64(ConfigurationScreen, { onDone: goToSettings });
33789
34519
  case "settings-opt-in-analytics":
33790
- return /* @__PURE__ */ jsx59(OptInAnalyticsScreen, { onDone: goToSettings });
34520
+ return /* @__PURE__ */ jsx64(OptInAnalyticsScreen, { onDone: goToSettings });
33791
34521
  case "settings-debug-mode":
33792
- return /* @__PURE__ */ jsx59(DebugModeScreen, { onDone: goToSettings });
34522
+ return /* @__PURE__ */ jsx64(DebugModeScreen, { onDone: goToSettings });
33793
34523
  case "start":
33794
- return /* @__PURE__ */ jsx59(HomeScreen, { onNavigate: setScreen });
34524
+ return /* @__PURE__ */ jsx64(HomeScreen, { onNavigate: setScreen });
33795
34525
  }
33796
34526
  }
33797
34527
  async function runApp(renderApp, importOptions) {
@@ -33799,7 +34529,7 @@ async function runApp(renderApp, importOptions) {
33799
34529
  instance.clear?.();
33800
34530
  process.stdout.write("\x1B[H\x1B[0J");
33801
34531
  };
33802
- const instance = renderApp(/* @__PURE__ */ jsx59(App, { importOptions, inkClear }));
34532
+ const instance = renderApp(/* @__PURE__ */ jsx64(App, { importOptions, inkClear }));
33803
34533
  await instance.waitUntilExit();
33804
34534
  }
33805
34535
  var init_app = __esm({
@@ -33834,7 +34564,7 @@ var init_app = __esm({
33834
34564
  // packages/experience-design-system-cli/program.ts
33835
34565
  init_src4();
33836
34566
  import { readFileSync as readFileSync9 } from "node:fs";
33837
- import { join as join27 } from "node:path";
34567
+ import { join as join28 } from "node:path";
33838
34568
  import { Command } from "commander";
33839
34569
 
33840
34570
  // packages/experience-design-system-cli/src/commands/import-options.ts
@@ -33862,14 +34592,14 @@ function runDevWatch(args) {
33862
34592
  process.stderr.write("--watch only works from a checkout of the repo (scripts/dev.mjs is not in the package).\n");
33863
34593
  return Promise.resolve(1);
33864
34594
  }
33865
- return new Promise((resolve27) => {
34595
+ return new Promise((resolve28) => {
33866
34596
  const child = spawn3(process.execPath, [script, ...args], { stdio: "inherit" });
33867
34597
  process.on("SIGINT", () => void 0);
33868
- child.on("exit", (code) => resolve27(code ?? 0));
34598
+ child.on("exit", (code) => resolve28(code ?? 0));
33869
34599
  child.on("error", (err) => {
33870
34600
  process.stderr.write(`${err.message}
33871
34601
  `);
33872
- resolve27(1);
34602
+ resolve28(1);
33873
34603
  });
33874
34604
  });
33875
34605
  }
@@ -33894,11 +34624,13 @@ function registerImportCommand(program, openTui) {
33894
34624
  }
33895
34625
 
33896
34626
  // packages/experience-design-system-cli/program.ts
34627
+ init_agent_store();
34628
+ init_apply_binary_overrides();
33897
34629
  init_analytics_store();
33898
34630
  init_package_root();
33899
34631
  var pkg = JSON.parse(
33900
34632
  readFileSync9(
33901
- join27(findPackageRoot(import.meta.url, "@contentful/experience-design-system-cli"), "package.json"),
34633
+ join28(findPackageRoot(import.meta.url, "@contentful/experience-design-system-cli"), "package.json"),
33902
34634
  "utf8"
33903
34635
  )
33904
34636
  );
@@ -33915,6 +34647,7 @@ function createProgram() {
33915
34647
  const commandChain = chain.join(" ") || actionCommand.name();
33916
34648
  const { enabled } = await readAnalyticsSetting();
33917
34649
  setPersistedAnalyticsDisabled(!enabled);
34650
+ await readAgentConfig().then(applyBinaryOverrides, () => void 0);
33918
34651
  setCliVersion(pkg.version);
33919
34652
  noteCommandStart(commandChain);
33920
34653
  });
@@ -33938,7 +34671,7 @@ init_config();
33938
34671
  init_package_root();
33939
34672
  import { existsSync as existsSync11 } from "node:fs";
33940
34673
  import { mkdir as mkdir10, readFile as readFile19, rename as rename3, rmdir, unlink } from "node:fs/promises";
33941
- import { dirname as dirname16, join as join28 } from "node:path";
34674
+ import { dirname as dirname16, join as join29 } from "node:path";
33942
34675
  var PACKAGE_NAME3 = "@contentful/experience-design-system-cli";
33943
34676
  async function readJson(path5) {
33944
34677
  try {
@@ -33949,9 +34682,9 @@ async function readJson(path5) {
33949
34682
  }
33950
34683
  async function migrateOldConfig() {
33951
34684
  try {
33952
- const oldCredentials = join28(oldConfigDir2(), "credentials.json");
33953
- const oldRuns = join28(oldConfigDir2(), "runs.json");
33954
- const oldDebugMode = join28(
34685
+ const oldCredentials = join29(oldConfigDir2(), "credentials.json");
34686
+ const oldRuns = join29(oldConfigDir2(), "runs.json");
34687
+ const oldDebugMode = join29(
33955
34688
  findPackageRoot(import.meta.url, PACKAGE_NAME3),
33956
34689
  ".contentful",
33957
34690
  "config",