@contentful/experience-design-system-cli 2.37.1-dev-build-7314a760.0 → 2.37.1-dev-build-be7b0e35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.js CHANGED
@@ -837,7 +837,7 @@ async function runAgent(options) {
837
837
  promptLen: prompt.length,
838
838
  promptHead: prompt.slice(0, 500)
839
839
  });
840
- return new Promise((resolve27) => {
840
+ return new Promise((resolve28) => {
841
841
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
842
842
  const child = spawn(binary, args, {
843
843
  stdio: ["pipe", "pipe", "pipe"],
@@ -886,7 +886,7 @@ async function runAgent(options) {
886
886
  stderrLen: stderr.length,
887
887
  stderrTail: stderr.slice(-1e3)
888
888
  });
889
- resolve27(result);
889
+ resolve28(result);
890
890
  });
891
891
  });
892
892
  }
@@ -908,7 +908,7 @@ async function checkAgentAuth(agent) {
908
908
  return "not-found";
909
909
  if (agent !== "claude")
910
910
  return "ok";
911
- return new Promise((resolve27) => {
911
+ return new Promise((resolve28) => {
912
912
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
913
913
  let stdout = "";
914
914
  let done = false;
@@ -917,7 +917,7 @@ async function checkAgentAuth(agent) {
917
917
  return;
918
918
  done = true;
919
919
  child.kill("SIGTERM");
920
- resolve27("unauthenticated");
920
+ resolve28("unauthenticated");
921
921
  }, 5e3);
922
922
  child.stdout?.on("data", (chunk) => {
923
923
  stdout += chunk.toString();
@@ -928,14 +928,14 @@ async function checkAgentAuth(agent) {
928
928
  done = true;
929
929
  clearTimeout(timer);
930
930
  if (code !== 0) {
931
- resolve27("unauthenticated");
931
+ resolve28("unauthenticated");
932
932
  return;
933
933
  }
934
934
  try {
935
935
  const status = JSON.parse(stdout);
936
- resolve27(status.loggedIn ? "ok" : "unauthenticated");
936
+ resolve28(status.loggedIn ? "ok" : "unauthenticated");
937
937
  } catch {
938
- resolve27("unauthenticated");
938
+ resolve28("unauthenticated");
939
939
  }
940
940
  });
941
941
  });
@@ -945,9 +945,9 @@ async function binaryIsOnPath(binary) {
945
945
  const fs = await import("node:fs/promises");
946
946
  return fs.access(binary).then(() => true, () => false);
947
947
  }
948
- return new Promise((resolve27) => {
948
+ return new Promise((resolve28) => {
949
949
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
950
- child.on("close", (code) => resolve27(code === 0));
950
+ child.on("close", (code) => resolve28(code === 0));
951
951
  });
952
952
  }
953
953
  var init_check_agent_auth = __esm({
@@ -2329,8 +2329,8 @@ var init_debug_store = __esm({
2329
2329
  });
2330
2330
 
2331
2331
  // packages/experience-design-system-cli/app.tsx
2332
- import { join as join25 } from "node:path";
2333
- import { useEffect as useEffect26, useState as useState33 } from "react";
2332
+ import { join as join26 } from "node:path";
2333
+ import { useEffect as useEffect28, useState as useState37 } from "react";
2334
2334
 
2335
2335
  // packages/experience-design-system-cli/src/tui/home/home.tsx
2336
2336
  import { useEffect as useEffect2, useState as useState2 } from "react";
@@ -8453,10 +8453,10 @@ function extractVueSlotsFromSetup(options) {
8453
8453
  if (!body)
8454
8454
  return [];
8455
8455
  const slotsByName = /* @__PURE__ */ new Map();
8456
- for (const access6 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
8457
- if (access6.getExpression().getText() !== slotsName)
8456
+ for (const access7 of body.getDescendantsOfKind(SyntaxKind5.PropertyAccessExpression)) {
8457
+ if (access7.getExpression().getText() !== slotsName)
8458
8458
  continue;
8459
- const slotName = access6.getName();
8459
+ const slotName = access7.getName();
8460
8460
  if (!slotsByName.has(slotName)) {
8461
8461
  slotsByName.set(slotName, {
8462
8462
  name: slotName,
@@ -13846,7 +13846,7 @@ function errorMessage(error) {
13846
13846
  return error instanceof Error && error.message ? error.message : String(error);
13847
13847
  }
13848
13848
  function defaultSleep(delayMs) {
13849
- return new Promise((resolve27) => setTimeout(resolve27, delayMs));
13849
+ return new Promise((resolve28) => setTimeout(resolve28, delayMs));
13850
13850
  }
13851
13851
 
13852
13852
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -14087,7 +14087,7 @@ var ApiClient = class {
14087
14087
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
14088
14088
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
14089
14089
  const jitter = Math.random() * baseDelay * 0.15;
14090
- await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
14090
+ await new Promise((resolve28) => setTimeout(resolve28, baseDelay + jitter));
14091
14091
  }
14092
14092
  }
14093
14093
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -14572,6 +14572,7 @@ function readTokensFromPath2(request) {
14572
14572
  init_agents();
14573
14573
  init_agent_name();
14574
14574
  init_models();
14575
+ init_binaries();
14575
14576
  init_is_agent_name();
14576
14577
  init_agent_supports_bedrock();
14577
14578
  init_check_agent_auth();
@@ -16396,7 +16397,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
16396
16397
  const message = error instanceof Error ? error.message : String(error);
16397
16398
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
16398
16399
  throw error;
16399
- await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
16400
+ await new Promise((resolve28) => setTimeout(resolve28, Math.min(250 * attempt, 2e3)));
16400
16401
  }
16401
16402
  }
16402
16403
  }
@@ -28030,7 +28031,7 @@ var realSaveDeps = () => ({
28030
28031
  writeFile: (path5, contents) => writeFile7(path5, contents),
28031
28032
  appendRun,
28032
28033
  buildSourceFingerprint,
28033
- sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
28034
+ sleep: (ms) => new Promise((resolve28) => setTimeout(resolve28, ms)),
28034
28035
  warn: (message) => process.stderr.write(message)
28035
28036
  });
28036
28037
  async function runPrintFiles(input, deps, onPatch) {
@@ -28420,12 +28421,44 @@ init_config();
28420
28421
  init_debug_store();
28421
28422
  init_debug_mode_store();
28422
28423
  init_version();
28424
+
28425
+ // packages/experience-design-system-cli/src/tui/help/file-locations.ts
28426
+ import { join as join25, resolve as resolve27 } from "node:path";
28427
+ function describeFileLocations({
28428
+ contentfulBaseDir,
28429
+ debugModeEnabled,
28430
+ currentSessionDir: currentSessionDir2
28431
+ }) {
28432
+ if (!debugModeEnabled) {
28433
+ return {
28434
+ debugLogs: "none while Debug Mode is off",
28435
+ importFiles: `${join25("<project>", ".contentful")}/ (tokens.json, components.json)`
28436
+ };
28437
+ }
28438
+ const base = contentfulBaseDir ? resolve27(contentfulBaseDir) : "<project>";
28439
+ const session = currentSessionDir2 ?? join25(base, ".contentful", "<date>-session-<n>");
28440
+ return {
28441
+ debugLogs: join25(session, "debug"),
28442
+ importFiles: `${join25(session, "dsi-import-<n>")}/ (tokens.json, components.json)`
28443
+ };
28444
+ }
28445
+
28446
+ // packages/experience-design-system-cli/src/tui/help/help-info.ts
28423
28447
  async function readHelpInfo() {
28424
- const debugMode = await readDebugModeSetting();
28448
+ const [debugMode, settings] = await Promise.all([readDebugModeSetting(), readSettings2()]);
28449
+ const base = settings["contentfulBaseDir"];
28450
+ const locations = describeFileLocations({
28451
+ contentfulBaseDir: typeof base === "string" ? base : "",
28452
+ debugModeEnabled: debugMode.enabled,
28453
+ currentSessionDir: currentSessionDir()
28454
+ });
28425
28455
  return {
28426
28456
  storage: [
28427
28457
  { label: "Config folder", value: configRoot2() },
28428
- { label: "Settings file", value: configFilePath2() }
28458
+ { label: "Settings file", value: configFilePath2() },
28459
+ { label: "Agent settings", value: `${configFilePath2()} (keys: agent, agentModel, agents)` },
28460
+ { label: "Debug logs", value: locations.debugLogs },
28461
+ { label: "Import files", value: locations.importFiles }
28429
28462
  ],
28430
28463
  troubleshooting: [
28431
28464
  { label: "CLI version", value: readPackageVersion() },
@@ -28446,7 +28479,7 @@ function Section({ title, rows }) {
28446
28479
  return /* @__PURE__ */ jsxs43(Box42, { flexDirection: "column", children: [
28447
28480
  /* @__PURE__ */ jsx53(Text44, { bold: true, color: PALETTE.accent, children: title }),
28448
28481
  rows.map((row) => /* @__PURE__ */ jsxs43(Box42, { gap: 1, children: [
28449
- /* @__PURE__ */ jsx53(Box42, { width: 14, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
28482
+ /* @__PURE__ */ jsx53(Box42, { width: 16, flexShrink: 0, children: /* @__PURE__ */ jsx53(Text44, { color: PALETTE.muted, children: row.label }) }),
28450
28483
  /* @__PURE__ */ jsx53(Text44, { children: row.value })
28451
28484
  ] }, row.label))
28452
28485
  ] });
@@ -28546,200 +28579,757 @@ function SettingsScreen({
28546
28579
  }
28547
28580
 
28548
28581
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28549
- import { useEffect as useEffect22, useState as useState29 } from "react";
28550
- import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28551
- import TextInput4 from "ink-text-input";
28582
+ import { useState as useState33 } from "react";
28583
+ import { Box as Box48, Text as Text51, useInput as useInput14 } from "ink";
28584
+
28585
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
28586
+ import { useEffect as useEffect23, useState as useState30 } from "react";
28587
+ import { Box as Box45, Text as Text48, useInput as useInput12 } from "ink";
28588
+ init_debug_store();
28552
28589
 
28553
28590
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28554
28591
  init_config();
28555
28592
  var readV1Store = readSettings2;
28556
28593
  var writeV1Store = writeSettings2;
28557
28594
 
28558
- // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
28559
- async function readCredentials() {
28595
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-store.ts
28596
+ var DEFAULT_AGENT3 = "claude";
28597
+ var AGENT_LABELS = {
28598
+ claude: "Claude Code",
28599
+ codex: "OpenAI Codex",
28600
+ opencode: "OpenCode",
28601
+ cursor: "Cursor",
28602
+ copilot: "GitHub Copilot"
28603
+ };
28604
+ var AGENT_HINTS = {
28605
+ claude: "claude",
28606
+ codex: "codex",
28607
+ opencode: "opencode",
28608
+ cursor: "cursor-agent",
28609
+ copilot: "copilot"
28610
+ };
28611
+ var asString = (value) => typeof value === "string" ? value : "";
28612
+ function emptyAgents() {
28613
+ return Object.fromEntries(AGENT_NAMES.map((name) => [name, { model: "", binary: "" }]));
28614
+ }
28615
+ async function readAgentConfig() {
28560
28616
  const store = await readV1Store();
28561
- return {
28562
- spaceId: store.spaceId || "",
28563
- environmentId: store.environmentId || "",
28564
- cmaToken: store.cmaToken || "",
28565
- host: store.host || "",
28566
- defaultComponentDir: store.defaultComponentDir || "",
28567
- defaultTokenFile: store.defaultTokenFile || "",
28568
- contentfulBaseDir: store.contentfulBaseDir || ""
28569
- };
28617
+ const stored = asString(store["agent"]);
28618
+ const defaultAgent = isAgentName(stored) ? stored : DEFAULT_AGENT3;
28619
+ const agents = emptyAgents();
28620
+ const saved = store["agents"];
28621
+ if (saved && typeof saved === "object") {
28622
+ for (const name of AGENT_NAMES) {
28623
+ const entry = saved[name];
28624
+ if (entry && typeof entry === "object") {
28625
+ const fields = entry;
28626
+ agents[name] = { model: asString(fields["model"]), binary: asString(fields["binary"]) };
28627
+ }
28628
+ }
28629
+ }
28630
+ const legacyModel = asString(store["agentModel"]);
28631
+ if (legacyModel && !agents[defaultAgent].model)
28632
+ agents[defaultAgent] = { ...agents[defaultAgent], model: legacyModel };
28633
+ return { defaultAgent, agents };
28570
28634
  }
28571
- async function writeCredentials(config) {
28635
+ async function writeAgentConfig(config) {
28572
28636
  const existing = await readV1Store();
28573
- const merged = {
28574
- ...existing,
28575
- ...config
28576
- };
28577
- Object.keys(merged).forEach((k) => {
28578
- if (!merged[k]) delete merged[k];
28579
- });
28637
+ const merged = { ...existing };
28638
+ const agents = {};
28639
+ for (const name of AGENT_NAMES) {
28640
+ const model = config.agents[name].model.trim();
28641
+ const binary = config.agents[name].binary.trim();
28642
+ if (model || binary) agents[name] = { ...model ? { model } : {}, ...binary ? { binary } : {} };
28643
+ }
28644
+ merged["agent"] = config.defaultAgent;
28645
+ const defaultModel = agents[config.defaultAgent]?.model;
28646
+ if (defaultModel) merged["agentModel"] = defaultModel;
28647
+ else delete merged["agentModel"];
28648
+ if (Object.keys(agents).length > 0) merged["agents"] = agents;
28649
+ else delete merged["agents"];
28580
28650
  await writeV1Store(merged);
28581
28651
  }
28582
28652
 
28583
- // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28584
- init_debug_store();
28585
- import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28586
- var FIELD_ORDER = [
28587
- "spaceId",
28588
- "environmentId",
28589
- "cmaToken",
28590
- "host",
28591
- "defaultComponentDir",
28592
- "defaultTokenFile",
28593
- "contentfulBaseDir"
28594
- ];
28595
- function debugFields(config) {
28596
- return {
28597
- space_id: config?.spaceId ?? "",
28598
- environment_id: config?.environmentId ?? "",
28599
- cma_token: config?.cmaToken ?? "",
28600
- host: config?.host ?? "",
28601
- default_component_dir: config?.defaultComponentDir ?? "",
28602
- default_token_file: config?.defaultTokenFile ?? "",
28603
- contentful_base_dir: config?.contentfulBaseDir ?? ""
28604
- };
28653
+ // packages/experience-design-system-cli/src/tui/settings/agents/agent-status.ts
28654
+ import { execFile as execFile2 } from "node:child_process";
28655
+ import { access as access6, constants } from "node:fs/promises";
28656
+ var VERSION_TIMEOUT_MS = 5e3;
28657
+ var PROMPT_TIMEOUT_MS = 6e4;
28658
+ var TEST_PROMPT = "Reply with the single word: ok";
28659
+ var INSTALL_HINTS = {
28660
+ claude: "npm install -g @anthropic-ai/claude-code",
28661
+ codex: "npm install -g @openai/codex",
28662
+ opencode: "npm install -g opencode-ai",
28663
+ cursor: "install Cursor\u2019s `cursor-agent` command",
28664
+ copilot: "npm install -g @github/copilot"
28665
+ };
28666
+ var LOGIN_HINTS = {
28667
+ claude: "run `claude login`",
28668
+ codex: "set OPENAI_API_KEY, or sign in with a ChatGPT account",
28669
+ opencode: "run `opencode auth`",
28670
+ cursor: "sign in from Cursor",
28671
+ copilot: "run `copilot` and sign in"
28672
+ };
28673
+ function effectiveBinary(name, savedBinary) {
28674
+ return savedBinary.trim() || AGENT_BINARIES[name];
28675
+ }
28676
+ function defaultModelLabel(name) {
28677
+ const model = DEFAULT_MODELS[name];
28678
+ return model && model !== "Auto" ? model : "chosen by the agent";
28679
+ }
28680
+ var fail3 = (step, detail) => ({ step, ok: false, detail });
28681
+ var pass = (step, detail) => ({ step, ok: true, detail });
28682
+ function resolveOnPath(binary) {
28683
+ if (binary.includes("/")) {
28684
+ return access6(binary, constants.X_OK).then(
28685
+ () => binary,
28686
+ () => null
28687
+ );
28688
+ }
28689
+ return new Promise((resolve28) => {
28690
+ execFile2(
28691
+ process.platform === "win32" ? "where" : "which",
28692
+ [binary],
28693
+ (error, stdout) => resolve28(error ? null : stdout.split("\n")[0]?.trim() ?? null)
28694
+ );
28695
+ });
28605
28696
  }
28606
- var FIELD_LABELS = {
28607
- spaceId: "Space ID",
28608
- environmentId: "Environment ID",
28609
- cmaToken: "CMA Token",
28610
- host: "API Host",
28611
- defaultComponentDir: "Default component directory",
28612
- defaultTokenFile: "Default token file",
28613
- contentfulBaseDir: "Root Project Directory"
28697
+ function readVersion(binary) {
28698
+ return new Promise((resolve28) => {
28699
+ execFile2(binary, ["--version"], { timeout: VERSION_TIMEOUT_MS }, (error, stdout) => {
28700
+ const line = stdout.split("\n")[0]?.trim() ?? "";
28701
+ if (!error && line) resolve28(pass("version", line));
28702
+ else resolve28(fail3("version", "runs, but did not report a version"));
28703
+ });
28704
+ });
28705
+ }
28706
+ async function inspectAgent(name, binary) {
28707
+ const target = effectiveBinary(name, binary);
28708
+ const found = await resolveOnPath(target);
28709
+ if (!found) return [fail3("path", `\`${target}\` was not found or is not executable`)];
28710
+ const checks = [pass("path", found)];
28711
+ checks.push(await readVersion(found));
28712
+ if (name === "claude") {
28713
+ const auth = await withBinaryEnv(name, found, () => checkAgentAuth(name));
28714
+ checks.push(
28715
+ auth === "ok" ? pass("login", "logged in") : fail3("login", auth === "not-found" ? "binary not found" : `not logged in: ${LOGIN_HINTS.claude}`)
28716
+ );
28717
+ }
28718
+ return checks;
28719
+ }
28720
+ async function testAgent(name, binary, model) {
28721
+ const checks = await inspectAgent(name, binary);
28722
+ if (!checks.every((check) => check.step === "version" || check.ok)) return checks;
28723
+ const target = effectiveBinary(name, binary);
28724
+ const found = await resolveOnPath(target) ?? target;
28725
+ const started = Date.now();
28726
+ const result = await withBinaryEnv(
28727
+ name,
28728
+ found,
28729
+ () => createLocalCliAgentInvoker().invoke({
28730
+ agent: name,
28731
+ ...model.trim() ? { model: model.trim() } : {},
28732
+ prompt: TEST_PROMPT,
28733
+ timeoutMs: PROMPT_TIMEOUT_MS
28734
+ })
28735
+ );
28736
+ const seconds = ((Date.now() - started) / 1e3).toFixed(1);
28737
+ if (result.timedOut) {
28738
+ return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
28739
+ }
28740
+ if (result.exitCode !== 0) {
28741
+ const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
28742
+ return [...checks, fail3("prompt", reason)];
28743
+ }
28744
+ return [...checks, pass("prompt", `answered in ${seconds}s`)];
28745
+ }
28746
+ function statusFromChecks(name, checks, savedBinary) {
28747
+ if (checks.length === 0) return "checking";
28748
+ if (checks.some((check) => check.step === "path" && !check.ok)) {
28749
+ return savedBinary.trim() ? "not-found" : "not-configured";
28750
+ }
28751
+ const prompt = checks.find((check) => check.step === "prompt");
28752
+ if (prompt) {
28753
+ if (prompt.ok) return "ready";
28754
+ return prompt.timedOut ? "timed-out" : "test-failed";
28755
+ }
28756
+ const login = checks.find((check) => check.step === "login");
28757
+ if (login) return login.ok ? "ready" : "not-logged-in";
28758
+ return name === "claude" ? "ready" : "unknown";
28759
+ }
28760
+ function setupHint(name, status) {
28761
+ if (status === "not-configured") return `${INSTALL_HINTS[name]}, or set its command path in settings`;
28762
+ if (status === "not-found") return `${INSTALL_HINTS[name]}, or correct the command path in settings`;
28763
+ if (status === "not-logged-in") return LOGIN_HINTS[name];
28764
+ if (status === "test-failed") return `read the test message; if it is a login problem, ${LOGIN_HINTS[name]}`;
28765
+ if (status === "timed-out") return "it may be slow or waiting for input; run the test again, or try it in a terminal";
28766
+ if (status === "unknown") return "run a full test to confirm it is logged in";
28767
+ return "";
28768
+ }
28769
+ function testOutcome(checks) {
28770
+ const prompt = checks?.find((check) => check.step === "prompt");
28771
+ if (!prompt) return void 0;
28772
+ if (prompt.ok) return { ok: true, text: `Test passed: ${prompt.detail}` };
28773
+ if (prompt.timedOut) return { ok: false, text: `Test timed out: ${prompt.detail}` };
28774
+ return { ok: false, text: `Test failed: ${prompt.detail}` };
28775
+ }
28776
+ var LIST_STATUS = {
28777
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
28778
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
28779
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
28780
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
28781
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
28782
+ "test-failed": { symbol: "\u2717", text: "test failed", tone: "bad" },
28783
+ "timed-out": { symbol: "\u2717", text: "test timed out", tone: "bad" },
28784
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
28614
28785
  };
28615
- var FIELD_HINTS = {
28616
- contentfulBaseDir: "(where .contentful goes)"
28786
+ function modelLine(name, savedModel) {
28787
+ const model = savedModel.trim();
28788
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
28789
+ }
28790
+ function panelRows(name, checks, settings) {
28791
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
28792
+ const status = statusFromChecks(name, checks, settings.binary);
28793
+ const path5 = checks.find((check) => check.step === "path");
28794
+ if (!path5?.ok) {
28795
+ const rows2 = [
28796
+ {
28797
+ label: "Command",
28798
+ value: settings.binary.trim() ? path5?.detail ?? "not found" : "not found on your PATH",
28799
+ tone: settings.binary.trim() ? "bad" : "muted"
28800
+ }
28801
+ ];
28802
+ const hint2 = setupHint(name, status);
28803
+ if (hint2) rows2.push({ label: "Setup", value: hint2, tone: "muted" });
28804
+ return rows2;
28805
+ }
28806
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
28807
+ const version = checks.find((check) => check.step === "version");
28808
+ if (version?.ok) rows.push({ label: "Version", value: version.detail, tone: "ok" });
28809
+ rows.push({ label: "Model", value: modelLine(name, settings.model), tone: "muted" });
28810
+ const hint = setupHint(name, status);
28811
+ if (hint) rows.push({ label: "Setup", value: hint, tone: "muted" });
28812
+ return rows;
28813
+ }
28814
+ function statusRows(_name, checks, savedBinary) {
28815
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
28816
+ const find = (step) => checks.find((check) => check.step === step);
28817
+ const path5 = find("path");
28818
+ if (!path5?.ok) {
28819
+ if (savedBinary.trim()) return [{ label: "Command", value: path5?.detail ?? "not found", tone: "bad" }];
28820
+ return [{ label: "Command", value: "not configured (not on the PATH)", tone: "muted" }];
28821
+ }
28822
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
28823
+ const version = find("version");
28824
+ if (version) {
28825
+ rows.push({
28826
+ label: "Version",
28827
+ value: version.ok ? version.detail : "could not be read",
28828
+ tone: version.ok ? "ok" : "muted"
28829
+ });
28830
+ }
28831
+ const login = find("login");
28832
+ const prompt = find("prompt");
28833
+ if (login) {
28834
+ rows.push({ label: "Login", value: login.detail, tone: login.ok ? "ok" : "bad" });
28835
+ } else if (prompt) {
28836
+ rows.push({
28837
+ label: "Login",
28838
+ value: prompt.ok ? "confirmed by the test" : prompt.timedOut ? "unknown (the test timed out)" : "see the test result",
28839
+ tone: prompt.ok ? "ok" : prompt.timedOut ? "muted" : "bad"
28840
+ });
28841
+ } else {
28842
+ rows.push({ label: "Login", value: "not checked (use Run test)", tone: "muted" });
28843
+ }
28844
+ if (prompt) rows.push({ label: "Test", value: prompt.detail, tone: prompt.ok ? "ok" : "bad" });
28845
+ return rows;
28846
+ }
28847
+ async function withBinaryEnv(name, binary, run) {
28848
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
28849
+ const previous = process.env[key];
28850
+ process.env[key] = binary;
28851
+ try {
28852
+ return await run();
28853
+ } finally {
28854
+ if (previous === void 0) delete process.env[key];
28855
+ else process.env[key] = previous;
28856
+ }
28857
+ }
28858
+
28859
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28860
+ import { useEffect as useEffect22, useState as useState29 } from "react";
28861
+ import { Box as Box44, Text as Text47, useInput as useInput11 } from "ink";
28862
+ import TextInput4 from "ink-text-input";
28863
+
28864
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
28865
+ import { Text as Text46 } from "ink";
28866
+ import { jsx as jsx55 } from "react/jsx-runtime";
28867
+ var TONE_COLOR = {
28868
+ ok: PALETTE.success,
28869
+ bad: PALETTE.error,
28870
+ muted: PALETTE.muted
28617
28871
  };
28618
- var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28619
- function ConfigurationScreen({ onDone }) {
28620
- const [stage, setStage] = useState29("loading");
28621
- const [config, setConfig] = useState29(null);
28622
- const [activeField, setActiveField] = useState29("spaceId");
28623
- const [notice, setNotice] = useState29(null);
28624
- const [lastSaved, setLastSaved] = useState29(null);
28872
+ function AgentStatusBadge({
28873
+ name,
28874
+ checks,
28875
+ binary
28876
+ }) {
28877
+ const { symbol, text, tone } = LIST_STATUS[checks ? statusFromChecks(name, checks, binary) : "checking"];
28878
+ return /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[tone], children: `${symbol} ${text}` });
28879
+ }
28880
+
28881
+ // packages/experience-design-system-cli/src/tui/settings/agents/apply-binary-overrides.ts
28882
+ var shellValues = /* @__PURE__ */ new Map();
28883
+ function applyBinaryOverrides(config) {
28884
+ for (const name of AGENT_NAMES) {
28885
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
28886
+ const binary = config.agents[name].binary.trim();
28887
+ if (binary) {
28888
+ if (!shellValues.has(key)) shellValues.set(key, process.env[key]);
28889
+ process.env[key] = binary;
28890
+ } else if (shellValues.has(key)) {
28891
+ const shellValue = shellValues.get(key);
28892
+ if (shellValue === void 0) delete process.env[key];
28893
+ else process.env[key] = shellValue;
28894
+ shellValues.delete(key);
28895
+ }
28896
+ }
28897
+ }
28898
+
28899
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28900
+ import { jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
28901
+ var FOCUS_ORDER = ["binary", "model", "test"];
28902
+ var FIELDS2 = ["binary", "model"];
28903
+ var FIELD_LABEL = { binary: "Command path", model: "Model" };
28904
+ var LABEL_WIDTH = "Command path".length;
28905
+ var LABEL_GAP = 2;
28906
+ var POINTER_WIDTH = 2;
28907
+ var fieldHint = (name, field) => field === "binary" ? `(empty: \`${AGENT_HINTS[name]}\` from the PATH)` : `(empty: ${defaultModelLabel(name)})`;
28908
+ function Row2({
28909
+ pointer,
28910
+ label,
28911
+ labelProps,
28912
+ children
28913
+ }) {
28914
+ return /* @__PURE__ */ jsxs45(Box44, { children: [
28915
+ /* @__PURE__ */ jsx56(Box44, { width: POINTER_WIDTH, flexShrink: 0, children: pointer }),
28916
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH + LABEL_GAP, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, ...labelProps, children: label }) }),
28917
+ children
28918
+ ] });
28919
+ }
28920
+ function Section2({
28921
+ title,
28922
+ note,
28923
+ interactive = false,
28924
+ children
28925
+ }) {
28926
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", marginTop: 1, children: [
28927
+ /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28928
+ /* @__PURE__ */ jsx56(Text47, { bold: true, color: interactive ? PALETTE.accent : PALETTE.muted, children: title }),
28929
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: `\xB7 ${note}` })
28930
+ ] }),
28931
+ children
28932
+ ] });
28933
+ }
28934
+ function AgentDetail({
28935
+ name,
28936
+ config,
28937
+ setConfig,
28938
+ onBack
28939
+ }) {
28940
+ const settings = config.agents[name];
28941
+ const [focusIndex, setFocusIndex] = useState29(0);
28625
28942
  const [editing, setEditing] = useState29(false);
28626
28943
  const [valueBeforeEdit, setValueBeforeEdit] = useState29("");
28944
+ const [saving, setSaving] = useState29(false);
28945
+ const [testing, setTesting] = useState29(false);
28946
+ const [notice, setNotice] = useState29(null);
28947
+ const [checks, setChecks] = useState29(void 0);
28627
28948
  useEffect22(() => {
28628
- readCredentials().then((cfg) => {
28629
- setConfig(cfg);
28630
- setStage("form");
28949
+ let active = true;
28950
+ setChecks(void 0);
28951
+ void inspectAgent(name, settings.binary).then((result) => active && setChecks(result));
28952
+ return () => {
28953
+ active = false;
28954
+ };
28955
+ }, [name, settings.binary]);
28956
+ const setField = (field, value) => {
28957
+ setConfig({ ...config, agents: { ...config.agents, [name]: { ...settings, [field]: value } } });
28958
+ setNotice(null);
28959
+ };
28960
+ const save = () => {
28961
+ setSaving(true);
28962
+ setNotice(null);
28963
+ writeAgentConfig(config).then(() => {
28964
+ applyBinaryOverrides(config);
28965
+ setNotice({ kind: "success", text: `Saved: ${AGENT_LABELS[name]} settings are written to config.json` });
28966
+ }).catch(
28967
+ (err) => setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` })
28968
+ ).finally(() => setSaving(false));
28969
+ };
28970
+ const runTest = () => {
28971
+ setTesting(true);
28972
+ setNotice(null);
28973
+ testAgent(name, settings.binary, settings.model).then((result) => {
28974
+ setChecks(result);
28975
+ const outcome = testOutcome(result);
28976
+ setNotice(
28977
+ outcome ? { kind: outcome.ok ? "success" : "error", text: outcome.text } : { kind: "error", text: "Test not run: the agent could not be started (see Status)" }
28978
+ );
28979
+ }).catch(
28980
+ (err) => setNotice({ kind: "error", text: `Test could not run: ${err instanceof Error ? err.message : String(err)}` })
28981
+ ).finally(() => setTesting(false));
28982
+ };
28983
+ const focused = FOCUS_ORDER[focusIndex];
28984
+ const focusedField = focused === "test" ? null : focused;
28985
+ useInput11((input, key) => {
28986
+ if (saving || testing) return;
28987
+ if (editing) {
28988
+ if (key.escape && focusedField) {
28989
+ setField(focusedField, valueBeforeEdit);
28990
+ setEditing(false);
28991
+ }
28992
+ return;
28993
+ }
28994
+ if (key.escape || input === "q") {
28995
+ onBack();
28996
+ return;
28997
+ }
28998
+ if (input === "s") {
28999
+ save();
29000
+ return;
29001
+ }
29002
+ if (key.upArrow) {
29003
+ setFocusIndex((i) => (i - 1 + FOCUS_ORDER.length) % FOCUS_ORDER.length);
29004
+ return;
29005
+ }
29006
+ if (key.downArrow || key.tab) {
29007
+ setFocusIndex((i) => (i + 1) % FOCUS_ORDER.length);
29008
+ return;
29009
+ }
29010
+ if (input === "c" && focusedField) {
29011
+ setField(focusedField, "");
29012
+ return;
29013
+ }
29014
+ if (key.return) {
29015
+ if (focusedField) {
29016
+ setValueBeforeEdit(settings[focusedField]);
29017
+ setEditing(true);
29018
+ } else {
29019
+ runTest();
29020
+ }
29021
+ }
29022
+ });
29023
+ const status = checks ? statusFromChecks(name, checks, settings.binary) : "checking";
29024
+ const hint = setupHint(name, status);
29025
+ const pointer = (isFocused) => /* @__PURE__ */ jsx56(Text47, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
29026
+ return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29027
+ /* @__PURE__ */ jsx56(Text47, { bold: true, children: AGENT_LABELS[name] }),
29028
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
29029
+ (notice || testing || saving) && /* @__PURE__ */ jsx56(Box44, { marginTop: 1, children: testing || saving ? /* @__PURE__ */ jsx56(Text47, { color: PALETTE.accent, children: testing ? "\u2026 Running the test (up to 60s)" : "\u2026 Saving" }) : notice && /* @__PURE__ */ jsxs45(Text47, { bold: true, color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29030
+ notice.kind === "success" ? "\u2713" : "\u2717",
29031
+ " ",
29032
+ notice.text
29033
+ ] }) }),
29034
+ /* @__PURE__ */ jsxs45(Section2, { title: "CONFIGURE", note: "you can change these", interactive: true, children: [
29035
+ FIELDS2.map((field) => {
29036
+ const isFocused = focused === field;
29037
+ const value = settings[field];
29038
+ const display = isFocused && editing ? /* @__PURE__ */ jsx56(TextInput4, { value, onChange: (next) => setField(field, next), onSubmit: () => setEditing(false) }) : value ? /* @__PURE__ */ jsx56(Text47, { bold: true, children: value }) : /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: fieldHint(name, field) });
29039
+ return /* @__PURE__ */ jsx56(
29040
+ Row2,
29041
+ {
29042
+ pointer: pointer(isFocused),
29043
+ label: FIELD_LABEL[field],
29044
+ labelProps: { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted },
29045
+ children: display
29046
+ },
29047
+ field
29048
+ );
29049
+ }),
29050
+ /* @__PURE__ */ jsx56(
29051
+ Row2,
29052
+ {
29053
+ pointer: pointer(focused === "test"),
29054
+ label: "Run test",
29055
+ labelProps: { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted },
29056
+ children: /* @__PURE__ */ jsx56(Text47, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
29057
+ }
29058
+ )
29059
+ ] }),
29060
+ /* @__PURE__ */ jsxs45(Section2, { title: "STATUS", note: "read only", children: [
29061
+ statusRows(name, checks, settings.binary).map((row) => /* @__PURE__ */ jsx56(Row2, { pointer: null, label: row.label, children: /* @__PURE__ */ jsx56(Text47, { color: TONE_COLOR[row.tone], children: row.value }) }, row.label)),
29062
+ hint && /* @__PURE__ */ jsx56(Row2, { pointer: null, label: "Setup", children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: hint }) })
29063
+ ] }),
29064
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
29065
+ /* @__PURE__ */ jsx56(
29066
+ ControlHints,
29067
+ {
29068
+ hints: editing ? [
29069
+ { keys: "type", label: "edit" },
29070
+ { keys: "\u2190/\u2192", label: "move cursor" },
29071
+ { keys: "\u23CE", label: "done" },
29072
+ { keys: "Esc", label: "cancel edit" }
29073
+ ] : [
29074
+ { keys: "\u2191/\u2193", label: "move" },
29075
+ { keys: "\u23CE", label: focusedField ? "edit" : "run test" },
29076
+ ...focusedField ? [{ keys: "c", label: "clear" }] : [],
29077
+ { keys: "s", label: "save" },
29078
+ { keys: "Esc/q", label: "back without saving" }
29079
+ ]
29080
+ }
29081
+ )
29082
+ ] });
29083
+ }
29084
+
29085
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
29086
+ import { Fragment as Fragment17, jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
29087
+ var NAME_WIDTH = 16;
29088
+ var PANEL_LABEL_WIDTH = "Command".length;
29089
+ function AgentsScreen({ onDone }) {
29090
+ const [config, setConfig] = useState30(null);
29091
+ const [focus, setFocus] = useState30(0);
29092
+ const [open, setOpen] = useState30(null);
29093
+ const [notice, setNotice] = useState30(null);
29094
+ const [saving, setSaving] = useState30(false);
29095
+ const [checks, setChecks] = useState30({});
29096
+ const inspectAll = (loaded) => {
29097
+ for (const name of AGENT_NAMES) {
29098
+ void inspectAgent(name, loaded.agents[name].binary).then(
29099
+ (result) => setChecks((previous) => ({ ...previous, [name]: result }))
29100
+ );
29101
+ }
29102
+ };
29103
+ useEffect23(() => {
29104
+ void readAgentConfig().then((loaded) => {
29105
+ setConfig(loaded);
29106
+ inspectAll(loaded);
28631
29107
  startDebugRun({
28632
- flow: "settings/contentful-configuration",
28633
- step: "01-configuration",
28634
- menuOption: "Configuration",
28635
- inputs: debugFields(cfg)
29108
+ flow: "settings/agents",
29109
+ step: "01-agents",
29110
+ menuOption: "Configuration > Agents",
29111
+ inputs: { default_agent: loaded.defaultAgent }
28636
29112
  });
28637
29113
  });
28638
29114
  }, []);
28639
- function fieldValue(field) {
28640
- if (!config) return "";
28641
- return config[field] || "";
28642
- }
28643
- function setFieldValue(field, value) {
28644
- if (!config) return;
28645
- setConfig({ ...config, [field]: value });
28646
- setNotice(null);
28647
- }
28648
- function handleSave() {
28649
- if (!config) return;
28650
- setStage("saving");
29115
+ const makeDefault = (name) => {
29116
+ if (!config || saving) return;
29117
+ if (name === config.defaultAgent) {
29118
+ setNotice({ kind: "success", text: `${AGENT_LABELS[name]} is already the default agent` });
29119
+ return;
29120
+ }
29121
+ setSaving(true);
28651
29122
  setNotice(null);
28652
- writeCredentials(config).then(() => {
28653
- setLastSaved(config);
28654
- if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28655
- setNotice({ kind: "success", text: "Configuration saved" });
28656
- setStage("form");
28657
- }).catch((err) => {
28658
- setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
28659
- setStage("form");
28660
- });
29123
+ writeAgentConfig({ ...config, defaultAgent: name }).then(() => {
29124
+ setConfig((current) => current ? { ...current, defaultAgent: name } : current);
29125
+ setNotice({ kind: "success", text: `Default agent is now ${AGENT_LABELS[name]}` });
29126
+ }).catch(
29127
+ (err) => setNotice({
29128
+ kind: "error",
29129
+ text: `Default agent not changed: ${err instanceof Error ? err.message : String(err)}`
29130
+ })
29131
+ ).finally(() => setSaving(false));
29132
+ };
29133
+ useInput12((input, key) => {
29134
+ if (!config || open || saving) return;
29135
+ const focused = AGENT_NAMES[focus];
29136
+ if (key.upArrow || key.downArrow || key.tab) setNotice(null);
29137
+ if (key.upArrow) {
29138
+ setFocus((i) => (i - 1 + AGENT_NAMES.length) % AGENT_NAMES.length);
29139
+ return;
29140
+ }
29141
+ if (key.downArrow || key.tab) {
29142
+ setFocus((i) => (i + 1) % AGENT_NAMES.length);
29143
+ return;
29144
+ }
29145
+ if (key.return) {
29146
+ makeDefault(focused);
29147
+ return;
29148
+ }
29149
+ if (key.rightArrow) {
29150
+ setNotice(null);
29151
+ setOpen(focused);
29152
+ return;
29153
+ }
29154
+ if (key.escape || input === "q") {
29155
+ void finishDebugRun({ outputs: { default_agent: config.defaultAgent }, status: "success", exitMethod: "saved" });
29156
+ onDone();
29157
+ }
29158
+ });
29159
+ if (!config) {
29160
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29161
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
29162
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29163
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "Loading..." })
29164
+ ] });
28661
29165
  }
28662
- function quit() {
28663
- void finishDebugRun(
28664
- lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
29166
+ if (open) {
29167
+ return /* @__PURE__ */ jsx57(
29168
+ AgentDetail,
29169
+ {
29170
+ name: open,
29171
+ config,
29172
+ setConfig,
29173
+ onBack: () => {
29174
+ setOpen(null);
29175
+ void readAgentConfig().then((saved) => {
29176
+ setConfig(saved);
29177
+ inspectAll(saved);
29178
+ });
29179
+ }
29180
+ }
28665
29181
  );
28666
- onDone();
28667
29182
  }
28668
- useInput11((input, key) => {
28669
- if (stage === "loading" || stage === "saving") return;
29183
+ const focusedAgent = AGENT_NAMES[focus];
29184
+ return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29185
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
29186
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "The coding agent the CLI runs, and what was found for each one." }),
29187
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29188
+ /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29189
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Default agent" }),
29190
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: AGENT_LABELS[config.defaultAgent] }),
29191
+ saving && /* @__PURE__ */ jsx57(Text48, { color: PALETTE.accent, children: "\u2026 saving" })
29192
+ ] }),
29193
+ /* @__PURE__ */ jsxs46(Box45, { marginTop: 1, gap: 1, children: [
29194
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29195
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29196
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "AGENT" }) }),
29197
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "STATUS" })
29198
+ ] }),
29199
+ AGENT_NAMES.map((name) => {
29200
+ const isFocused = focusedAgent === name;
29201
+ return /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29202
+ /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " }),
29203
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: name === config.defaultAgent ? "\u2605" : " " }),
29204
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[name] }) }),
29205
+ /* @__PURE__ */ jsx57(AgentStatusBadge, { name, checks: checks[name], binary: config.agents[name].binary })
29206
+ ] }, name);
29207
+ }),
29208
+ /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", marginTop: 1, children: [
29209
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: `\u2500 ${AGENT_LABELS[focusedAgent]} ${"\u2500".repeat(30)}` }),
29210
+ panelRows(focusedAgent, checks[focusedAgent], config.agents[focusedAgent]).map((row) => /* @__PURE__ */ jsxs46(Box45, { gap: 1, paddingLeft: 1, children: [
29211
+ /* @__PURE__ */ jsx57(Box45, { width: PANEL_LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: row.label }) }),
29212
+ /* @__PURE__ */ jsx57(Text48, { color: TONE_COLOR[row.tone], children: row.value })
29213
+ ] }, row.label))
29214
+ ] }),
29215
+ notice && /* @__PURE__ */ jsxs46(Fragment17, { children: [
29216
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29217
+ /* @__PURE__ */ jsxs46(Text48, { bold: true, color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29218
+ notice.kind === "success" ? "\u2713" : "\u2717",
29219
+ " ",
29220
+ notice.text
29221
+ ] })
29222
+ ] }),
29223
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29224
+ /* @__PURE__ */ jsx57(
29225
+ ControlHints,
29226
+ {
29227
+ hints: [
29228
+ { keys: "\u2191/\u2193", label: "move" },
29229
+ { keys: "\u23CE", label: "make default" },
29230
+ { keys: "\u2192", label: "settings and test" },
29231
+ { keys: "Esc/q", label: "back" }
29232
+ ]
29233
+ }
29234
+ )
29235
+ ] });
29236
+ }
29237
+
29238
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx
29239
+ import { useEffect as useEffect24, useState as useState32 } from "react";
29240
+ import { Box as Box47, Text as Text50 } from "ink";
29241
+ init_debug_store();
29242
+
29243
+ // packages/experience-design-system-cli/src/tui/settings/shared/FieldForm.tsx
29244
+ import { useState as useState31 } from "react";
29245
+ import { Box as Box46, Text as Text49, useInput as useInput13 } from "ink";
29246
+ import TextInput5 from "ink-text-input";
29247
+ import { Fragment as Fragment18, jsx as jsx58, jsxs as jsxs47 } from "react/jsx-runtime";
29248
+ function FieldForm({
29249
+ title,
29250
+ subtitle,
29251
+ fields,
29252
+ values,
29253
+ onChange,
29254
+ onSave,
29255
+ onQuit,
29256
+ notice,
29257
+ busy = false,
29258
+ footer
29259
+ }) {
29260
+ const [active, setActive] = useState31(0);
29261
+ const [editing, setEditing] = useState31(false);
29262
+ const [valueBeforeEdit, setValueBeforeEdit] = useState31("");
29263
+ const labelWidth = Math.max(...fields.map((field) => field.label.length));
29264
+ const current = fields[active];
29265
+ useInput13((input, key) => {
29266
+ if (busy) return;
28670
29267
  if (editing) {
28671
29268
  if (key.escape) {
28672
- setFieldValue(activeField, valueBeforeEdit);
29269
+ onChange(current.key, valueBeforeEdit);
28673
29270
  setEditing(false);
28674
29271
  }
28675
29272
  return;
28676
29273
  }
28677
29274
  if (key.escape || input === "q") {
28678
- quit();
29275
+ onQuit();
28679
29276
  return;
28680
29277
  }
28681
29278
  if (input === "s") {
28682
- handleSave();
29279
+ onSave();
28683
29280
  return;
28684
29281
  }
28685
29282
  if (input === "c") {
28686
- setFieldValue(activeField, "");
29283
+ onChange(current.key, "");
28687
29284
  return;
28688
29285
  }
28689
29286
  if (key.tab || key.downArrow) {
28690
- const idx = FIELD_ORDER.indexOf(activeField);
28691
- setActiveField(FIELD_ORDER[(idx + 1) % FIELD_ORDER.length]);
29287
+ setActive((i) => (i + 1) % fields.length);
28692
29288
  return;
28693
29289
  }
28694
29290
  if (key.upArrow) {
28695
- const idx = FIELD_ORDER.indexOf(activeField);
28696
- setActiveField(FIELD_ORDER[(idx - 1 + FIELD_ORDER.length) % FIELD_ORDER.length]);
29291
+ setActive((i) => (i - 1 + fields.length) % fields.length);
28697
29292
  return;
28698
29293
  }
28699
29294
  if (key.return) {
28700
- setValueBeforeEdit(fieldValue(activeField));
29295
+ setValueBeforeEdit(values[current.key]);
28701
29296
  setEditing(true);
28702
29297
  }
28703
29298
  });
28704
- if (stage === "loading") {
28705
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28706
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
28707
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28708
- /* @__PURE__ */ jsx55(Text46, { color: PALETTE.accent, children: "Loading..." })
28709
- ] });
28710
- }
28711
- return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28712
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: "Configuration" }),
28713
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28714
- /* @__PURE__ */ jsx55(Box44, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
28715
- const isActive = activeField === field;
28716
- const value = fieldValue(field);
28717
- const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28718
- return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28719
- /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28720
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28721
- isActive && editing ? /* @__PURE__ */ jsx55(
28722
- TextInput4,
29299
+ return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29300
+ /* @__PURE__ */ jsx58(Text49, { bold: true, children: title }),
29301
+ subtitle && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: subtitle }),
29302
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29303
+ /* @__PURE__ */ jsx58(Box46, { flexDirection: "column", children: fields.map((field, index) => {
29304
+ const isActive = index === active;
29305
+ const value = values[field.key];
29306
+ const display = field.masked ? "\u2022".repeat(value.length) : value;
29307
+ return /* @__PURE__ */ jsxs47(Box46, { gap: 1, children: [
29308
+ /* @__PURE__ */ jsx58(Text49, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
29309
+ /* @__PURE__ */ jsx58(Box46, { width: labelWidth, flexShrink: 0, children: /* @__PURE__ */ jsx58(Text49, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: field.label }) }),
29310
+ isActive && editing ? /* @__PURE__ */ jsx58(
29311
+ TextInput5,
28723
29312
  {
28724
29313
  value,
28725
- onChange: (next) => setFieldValue(field, next),
29314
+ onChange: (next) => onChange(field.key, next),
28726
29315
  onSubmit: () => setEditing(false),
28727
- mask: field === "cmaToken" ? "\u2022" : void 0
29316
+ mask: field.masked ? "\u2022" : void 0
28728
29317
  }
28729
- ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28730
- FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28731
- ] }, field);
29318
+ ) : /* @__PURE__ */ jsx58(Text49, { bold: !!display, children: display || (field.hint ? "" : /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "(empty)" })) }),
29319
+ field.hint && /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: field.hint })
29320
+ ] }, field.key);
28732
29321
  }) }),
28733
- notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
28734
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28735
- /* @__PURE__ */ jsxs45(Text46, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29322
+ notice && /* @__PURE__ */ jsxs47(Fragment18, { children: [
29323
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29324
+ /* @__PURE__ */ jsxs47(Text49, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
28736
29325
  notice.kind === "success" ? "\u2713" : "\u2717",
28737
29326
  " ",
28738
29327
  notice.text
28739
29328
  ] })
28740
29329
  ] }),
28741
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28742
- /* @__PURE__ */ jsx55(
29330
+ footer,
29331
+ /* @__PURE__ */ jsx58(Text49, { children: " " }),
29332
+ /* @__PURE__ */ jsx58(
28743
29333
  ControlHints,
28744
29334
  {
28745
29335
  hints: editing ? [
@@ -28752,7 +29342,168 @@ function ConfigurationScreen({ onDone }) {
28752
29342
  { keys: "\u23CE", label: "edit" },
28753
29343
  { keys: "c", label: "clear" },
28754
29344
  { keys: "s", label: "save" },
28755
- { keys: "Esc/q", label: "quit without saving" }
29345
+ { keys: "Esc/q", label: "back without saving" }
29346
+ ]
29347
+ }
29348
+ )
29349
+ ] });
29350
+ }
29351
+
29352
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
29353
+ async function readCredentials() {
29354
+ const store = await readV1Store();
29355
+ return {
29356
+ spaceId: store.spaceId || "",
29357
+ environmentId: store.environmentId || "",
29358
+ cmaToken: store.cmaToken || "",
29359
+ host: store.host || "",
29360
+ defaultComponentDir: store.defaultComponentDir || "",
29361
+ defaultTokenFile: store.defaultTokenFile || "",
29362
+ contentfulBaseDir: store.contentfulBaseDir || ""
29363
+ };
29364
+ }
29365
+ async function writeCredentials(config) {
29366
+ const existing = await readV1Store();
29367
+ const merged = {
29368
+ ...existing,
29369
+ ...config
29370
+ };
29371
+ Object.keys(merged).forEach((k) => {
29372
+ if (!merged[k]) delete merged[k];
29373
+ });
29374
+ await writeV1Store(merged);
29375
+ }
29376
+
29377
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ProjectConfigScreen.tsx
29378
+ import { jsx as jsx59, jsxs as jsxs48 } from "react/jsx-runtime";
29379
+ var FIELDS3 = [
29380
+ { key: "spaceId", label: "Space ID" },
29381
+ { key: "environmentId", label: "Environment ID" },
29382
+ { key: "cmaToken", label: "CMA Token", masked: true },
29383
+ { key: "host", label: "API Host" },
29384
+ { key: "defaultComponentDir", label: "Default component directory" },
29385
+ { key: "defaultTokenFile", label: "Default token file" },
29386
+ { key: "contentfulBaseDir", label: "Root Project Directory", hint: "(where .contentful goes)" }
29387
+ ];
29388
+ function debugFields(config) {
29389
+ return {
29390
+ space_id: config?.spaceId ?? "",
29391
+ environment_id: config?.environmentId ?? "",
29392
+ cma_token: config?.cmaToken ?? "",
29393
+ host: config?.host ?? "",
29394
+ default_component_dir: config?.defaultComponentDir ?? "",
29395
+ default_token_file: config?.defaultTokenFile ?? "",
29396
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
29397
+ };
29398
+ }
29399
+ var valuesOf = (config) => Object.fromEntries(FIELDS3.map(({ key }) => [key, config[key] || ""]));
29400
+ function ProjectConfigScreen({ onDone }) {
29401
+ const [config, setConfig] = useState32(null);
29402
+ const [saving, setSaving] = useState32(false);
29403
+ const [notice, setNotice] = useState32(null);
29404
+ const [lastSaved, setLastSaved] = useState32(null);
29405
+ useEffect24(() => {
29406
+ void readCredentials().then((cfg) => {
29407
+ setConfig(cfg);
29408
+ startDebugRun({
29409
+ flow: "settings/contentful-configuration",
29410
+ step: "01-configuration",
29411
+ menuOption: "Configuration > Project",
29412
+ inputs: debugFields(cfg)
29413
+ });
29414
+ });
29415
+ }, []);
29416
+ if (!config) {
29417
+ return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29418
+ /* @__PURE__ */ jsx59(Text50, { bold: true, children: "Project" }),
29419
+ /* @__PURE__ */ jsx59(Text50, { children: " " }),
29420
+ /* @__PURE__ */ jsx59(Text50, { color: PALETTE.accent, children: "Loading..." })
29421
+ ] });
29422
+ }
29423
+ const save = () => {
29424
+ setSaving(true);
29425
+ setNotice(null);
29426
+ writeCredentials(config).then(() => {
29427
+ setLastSaved(config);
29428
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
29429
+ setNotice({ kind: "success", text: "Project settings saved" });
29430
+ }).catch((err) => {
29431
+ setNotice({ kind: "error", text: err instanceof Error ? err.message : "Failed to save" });
29432
+ }).finally(() => setSaving(false));
29433
+ };
29434
+ const quit = () => {
29435
+ void finishDebugRun(
29436
+ lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
29437
+ );
29438
+ onDone();
29439
+ };
29440
+ return /* @__PURE__ */ jsx59(
29441
+ FieldForm,
29442
+ {
29443
+ title: "Project",
29444
+ subtitle: "The Contentful space and where the CLI keeps its files.",
29445
+ fields: FIELDS3,
29446
+ values: valuesOf(config),
29447
+ onChange: (key, value) => {
29448
+ setConfig({ ...config, [key]: value });
29449
+ setNotice(null);
29450
+ },
29451
+ onSave: save,
29452
+ onQuit: quit,
29453
+ notice,
29454
+ busy: saving
29455
+ }
29456
+ );
29457
+ }
29458
+
29459
+ // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
29460
+ import { jsx as jsx60, jsxs as jsxs49 } from "react/jsx-runtime";
29461
+ var SECTIONS = [
29462
+ {
29463
+ id: "project",
29464
+ label: "Project",
29465
+ description: "Contentful space, credentials, defaults and where .contentful goes"
29466
+ },
29467
+ { id: "agents", label: "Agents", description: "Which coding agent the CLI uses, and each agent\u2019s settings" }
29468
+ ];
29469
+ function ConfigurationScreen({ onDone }) {
29470
+ const [focus, setFocus] = useState33(0);
29471
+ const [open, setOpen] = useState33(null);
29472
+ const close = () => setOpen(null);
29473
+ useInput14((input, key) => {
29474
+ if (open) return;
29475
+ if (key.upArrow) {
29476
+ setFocus((i) => (i - 1 + SECTIONS.length) % SECTIONS.length);
29477
+ return;
29478
+ }
29479
+ if (key.downArrow || key.tab) {
29480
+ setFocus((i) => (i + 1) % SECTIONS.length);
29481
+ return;
29482
+ }
29483
+ if (key.return) {
29484
+ setOpen(SECTIONS[focus].id);
29485
+ return;
29486
+ }
29487
+ if (key.escape || input === "q") onDone();
29488
+ });
29489
+ if (open === "project") return /* @__PURE__ */ jsx60(ProjectConfigScreen, { onDone: close });
29490
+ if (open === "agents") return /* @__PURE__ */ jsx60(AgentsScreen, { onDone: close });
29491
+ return /* @__PURE__ */ jsxs49(Box48, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29492
+ /* @__PURE__ */ jsx60(Text51, { bold: true, children: "Configuration" }),
29493
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
29494
+ SECTIONS.map((section, index) => /* @__PURE__ */ jsxs49(Box48, { gap: 1, children: [
29495
+ /* @__PURE__ */ jsx60(Text51, { color: index === focus ? PALETTE.accent : void 0, children: index === focus ? "\u276F" : " " }),
29496
+ /* @__PURE__ */ jsx60(Box48, { width: 9, flexShrink: 0, children: /* @__PURE__ */ jsx60(Text51, { bold: index === focus, color: index === focus ? PALETTE.accent : void 0, children: section.label }) }),
29497
+ /* @__PURE__ */ jsx60(Text51, { color: PALETTE.muted, children: section.description })
29498
+ ] }, section.id)),
29499
+ /* @__PURE__ */ jsx60(Text51, { children: " " }),
29500
+ /* @__PURE__ */ jsx60(
29501
+ ControlHints,
29502
+ {
29503
+ hints: [
29504
+ { keys: "\u2191/\u2193", label: "move" },
29505
+ { keys: "\u23CE", label: "open" },
29506
+ { keys: "Esc/q", label: "back" }
28756
29507
  ]
28757
29508
  }
28758
29509
  )
@@ -28760,8 +29511,8 @@ function ConfigurationScreen({ onDone }) {
28760
29511
  }
28761
29512
 
28762
29513
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28763
- import { useEffect as useEffect23, useState as useState30 } from "react";
28764
- import { Box as Box45, Text as Text47, useInput as useInput12 } from "ink";
29514
+ import { useEffect as useEffect25, useState as useState34 } from "react";
29515
+ import { Box as Box49, Text as Text52, useInput as useInput15 } from "ink";
28765
29516
 
28766
29517
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
28767
29518
  async function readAnalyticsSetting() {
@@ -28780,11 +29531,11 @@ async function writeAnalyticsSetting(setting) {
28780
29531
 
28781
29532
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28782
29533
  init_debug_store();
28783
- import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
29534
+ import { Fragment as Fragment19, jsx as jsx61, jsxs as jsxs50 } from "react/jsx-runtime";
28784
29535
  function OptInAnalyticsScreen({ onDone }) {
28785
- const [loading, setLoading] = useState30(true);
28786
- const [enabled, setEnabled] = useState30(true);
28787
- useEffect23(() => {
29536
+ const [loading, setLoading] = useState34(true);
29537
+ const [enabled, setEnabled] = useState34(true);
29538
+ useEffect25(() => {
28788
29539
  readAnalyticsSetting().then((setting) => {
28789
29540
  setEnabled(setting.enabled);
28790
29541
  setLoading(false);
@@ -28796,7 +29547,7 @@ function OptInAnalyticsScreen({ onDone }) {
28796
29547
  });
28797
29548
  });
28798
29549
  }, []);
28799
- useInput12((input, key) => {
29550
+ useInput15((input, key) => {
28800
29551
  if (loading) return;
28801
29552
  if (key.return || input === " ") {
28802
29553
  setEnabled((current) => {
@@ -28811,21 +29562,21 @@ function OptInAnalyticsScreen({ onDone }) {
28811
29562
  onDone();
28812
29563
  }
28813
29564
  });
28814
- return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28815
- /* @__PURE__ */ jsx56(Text47, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
28816
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28817
- loading ? /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs46(Fragment18, { children: [
28818
- /* @__PURE__ */ jsxs46(Text47, { children: [
29565
+ return /* @__PURE__ */ jsxs50(Box49, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29566
+ /* @__PURE__ */ jsx61(Text52, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
29567
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29568
+ loading ? /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs50(Fragment19, { children: [
29569
+ /* @__PURE__ */ jsxs50(Text52, { children: [
28819
29570
  "Share anonymous usage data:",
28820
29571
  " ",
28821
- /* @__PURE__ */ jsx56(Text47, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
29572
+ /* @__PURE__ */ jsx61(Text52, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
28822
29573
  ] }),
28823
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28824
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
28825
- /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
29574
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29575
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Shares which CLI commands are used and where imports succeed or fail." }),
29576
+ /* @__PURE__ */ jsx61(Text52, { color: PALETTE.muted, children: "Never includes source code, file paths, credentials, or authored content." })
28826
29577
  ] }),
28827
- /* @__PURE__ */ jsx56(Text47, { children: " " }),
28828
- /* @__PURE__ */ jsx56(
29578
+ /* @__PURE__ */ jsx61(Text52, { children: " " }),
29579
+ /* @__PURE__ */ jsx61(
28829
29580
  ControlHints,
28830
29581
  {
28831
29582
  hints: [
@@ -28838,15 +29589,15 @@ function OptInAnalyticsScreen({ onDone }) {
28838
29589
  }
28839
29590
 
28840
29591
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28841
- import { useEffect as useEffect24, useState as useState31 } from "react";
28842
- import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
29592
+ import { useEffect as useEffect26, useState as useState35 } from "react";
29593
+ import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
28843
29594
  init_version();
28844
29595
  init_debug_store();
28845
- import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
29596
+ import { jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
28846
29597
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28847
29598
  function UpgradeScreen({ onDone }) {
28848
- const [upgradeCheck, setUpgradeCheck] = useState31();
28849
- useEffect24(() => {
29599
+ const [upgradeCheck, setUpgradeCheck] = useState35();
29600
+ useEffect26(() => {
28850
29601
  startDebugRun({
28851
29602
  flow: "upgrade",
28852
29603
  step: "01-upgrade",
@@ -28855,7 +29606,7 @@ function UpgradeScreen({ onDone }) {
28855
29606
  });
28856
29607
  checkForUpgrade().then(setUpgradeCheck).catch(() => setUpgradeCheck({ status: "error" }));
28857
29608
  }, []);
28858
- useInput13((_input, key) => {
29609
+ useInput16((_input, key) => {
28859
29610
  if (key.return) {
28860
29611
  void finishDebugRun({
28861
29612
  outputs: upgradeCheck ?? {},
@@ -28866,12 +29617,12 @@ function UpgradeScreen({ onDone }) {
28866
29617
  return;
28867
29618
  }
28868
29619
  });
28869
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28870
- /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Upgrade" }),
28871
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
29620
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29621
+ /* @__PURE__ */ jsx62(Text53, { bold: true, children: "Upgrade" }),
29622
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
28872
29623
  renderBody(upgradeCheck),
28873
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
28874
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.accent, children: [
29624
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
29625
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.accent, children: [
28875
29626
  FOCUS_MARKER,
28876
29627
  " Go Back"
28877
29628
  ] })
@@ -28879,47 +29630,47 @@ function UpgradeScreen({ onDone }) {
28879
29630
  }
28880
29631
  function renderBody(upgradeCheck) {
28881
29632
  if (!upgradeCheck) {
28882
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "Checking for updates\u2026" });
29633
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Checking for updates\u2026" });
28883
29634
  }
28884
29635
  if (upgradeCheck.status === "error") {
28885
- return /* @__PURE__ */ jsx57(Text48, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
29636
+ return /* @__PURE__ */ jsx62(Text53, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
28886
29637
  }
28887
29638
  if (upgradeCheck.status === "up-to-date") {
28888
- return /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.success, children: [
29639
+ return /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.success, children: [
28889
29640
  "You're already on the latest version (v",
28890
29641
  upgradeCheck.current,
28891
29642
  ")."
28892
29643
  ] });
28893
29644
  }
28894
- return /* @__PURE__ */ jsxs47(Box46, { flexDirection: "column", children: [
28895
- /* @__PURE__ */ jsxs47(Text48, { color: PALETTE.muted, children: [
28896
- /* @__PURE__ */ jsxs47(Text48, { bold: true, color: PALETTE.success, children: [
29645
+ return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", children: [
29646
+ /* @__PURE__ */ jsxs51(Text53, { color: PALETTE.muted, children: [
29647
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.success, children: [
28897
29648
  "v",
28898
29649
  upgradeCheck.latest
28899
29650
  ] }),
28900
29651
  " ",
28901
29652
  "is available (you're on ",
28902
- /* @__PURE__ */ jsxs47(Text48, { bold: true, children: [
29653
+ /* @__PURE__ */ jsxs51(Text53, { bold: true, children: [
28903
29654
  "v",
28904
29655
  upgradeCheck.current
28905
29656
  ] }),
28906
29657
  "). Exit this program, cd into the root of your local clone of contentful/experience-design-system-sdk-public, then run:"
28907
29658
  ] }),
28908
- /* @__PURE__ */ jsx57(Text48, { children: " " }),
28909
- /* @__PURE__ */ jsx57(Box46, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx57(Text48, { bold: true, children: cmd }, cmd)) })
29659
+ /* @__PURE__ */ jsx62(Text53, { children: " " }),
29660
+ /* @__PURE__ */ jsx62(Box50, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx62(Text53, { bold: true, children: cmd }, cmd)) })
28910
29661
  ] });
28911
29662
  }
28912
29663
 
28913
29664
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28914
- import { useEffect as useEffect25, useState as useState32 } from "react";
28915
- import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
29665
+ import { useEffect as useEffect27, useState as useState36 } from "react";
29666
+ import { Box as Box51, Text as Text54, useInput as useInput17 } from "ink";
28916
29667
  init_debug_mode_store();
28917
29668
  init_debug_store();
28918
- import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
29669
+ import { jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
28919
29670
  function DebugModeScreen({ onDone }) {
28920
- const [loading, setLoading] = useState32(true);
28921
- const [enabled, setEnabled] = useState32(true);
28922
- useEffect25(() => {
29671
+ const [loading, setLoading] = useState36(true);
29672
+ const [enabled, setEnabled] = useState36(true);
29673
+ useEffect27(() => {
28923
29674
  readDebugModeSetting().then((setting) => {
28924
29675
  setEnabled(setting.enabled);
28925
29676
  setLoading(false);
@@ -28931,7 +29682,7 @@ function DebugModeScreen({ onDone }) {
28931
29682
  });
28932
29683
  });
28933
29684
  }, []);
28934
- useInput14((input, key) => {
29685
+ useInput17((input, key) => {
28935
29686
  if (loading) return;
28936
29687
  if (key.return || input === " ") {
28937
29688
  setEnabled((current) => {
@@ -28946,16 +29697,16 @@ function DebugModeScreen({ onDone }) {
28946
29697
  onDone();
28947
29698
  }
28948
29699
  });
28949
- return /* @__PURE__ */ jsxs48(Box47, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28950
- /* @__PURE__ */ jsx58(Text49, { bold: true, children: "Settings \u203A Debug Mode" }),
28951
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
28952
- loading ? /* @__PURE__ */ jsx58(Text49, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs48(Text49, { children: [
29700
+ return /* @__PURE__ */ jsxs52(Box51, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29701
+ /* @__PURE__ */ jsx63(Text54, { bold: true, children: "Settings \u203A Debug Mode" }),
29702
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
29703
+ loading ? /* @__PURE__ */ jsx63(Text54, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs52(Text54, { children: [
28953
29704
  "Debug logging:",
28954
29705
  " ",
28955
- /* @__PURE__ */ jsx58(Text49, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
29706
+ /* @__PURE__ */ jsx63(Text54, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
28956
29707
  ] }),
28957
- /* @__PURE__ */ jsx58(Text49, { children: " " }),
28958
- /* @__PURE__ */ jsx58(
29708
+ /* @__PURE__ */ jsx63(Text54, { children: " " }),
29709
+ /* @__PURE__ */ jsx63(
28959
29710
  ControlHints,
28960
29711
  {
28961
29712
  hints: [
@@ -28968,18 +29719,18 @@ function DebugModeScreen({ onDone }) {
28968
29719
  }
28969
29720
 
28970
29721
  // packages/experience-design-system-cli/app.tsx
28971
- import { Fragment as Fragment19, jsx as jsx59 } from "react/jsx-runtime";
29722
+ import { Fragment as Fragment20, jsx as jsx64 } from "react/jsx-runtime";
28972
29723
  function App({ importOptions, inkClear }) {
28973
- const [screen, setScreen] = useState33("start");
28974
- const [importExitCode, setImportExitCode] = useState33();
29724
+ const [screen, setScreen] = useState37("start");
29725
+ const [importExitCode, setImportExitCode] = useState37();
28975
29726
  const showImportResult = importExitCode !== void 0;
28976
- const [projectPath, setProjectPath] = useState33();
28977
- const [tokensPath, setTokensPath] = useState33();
28978
- const [scannedFiles, setScannedFiles] = useState33();
28979
- const [pendingLaunch, setPendingLaunch] = useState33();
28980
- const [extractionRun, setExtractionRun] = useState33();
29727
+ const [projectPath, setProjectPath] = useState37();
29728
+ const [tokensPath, setTokensPath] = useState37();
29729
+ const [scannedFiles, setScannedFiles] = useState37();
29730
+ const [pendingLaunch, setPendingLaunch] = useState37();
29731
+ const [extractionRun, setExtractionRun] = useState37();
28981
29732
  const extraction = useExtraction(extractionRun?.input);
28982
- const [scopeRun, setScopeRun] = useState33();
29733
+ const [scopeRun, setScopeRun] = useState37();
28983
29734
  const scopeFlow = useScopeGateFlow(
28984
29735
  scopeRun && {
28985
29736
  sessionId: scopeRun.extraction.sessionId,
@@ -28994,12 +29745,12 @@ function App({ importOptions, inkClear }) {
28994
29745
  }
28995
29746
  }
28996
29747
  );
28997
- const [generationInput, setGenerationInput] = useState33();
29748
+ const [generationInput, setGenerationInput] = useState37();
28998
29749
  const generation = useGeneration(generationInput);
28999
- const [flowStart, setFlowStart] = useState33();
29750
+ const [flowStart, setFlowStart] = useState37();
29000
29751
  const flow = useFlow(flowStart, { beforeStepChange: inkClear });
29001
- const [importDefaults, setImportDefaults] = useState33();
29002
- useEffect26(() => {
29752
+ const [importDefaults, setImportDefaults] = useState37();
29753
+ useEffect28(() => {
29003
29754
  if (screen !== "import") {
29004
29755
  setImportDefaults(void 0);
29005
29756
  return;
@@ -29017,7 +29768,7 @@ function App({ importOptions, inkClear }) {
29017
29768
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
29018
29769
  const state2 = await inspectTokens({
29019
29770
  rawTokensPath: tokens,
29020
- contentfulDir: join25(resolveUserPath(projectPath2), ".contentful"),
29771
+ contentfulDir: join26(resolveUserPath(projectPath2), ".contentful"),
29021
29772
  cache: importOptions.cache
29022
29773
  });
29023
29774
  if (state2.kind === "cached") {
@@ -29059,12 +29810,12 @@ function App({ importOptions, inkClear }) {
29059
29810
  }
29060
29811
  });
29061
29812
  };
29062
- useEffect26(() => {
29813
+ useEffect28(() => {
29063
29814
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
29064
29815
  setExtractionRun(void 0);
29065
29816
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
29066
29817
  }, [extraction, extractionRun]);
29067
- useEffect26(() => {
29818
+ useEffect28(() => {
29068
29819
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
29069
29820
  const { extraction: produced, input, generatePromptPath } = scopeRun;
29070
29821
  setGenerationInput({
@@ -29082,7 +29833,7 @@ function App({ importOptions, inkClear }) {
29082
29833
  ...generatePromptPath ? { generatePromptPath } : {}
29083
29834
  });
29084
29835
  }, [scopeFlow, scopeRun, generationInput]);
29085
- useEffect26(() => {
29836
+ useEffect28(() => {
29086
29837
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
29087
29838
  const { credentialsSkipped, tokenStrategy, extraction: produced, input, generatePromptPath } = scopeRun;
29088
29839
  inkClear();
@@ -29125,9 +29876,9 @@ function App({ importOptions, inkClear }) {
29125
29876
  };
29126
29877
  switch (screen) {
29127
29878
  case "import":
29128
- if (showImportResult) return /* @__PURE__ */ jsx59(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
29879
+ if (showImportResult) return /* @__PURE__ */ jsx64(ImportScreen, { exitCode: importExitCode, onDone: finishImportResult });
29129
29880
  if (flow && flowStart) {
29130
- return /* @__PURE__ */ jsx59(
29881
+ return /* @__PURE__ */ jsx64(
29131
29882
  FlowScreen,
29132
29883
  {
29133
29884
  state: flow.state,
@@ -29137,12 +29888,12 @@ function App({ importOptions, inkClear }) {
29137
29888
  }
29138
29889
  );
29139
29890
  }
29140
- if (importDefaults === void 0) return /* @__PURE__ */ jsx59(Fragment19, {});
29891
+ if (importDefaults === void 0) return /* @__PURE__ */ jsx64(Fragment20, {});
29141
29892
  if (projectPath === void 0) {
29142
- return /* @__PURE__ */ jsx59(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
29893
+ return /* @__PURE__ */ jsx64(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
29143
29894
  }
29144
29895
  if (tokensPath === void 0) {
29145
- return /* @__PURE__ */ jsx59(
29896
+ return /* @__PURE__ */ jsx64(
29146
29897
  TokenInputScreen,
29147
29898
  {
29148
29899
  initialPath: importDefaults.tokenFile,
@@ -29152,7 +29903,7 @@ function App({ importOptions, inkClear }) {
29152
29903
  );
29153
29904
  }
29154
29905
  if (scannedFiles === void 0) {
29155
- return /* @__PURE__ */ jsx59(
29906
+ return /* @__PURE__ */ jsx64(
29156
29907
  PathValidationScreen,
29157
29908
  {
29158
29909
  projectPath,
@@ -29164,10 +29915,10 @@ function App({ importOptions, inkClear }) {
29164
29915
  }
29165
29916
  if (extractionRun) {
29166
29917
  if (extraction?.status === "done" && !extraction.result.ok) {
29167
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
29918
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: extraction.result.step, message: extraction.result.message, onExit: leaveImport });
29168
29919
  }
29169
29920
  if (extraction?.status === "running") {
29170
- return /* @__PURE__ */ jsx59(
29921
+ return /* @__PURE__ */ jsx64(
29171
29922
  ExtractionScreen,
29172
29923
  {
29173
29924
  progress: extraction.progress,
@@ -29176,14 +29927,14 @@ function App({ importOptions, inkClear }) {
29176
29927
  }
29177
29928
  );
29178
29929
  }
29179
- return /* @__PURE__ */ jsx59(Fragment19, {});
29930
+ return /* @__PURE__ */ jsx64(Fragment20, {});
29180
29931
  }
29181
29932
  if (scopeRun && scopeFlow) {
29182
29933
  if (scopeFlow.status === "failed") {
29183
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
29934
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: "scope gate", message: scopeFlow.message, onExit: leaveImport });
29184
29935
  }
29185
29936
  if (scopeFlow.status === "deciding") {
29186
- return /* @__PURE__ */ jsx59(
29937
+ return /* @__PURE__ */ jsx64(
29187
29938
  ScopeGateScreen,
29188
29939
  {
29189
29940
  components: scopeFlow.load.components,
@@ -29193,7 +29944,7 @@ function App({ importOptions, inkClear }) {
29193
29944
  );
29194
29945
  }
29195
29946
  if (generation?.status === "done" && !generation.result.ok) {
29196
- return /* @__PURE__ */ jsx59(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
29947
+ return /* @__PURE__ */ jsx64(ErrorStep, { stepName: generation.result.step, message: generation.result.message, onExit: leaveImport });
29197
29948
  }
29198
29949
  if (generation?.status === "running") {
29199
29950
  const hasRawTokens = scopeRun.input.rawTokensPath !== "";
@@ -29201,7 +29952,7 @@ function App({ importOptions, inkClear }) {
29201
29952
  hasRawTokens,
29202
29953
  mapTokensEligible: generation.progress.mapTokensEligible
29203
29954
  });
29204
- return /* @__PURE__ */ jsx59(
29955
+ return /* @__PURE__ */ jsx64(
29205
29956
  GenerationScreen,
29206
29957
  {
29207
29958
  progress: generation.progress,
@@ -29213,10 +29964,10 @@ function App({ importOptions, inkClear }) {
29213
29964
  }
29214
29965
  );
29215
29966
  }
29216
- return /* @__PURE__ */ jsx59(Fragment19, {});
29967
+ return /* @__PURE__ */ jsx64(Fragment20, {});
29217
29968
  }
29218
29969
  if (pendingLaunch?.cached) {
29219
- return /* @__PURE__ */ jsx59(
29970
+ return /* @__PURE__ */ jsx64(
29220
29971
  TokenReuseScreen,
29221
29972
  {
29222
29973
  tokensPath: pendingLaunch.cached.tokensPath,
@@ -29227,7 +29978,7 @@ function App({ importOptions, inkClear }) {
29227
29978
  }
29228
29979
  );
29229
29980
  }
29230
- return /* @__PURE__ */ jsx59(
29981
+ return /* @__PURE__ */ jsx64(
29231
29982
  CredentialsScreen,
29232
29983
  {
29233
29984
  initial: importDefaults.credentials,
@@ -29236,19 +29987,19 @@ function App({ importOptions, inkClear }) {
29236
29987
  }
29237
29988
  );
29238
29989
  case "help":
29239
- return /* @__PURE__ */ jsx59(HelpScreen, { onDone: goToStart });
29990
+ return /* @__PURE__ */ jsx64(HelpScreen, { onDone: goToStart });
29240
29991
  case "upgrade":
29241
- return /* @__PURE__ */ jsx59(UpgradeScreen, { onDone: goToStart });
29992
+ return /* @__PURE__ */ jsx64(UpgradeScreen, { onDone: goToStart });
29242
29993
  case "settings":
29243
- return /* @__PURE__ */ jsx59(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
29994
+ return /* @__PURE__ */ jsx64(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
29244
29995
  case "settings-configuration":
29245
- return /* @__PURE__ */ jsx59(ConfigurationScreen, { onDone: goToSettings });
29996
+ return /* @__PURE__ */ jsx64(ConfigurationScreen, { onDone: goToSettings });
29246
29997
  case "settings-opt-in-analytics":
29247
- return /* @__PURE__ */ jsx59(OptInAnalyticsScreen, { onDone: goToSettings });
29998
+ return /* @__PURE__ */ jsx64(OptInAnalyticsScreen, { onDone: goToSettings });
29248
29999
  case "settings-debug-mode":
29249
- return /* @__PURE__ */ jsx59(DebugModeScreen, { onDone: goToSettings });
30000
+ return /* @__PURE__ */ jsx64(DebugModeScreen, { onDone: goToSettings });
29250
30001
  case "start":
29251
- return /* @__PURE__ */ jsx59(HomeScreen, { onNavigate: setScreen });
30002
+ return /* @__PURE__ */ jsx64(HomeScreen, { onNavigate: setScreen });
29252
30003
  }
29253
30004
  }
29254
30005
  async function runApp(renderApp, importOptions) {
@@ -29256,7 +30007,7 @@ async function runApp(renderApp, importOptions) {
29256
30007
  instance.clear?.();
29257
30008
  process.stdout.write("\x1B[H\x1B[0J");
29258
30009
  };
29259
- const instance = renderApp(/* @__PURE__ */ jsx59(App, { importOptions, inkClear }));
30010
+ const instance = renderApp(/* @__PURE__ */ jsx64(App, { importOptions, inkClear }));
29260
30011
  await instance.waitUntilExit();
29261
30012
  }
29262
30013
  export {