@contentful/experience-design-system-cli 2.37.1-dev-build-0b786a83.0 → 2.37.1-dev-build-9afe163e.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
@@ -4286,9 +4286,9 @@ async function resolveRelativeImport(specifier, fromDir) {
4286
4286
  async function resolveImportSpecifiers(sourceText, fromDir) {
4287
4287
  const resolvedPaths = [];
4288
4288
  for (const specifier of extractRelativeImportPaths(sourceText)) {
4289
- const resolvedPath2 = await resolveRelativeImport(specifier, fromDir);
4290
- if (resolvedPath2)
4291
- resolvedPaths.push(resolvedPath2);
4289
+ const resolvedPath = await resolveRelativeImport(specifier, fromDir);
4290
+ if (resolvedPath)
4291
+ resolvedPaths.push(resolvedPath);
4292
4292
  }
4293
4293
  return resolvedPaths;
4294
4294
  }
@@ -4302,20 +4302,20 @@ async function loadSiblingFiles(sourceText, sourcePath, propNames, candidateType
4302
4302
  if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
4303
4303
  break;
4304
4304
  const resolvedPaths = await resolveImportSpecifiers(node.text, node.dir);
4305
- for (const resolvedPath2 of resolvedPaths) {
4306
- if (visited.has(resolvedPath2))
4305
+ for (const resolvedPath of resolvedPaths) {
4306
+ if (visited.has(resolvedPath))
4307
4307
  continue;
4308
- visited.add(resolvedPath2);
4308
+ visited.add(resolvedPath);
4309
4309
  if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
4310
4310
  break;
4311
4311
  let content;
4312
4312
  try {
4313
- content = await readFile4(resolvedPath2, "utf8");
4313
+ content = await readFile4(resolvedPath, "utf8");
4314
4314
  } catch {
4315
4315
  continue;
4316
4316
  }
4317
- discovered.push({ path: resolvedPath2, content });
4318
- nextFrontier.push({ text: content, dir: dirname4(resolvedPath2) });
4317
+ discovered.push({ path: resolvedPath, content });
4318
+ nextFrontier.push({ text: content, dir: dirname4(resolvedPath) });
4319
4319
  }
4320
4320
  }
4321
4321
  frontier = nextFrontier;
@@ -5280,11 +5280,11 @@ function isBareModuleSpecifier(moduleSpecifier) {
5280
5280
  return !moduleSpecifier.startsWith(".") && !moduleSpecifier.startsWith("/");
5281
5281
  }
5282
5282
  function findRepoLocalAliasSourceFile(originSourceFile, moduleSpecifier) {
5283
- const resolvedPath2 = resolveRepoLocalAliasImportPath(originSourceFile.getFilePath(), moduleSpecifier);
5284
- if (!resolvedPath2)
5283
+ const resolvedPath = resolveRepoLocalAliasImportPath(originSourceFile.getFilePath(), moduleSpecifier);
5284
+ if (!resolvedPath)
5285
5285
  return void 0;
5286
5286
  const project = originSourceFile.getProject();
5287
- return findProjectSourceFileByImportPath(project, resolvedPath2);
5287
+ return findProjectSourceFileByImportPath(project, resolvedPath);
5288
5288
  }
5289
5289
  function resolveRepoLocalAliasImportPath(importingFilePath, moduleSpecifier) {
5290
5290
  const nearestTsConfigPath = findNearestTsConfigPath(importingFilePath);
@@ -5299,8 +5299,8 @@ function resolveRepoLocalAliasImportPath(importingFilePath, moduleSpecifier) {
5299
5299
  continue;
5300
5300
  for (const targetPattern of targets) {
5301
5301
  const substitutedTarget = substituteTsConfigPathTarget(targetPattern, match2.wildcard);
5302
- const resolvedPath2 = resolve7(tsConfigPaths.baseUrl, substitutedTarget);
5303
- const sourceFilePath = resolveImportSourcePath(resolvedPath2);
5302
+ const resolvedPath = resolve7(tsConfigPaths.baseUrl, substitutedTarget);
5303
+ const sourceFilePath = resolveImportSourcePath(resolvedPath);
5304
5304
  if (sourceFilePath)
5305
5305
  return sourceFilePath;
5306
5306
  }
@@ -5378,17 +5378,17 @@ function resolveImportSourcePath(basePath) {
5378
5378
  ];
5379
5379
  return candidates.find((candidatePath) => existsSync3(candidatePath));
5380
5380
  }
5381
- function findProjectSourceFileByImportPath(project, resolvedPath2) {
5381
+ function findProjectSourceFileByImportPath(project, resolvedPath) {
5382
5382
  const candidatePaths = [
5383
- resolvedPath2,
5384
- `${resolvedPath2}.ts`,
5385
- `${resolvedPath2}.tsx`,
5386
- `${resolvedPath2}.js`,
5387
- `${resolvedPath2}.jsx`,
5388
- join5(resolvedPath2, "index.ts"),
5389
- join5(resolvedPath2, "index.tsx"),
5390
- join5(resolvedPath2, "index.js"),
5391
- join5(resolvedPath2, "index.jsx")
5383
+ resolvedPath,
5384
+ `${resolvedPath}.ts`,
5385
+ `${resolvedPath}.tsx`,
5386
+ `${resolvedPath}.js`,
5387
+ `${resolvedPath}.jsx`,
5388
+ join5(resolvedPath, "index.ts"),
5389
+ join5(resolvedPath, "index.tsx"),
5390
+ join5(resolvedPath, "index.js"),
5391
+ join5(resolvedPath, "index.jsx")
5392
5392
  ];
5393
5393
  for (const candidatePath of candidatePaths) {
5394
5394
  const sourceFile = project.getSourceFile(candidatePath);
@@ -9899,11 +9899,11 @@ function getElementTagNameFromFastDefinition(classDecl, project) {
9899
9899
  }
9900
9900
  function resolveImportSourcePath2(fromFilePath, specifier) {
9901
9901
  if (specifier.startsWith(".")) {
9902
- const resolvedPath2 = resolve10(dirname8(fromFilePath), specifier);
9903
- if (resolvedPath2.endsWith(".js")) {
9904
- return `${resolvedPath2.slice(0, -3)}.ts`;
9902
+ const resolvedPath = resolve10(dirname8(fromFilePath), specifier);
9903
+ if (resolvedPath.endsWith(".js")) {
9904
+ return `${resolvedPath.slice(0, -3)}.ts`;
9905
9905
  }
9906
- return resolvedPath2;
9906
+ return resolvedPath;
9907
9907
  }
9908
9908
  const spectrumPrefix = "@spectrum-web-components/core/components/";
9909
9909
  if (!specifier.startsWith(spectrumPrefix)) {
@@ -17126,15 +17126,15 @@ function PathValidationScreen({
17126
17126
  onChangePath,
17127
17127
  onBack
17128
17128
  }) {
17129
- const resolvedPath2 = useMemo(() => resolveUserPath(projectPath), [projectPath]);
17129
+ const resolvedPath = useMemo(() => resolveUserPath(projectPath), [projectPath]);
17130
17130
  const [scan, setScan] = useState5();
17131
17131
  useEffect3(() => {
17132
- setScan(scanFiles(resolvedPath2));
17133
- }, [resolvedPath2]);
17132
+ setScan(scanFiles(resolvedPath));
17133
+ }, [resolvedPath]);
17134
17134
  const phase = phaseOf(scan);
17135
17135
  usePathValidationControls(phase, {
17136
17136
  onConfirm: () => {
17137
- if (scan?.ok) onConfirm({ projectPath: resolvedPath2, filePaths: scan.filePaths });
17137
+ if (scan?.ok) onConfirm({ projectPath: resolvedPath, filePaths: scan.filePaths });
17138
17138
  },
17139
17139
  onChangePath,
17140
17140
  onBack
@@ -17142,11 +17142,11 @@ function PathValidationScreen({
17142
17142
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
17143
17143
  scan === void 0 && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
17144
17144
  "Scanning ",
17145
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: resolvedPath2 }),
17145
+ /* @__PURE__ */ jsx6(Text6, { bold: true, children: resolvedPath }),
17146
17146
  "..."
17147
17147
  ] }),
17148
- scan?.ok === false && /* @__PURE__ */ jsx6(Failure, { scan, path: resolvedPath2 }),
17149
- scan?.ok === true && /* @__PURE__ */ jsx6(Summary, { scan, path: resolvedPath2 }),
17148
+ scan?.ok === false && /* @__PURE__ */ jsx6(Failure, { scan, path: resolvedPath }),
17149
+ scan?.ok === true && /* @__PURE__ */ jsx6(Summary, { scan, path: resolvedPath }),
17150
17150
  /* @__PURE__ */ jsx6(Box5, { marginTop: 1, gap: 3, children: controlsFor(phase).map((control) => /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
17151
17151
  "[",
17152
17152
  control.keys,
@@ -28760,9 +28760,41 @@ function nextStepHint(name, status) {
28760
28760
  if (status === "unknown") return "run a full test to confirm it is logged in";
28761
28761
  return "";
28762
28762
  }
28763
- function resolvedPath(checks) {
28764
- const path5 = checks?.find((check) => check.step === "path");
28765
- return path5?.ok ? path5.detail : "";
28763
+ var LIST_STATUS = {
28764
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
28765
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
28766
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
28767
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
28768
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
28769
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
28770
+ };
28771
+ function modelLine(name, savedModel) {
28772
+ const model = savedModel.trim();
28773
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
28774
+ }
28775
+ function panelRows(name, checks, settings) {
28776
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
28777
+ const status = statusFromChecks(name, checks, settings.binary);
28778
+ const path5 = checks.find((check) => check.step === "path");
28779
+ if (!path5?.ok) {
28780
+ const rows2 = [
28781
+ {
28782
+ label: "Command",
28783
+ value: settings.binary.trim() ? path5?.detail ?? "not found" : "not found on your PATH",
28784
+ tone: settings.binary.trim() ? "bad" : "muted"
28785
+ }
28786
+ ];
28787
+ const hint2 = nextStepHint(name, status);
28788
+ if (hint2) rows2.push({ label: "Next", value: hint2, tone: "muted" });
28789
+ return rows2;
28790
+ }
28791
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
28792
+ const version = checks.find((check) => check.step === "version");
28793
+ if (version?.ok) rows.push({ label: "Version", value: version.detail, tone: "ok" });
28794
+ rows.push({ label: "Model", value: modelLine(name, settings.model), tone: "muted" });
28795
+ const hint = nextStepHint(name, status);
28796
+ if (hint) rows.push({ label: "Next", value: hint, tone: "muted" });
28797
+ return rows;
28766
28798
  }
28767
28799
  function statusRows(_name, checks, savedBinary) {
28768
28800
  if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
@@ -28811,9 +28843,26 @@ async function withBinaryEnv(name, binary, run) {
28811
28843
 
28812
28844
  // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28813
28845
  import { useEffect as useEffect22, useState as useState29 } from "react";
28814
- import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28846
+ import { Box as Box44, Text as Text47, useInput as useInput11 } from "ink";
28815
28847
  import TextInput4 from "ink-text-input";
28816
28848
 
28849
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
28850
+ import { Text as Text46 } from "ink";
28851
+ import { jsx as jsx55 } from "react/jsx-runtime";
28852
+ var TONE_COLOR = {
28853
+ ok: PALETTE.success,
28854
+ bad: PALETTE.error,
28855
+ muted: PALETTE.muted
28856
+ };
28857
+ function AgentStatusBadge({
28858
+ name,
28859
+ checks,
28860
+ binary
28861
+ }) {
28862
+ const { symbol, text, tone } = LIST_STATUS[checks ? statusFromChecks(name, checks, binary) : "checking"];
28863
+ return /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[tone], children: `${symbol} ${text}` });
28864
+ }
28865
+
28817
28866
  // packages/experience-design-system-cli/src/tui/settings/agents/apply-binary-overrides.ts
28818
28867
  var shellValues = /* @__PURE__ */ new Map();
28819
28868
  function applyBinaryOverrides(config) {
@@ -28833,20 +28882,15 @@ function applyBinaryOverrides(config) {
28833
28882
  }
28834
28883
 
28835
28884
  // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
28836
- import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28885
+ import { Fragment as Fragment17, jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
28837
28886
  var FOCUS_ORDER = ["binary", "model", "test"];
28838
28887
  var FIELDS2 = ["binary", "model"];
28839
28888
  var FIELD_LABEL = { binary: "Command path", model: "Model" };
28840
28889
  var LABEL_WIDTH = "Command path".length;
28841
- var TONE_COLOR = {
28842
- ok: PALETTE.success,
28843
- bad: PALETTE.error,
28844
- muted: PALETTE.muted
28845
- };
28846
28890
  var fieldHint = (name, field) => field === "binary" ? `(empty: \`${AGENT_HINTS[name]}\` from the PATH)` : `(empty: ${defaultModelLabel(name)})`;
28847
28891
  function Section2({ title, children }) {
28848
28892
  return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", marginTop: 1, children: [
28849
- /* @__PURE__ */ jsx55(Text46, { bold: true, color: PALETTE.muted, children: title }),
28893
+ /* @__PURE__ */ jsx56(Text47, { bold: true, color: PALETTE.muted, children: title }),
28850
28894
  children
28851
28895
  ] });
28852
28896
  }
@@ -28936,52 +28980,52 @@ function AgentDetail({
28936
28980
  });
28937
28981
  const status = checks ? statusFromChecks(name, checks, settings.binary) : "checking";
28938
28982
  const hint = nextStepHint(name, status);
28939
- const pointer = (isFocused) => /* @__PURE__ */ jsx55(Text46, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
28983
+ const pointer = (isFocused) => /* @__PURE__ */ jsx56(Text47, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
28940
28984
  return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
28941
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: AGENT_LABELS[name] }),
28942
- /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
28985
+ /* @__PURE__ */ jsx56(Text47, { bold: true, children: AGENT_LABELS[name] }),
28986
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
28943
28987
  /* @__PURE__ */ jsxs45(Section2, { title: "STATUS", children: [
28944
28988
  statusRows(name, checks, settings.binary).map((row) => /* @__PURE__ */ jsxs45(Box44, { gap: 1, paddingLeft: 2, children: [
28945
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: row.label }) }),
28946
- /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[row.tone], children: row.value })
28989
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: row.label }) }),
28990
+ /* @__PURE__ */ jsx56(Text47, { color: TONE_COLOR[row.tone], children: row.value })
28947
28991
  ] }, row.label)),
28948
- hint && /* @__PURE__ */ jsx55(Box44, { paddingLeft: 2, children: /* @__PURE__ */ jsxs45(Text46, { color: PALETTE.muted, children: [
28992
+ hint && /* @__PURE__ */ jsx56(Box44, { paddingLeft: 2, children: /* @__PURE__ */ jsxs45(Text47, { color: PALETTE.muted, children: [
28949
28993
  "Next: ",
28950
28994
  hint
28951
28995
  ] }) })
28952
28996
  ] }),
28953
- /* @__PURE__ */ jsx55(Section2, { title: "SETTINGS", children: FIELDS2.map((field) => {
28997
+ /* @__PURE__ */ jsx56(Section2, { title: "SETTINGS", children: FIELDS2.map((field) => {
28954
28998
  const isFocused = focused === field;
28955
28999
  const value = settings[field];
28956
29000
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28957
29001
  pointer(isFocused),
28958
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: FIELD_LABEL[field] }) }),
28959
- isFocused && editing ? /* @__PURE__ */ jsx55(
29002
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: FIELD_LABEL[field] }) }),
29003
+ isFocused && editing ? /* @__PURE__ */ jsx56(
28960
29004
  TextInput4,
28961
29005
  {
28962
29006
  value,
28963
29007
  onChange: (next) => setField(field, next),
28964
29008
  onSubmit: () => setEditing(false)
28965
29009
  }
28966
- ) : /* @__PURE__ */ jsx55(Text46, { bold: true, children: value }),
28967
- !value && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: fieldHint(name, field) })
29010
+ ) : /* @__PURE__ */ jsx56(Text47, { bold: true, children: value }),
29011
+ !value && /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: fieldHint(name, field) })
28968
29012
  ] }, field);
28969
29013
  }) }),
28970
- /* @__PURE__ */ jsx55(Section2, { title: "ACTIONS", children: /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
29014
+ /* @__PURE__ */ jsx56(Section2, { title: "ACTIONS", children: /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28971
29015
  pointer(focused === "test"),
28972
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted, children: "Run test" }) }),
28973
- /* @__PURE__ */ jsx55(Text46, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
29016
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted, children: "Run test" }) }),
29017
+ /* @__PURE__ */ jsx56(Text47, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
28974
29018
  ] }) }),
28975
29019
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
28976
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28977
- /* @__PURE__ */ jsxs45(Text46, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29020
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
29021
+ /* @__PURE__ */ jsxs45(Text47, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
28978
29022
  notice.kind === "success" ? "\u2713" : "\u2717",
28979
29023
  " ",
28980
29024
  notice.text
28981
29025
  ] })
28982
29026
  ] }),
28983
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
28984
- /* @__PURE__ */ jsx55(
29027
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
29028
+ /* @__PURE__ */ jsx56(
28985
29029
  ControlHints,
28986
29030
  {
28987
29031
  hints: editing ? [
@@ -29001,39 +29045,11 @@ function AgentDetail({
29001
29045
  ] });
29002
29046
  }
29003
29047
 
29004
- // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
29005
- import { Text as Text47 } from "ink";
29006
- import { jsx as jsx56 } from "react/jsx-runtime";
29007
- var STATUS_TEXT = {
29008
- checking: "checking...",
29009
- ready: "ready",
29010
- "not-configured": "not configured",
29011
- "not-found": "not found",
29012
- "not-logged-in": "not logged in",
29013
- unknown: "found, login not checked"
29014
- };
29015
- var STATUS_COLOR = {
29016
- checking: PALETTE.muted,
29017
- ready: PALETTE.success,
29018
- "not-configured": PALETTE.muted,
29019
- "not-found": PALETTE.error,
29020
- "not-logged-in": PALETTE.error,
29021
- unknown: PALETTE.muted
29022
- };
29023
- function AgentStatusBadge({
29024
- name,
29025
- checks,
29026
- binary
29027
- }) {
29028
- const status = checks ? statusFromChecks(name, checks, binary) : "checking";
29029
- return /* @__PURE__ */ jsx56(Text47, { color: STATUS_COLOR[status], children: STATUS_TEXT[status] });
29030
- }
29031
-
29032
29048
  // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
29033
29049
  import { Fragment as Fragment18, jsx as jsx57, jsxs as jsxs46 } from "react/jsx-runtime";
29034
29050
  var ROWS = [{ kind: "default" }, ...AGENT_NAMES.map((name) => ({ kind: "agent", name }))];
29035
- var MAX_PATH_WIDTH = 44;
29036
- var shortenPath = (path5) => path5.length > MAX_PATH_WIDTH ? `\u2026${path5.slice(-(MAX_PATH_WIDTH - 1))}` : path5;
29051
+ var NAME_WIDTH = 16;
29052
+ var PANEL_LABEL_WIDTH = "Command".length;
29037
29053
  function AgentsScreen({ onDone }) {
29038
29054
  const [config, setConfig] = useState30(null);
29039
29055
  const [focus, setFocus] = useState30(0);
@@ -29071,6 +29087,7 @@ function AgentsScreen({ onDone }) {
29071
29087
  useInput12((input, key) => {
29072
29088
  if (!config || open) return;
29073
29089
  const row = ROWS[focus];
29090
+ if (key.upArrow || key.downArrow || key.tab) setNotice(null);
29074
29091
  if (key.upArrow) {
29075
29092
  setFocus((i) => (i - 1 + ROWS.length) % ROWS.length);
29076
29093
  return;
@@ -29121,29 +29138,46 @@ function AgentsScreen({ onDone }) {
29121
29138
  }
29122
29139
  );
29123
29140
  }
29141
+ const focusedRow = ROWS[focus];
29142
+ const focusedAgent = focusedRow.kind === "agent" ? focusedRow.name : null;
29124
29143
  return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29125
29144
  /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
29126
29145
  /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "The coding agent the CLI runs, and what was found for each one." }),
29127
29146
  /* @__PURE__ */ jsx57(Text48, { children: " " }),
29128
- ROWS.map((row, index) => {
29129
- const isFocused = index === focus;
29130
- const pointer = /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
29131
- if (row.kind === "default") {
29132
- return /* @__PURE__ */ jsx57(Box45, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29133
- pointer,
29134
- /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: "Default agent" }),
29135
- /* @__PURE__ */ jsx57(Text48, { bold: true, children: `\u2039 ${AGENT_LABELS[config.defaultAgent]} \u203A` })
29136
- ] }) }, "default");
29137
- }
29138
- const saved = config.agents[row.name].binary;
29147
+ /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29148
+ /* @__PURE__ */ jsx57(Text48, { color: focusedRow.kind === "default" ? PALETTE.accent : void 0, children: focusedRow.kind === "default" ? "\u276F" : " " }),
29149
+ /* @__PURE__ */ jsx57(
29150
+ Text48,
29151
+ {
29152
+ bold: focusedRow.kind === "default",
29153
+ color: focusedRow.kind === "default" ? PALETTE.accent : PALETTE.muted,
29154
+ children: "Default agent"
29155
+ }
29156
+ ),
29157
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: `\u2039 ${AGENT_LABELS[config.defaultAgent]} \u203A` })
29158
+ ] }),
29159
+ /* @__PURE__ */ jsxs46(Box45, { marginTop: 1, gap: 1, children: [
29160
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29161
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
29162
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "AGENT" }) }),
29163
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "STATUS" })
29164
+ ] }),
29165
+ AGENT_NAMES.map((name) => {
29166
+ const isFocused = focusedAgent === name;
29139
29167
  return /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
29140
- pointer,
29141
- /* @__PURE__ */ jsx57(Box45, { width: 16, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[row.name] }) }),
29142
- /* @__PURE__ */ jsx57(Box45, { width: 26, flexShrink: 0, children: /* @__PURE__ */ jsx57(AgentStatusBadge, { name: row.name, checks: checks[row.name], binary: saved }) }),
29143
- /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: shortenPath(resolvedPath(checks[row.name]) || saved) }),
29144
- row.name === config.defaultAgent && /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: "(default)" })
29145
- ] }, row.name);
29168
+ /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " }),
29169
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: name === config.defaultAgent ? "\u2605" : " " }),
29170
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[name] }) }),
29171
+ /* @__PURE__ */ jsx57(AgentStatusBadge, { name, checks: checks[name], binary: config.agents[name].binary })
29172
+ ] }, name);
29146
29173
  }),
29174
+ focusedAgent && /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", marginTop: 1, children: [
29175
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: `\u2500 ${AGENT_LABELS[focusedAgent]} ${"\u2500".repeat(30)}` }),
29176
+ panelRows(focusedAgent, checks[focusedAgent], config.agents[focusedAgent]).map((row) => /* @__PURE__ */ jsxs46(Box45, { gap: 1, paddingLeft: 1, children: [
29177
+ /* @__PURE__ */ jsx57(Box45, { width: PANEL_LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: row.label }) }),
29178
+ /* @__PURE__ */ jsx57(Text48, { color: TONE_COLOR[row.tone], children: row.value })
29179
+ ] }, row.label))
29180
+ ] }),
29147
29181
  notice && /* @__PURE__ */ jsxs46(Fragment18, { children: [
29148
29182
  /* @__PURE__ */ jsx57(Text48, { children: " " }),
29149
29183
  /* @__PURE__ */ jsxs46(Text48, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
@@ -29156,13 +29190,13 @@ function AgentsScreen({ onDone }) {
29156
29190
  /* @__PURE__ */ jsx57(
29157
29191
  ControlHints,
29158
29192
  {
29159
- hints: ROWS[focus].kind === "default" ? [
29193
+ hints: focusedRow.kind === "default" ? [
29160
29194
  { keys: "\u2191/\u2193", label: "move" },
29161
29195
  { keys: "\u2190/\u2192", label: "change default agent" },
29162
29196
  { keys: "Esc/q", label: "back" }
29163
29197
  ] : [
29164
29198
  { keys: "\u2191/\u2193", label: "move" },
29165
- { keys: "\u23CE", label: "open" },
29199
+ { keys: "\u23CE", label: "settings and test" },
29166
29200
  { keys: "Esc/q", label: "back" }
29167
29201
  ]
29168
29202
  }
package/dist/index.js CHANGED
@@ -3426,9 +3426,9 @@ async function resolveRelativeImport(specifier, fromDir) {
3426
3426
  async function resolveImportSpecifiers(sourceText, fromDir) {
3427
3427
  const resolvedPaths = [];
3428
3428
  for (const specifier of extractRelativeImportPaths(sourceText)) {
3429
- const resolvedPath2 = await resolveRelativeImport(specifier, fromDir);
3430
- if (resolvedPath2)
3431
- resolvedPaths.push(resolvedPath2);
3429
+ const resolvedPath = await resolveRelativeImport(specifier, fromDir);
3430
+ if (resolvedPath)
3431
+ resolvedPaths.push(resolvedPath);
3432
3432
  }
3433
3433
  return resolvedPaths;
3434
3434
  }
@@ -3442,20 +3442,20 @@ async function loadSiblingFiles(sourceText, sourcePath, propNames, candidateType
3442
3442
  if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
3443
3443
  break;
3444
3444
  const resolvedPaths = await resolveImportSpecifiers(node.text, node.dir);
3445
- for (const resolvedPath2 of resolvedPaths) {
3446
- if (visited.has(resolvedPath2))
3445
+ for (const resolvedPath of resolvedPaths) {
3446
+ if (visited.has(resolvedPath))
3447
3447
  continue;
3448
- visited.add(resolvedPath2);
3448
+ visited.add(resolvedPath);
3449
3449
  if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
3450
3450
  break;
3451
3451
  let content;
3452
3452
  try {
3453
- content = await readFile4(resolvedPath2, "utf8");
3453
+ content = await readFile4(resolvedPath, "utf8");
3454
3454
  } catch {
3455
3455
  continue;
3456
3456
  }
3457
- discovered.push({ path: resolvedPath2, content });
3458
- nextFrontier.push({ text: content, dir: dirname3(resolvedPath2) });
3457
+ discovered.push({ path: resolvedPath, content });
3458
+ nextFrontier.push({ text: content, dir: dirname3(resolvedPath) });
3459
3459
  }
3460
3460
  }
3461
3461
  frontier = nextFrontier;
@@ -4709,11 +4709,11 @@ function isBareModuleSpecifier(moduleSpecifier) {
4709
4709
  return !moduleSpecifier.startsWith(".") && !moduleSpecifier.startsWith("/");
4710
4710
  }
4711
4711
  function findRepoLocalAliasSourceFile(originSourceFile, moduleSpecifier) {
4712
- const resolvedPath2 = resolveRepoLocalAliasImportPath(originSourceFile.getFilePath(), moduleSpecifier);
4713
- if (!resolvedPath2)
4712
+ const resolvedPath = resolveRepoLocalAliasImportPath(originSourceFile.getFilePath(), moduleSpecifier);
4713
+ if (!resolvedPath)
4714
4714
  return void 0;
4715
4715
  const project = originSourceFile.getProject();
4716
- return findProjectSourceFileByImportPath(project, resolvedPath2);
4716
+ return findProjectSourceFileByImportPath(project, resolvedPath);
4717
4717
  }
4718
4718
  function resolveRepoLocalAliasImportPath(importingFilePath, moduleSpecifier) {
4719
4719
  const nearestTsConfigPath = findNearestTsConfigPath(importingFilePath);
@@ -4728,8 +4728,8 @@ function resolveRepoLocalAliasImportPath(importingFilePath, moduleSpecifier) {
4728
4728
  continue;
4729
4729
  for (const targetPattern of targets) {
4730
4730
  const substitutedTarget = substituteTsConfigPathTarget(targetPattern, match2.wildcard);
4731
- const resolvedPath2 = resolve6(tsConfigPaths.baseUrl, substitutedTarget);
4732
- const sourceFilePath = resolveImportSourcePath(resolvedPath2);
4731
+ const resolvedPath = resolve6(tsConfigPaths.baseUrl, substitutedTarget);
4732
+ const sourceFilePath = resolveImportSourcePath(resolvedPath);
4733
4733
  if (sourceFilePath)
4734
4734
  return sourceFilePath;
4735
4735
  }
@@ -4807,17 +4807,17 @@ function resolveImportSourcePath(basePath) {
4807
4807
  ];
4808
4808
  return candidates.find((candidatePath) => existsSync2(candidatePath));
4809
4809
  }
4810
- function findProjectSourceFileByImportPath(project, resolvedPath2) {
4810
+ function findProjectSourceFileByImportPath(project, resolvedPath) {
4811
4811
  const candidatePaths = [
4812
- resolvedPath2,
4813
- `${resolvedPath2}.ts`,
4814
- `${resolvedPath2}.tsx`,
4815
- `${resolvedPath2}.js`,
4816
- `${resolvedPath2}.jsx`,
4817
- join3(resolvedPath2, "index.ts"),
4818
- join3(resolvedPath2, "index.tsx"),
4819
- join3(resolvedPath2, "index.js"),
4820
- join3(resolvedPath2, "index.jsx")
4812
+ resolvedPath,
4813
+ `${resolvedPath}.ts`,
4814
+ `${resolvedPath}.tsx`,
4815
+ `${resolvedPath}.js`,
4816
+ `${resolvedPath}.jsx`,
4817
+ join3(resolvedPath, "index.ts"),
4818
+ join3(resolvedPath, "index.tsx"),
4819
+ join3(resolvedPath, "index.js"),
4820
+ join3(resolvedPath, "index.jsx")
4821
4821
  ];
4822
4822
  for (const candidatePath of candidatePaths) {
4823
4823
  const sourceFile = project.getSourceFile(candidatePath);
@@ -9422,11 +9422,11 @@ function getElementTagNameFromFastDefinition(classDecl, project) {
9422
9422
  }
9423
9423
  function resolveImportSourcePath2(fromFilePath, specifier) {
9424
9424
  if (specifier.startsWith(".")) {
9425
- const resolvedPath2 = resolve9(dirname7(fromFilePath), specifier);
9426
- if (resolvedPath2.endsWith(".js")) {
9427
- return `${resolvedPath2.slice(0, -3)}.ts`;
9425
+ const resolvedPath = resolve9(dirname7(fromFilePath), specifier);
9426
+ if (resolvedPath.endsWith(".js")) {
9427
+ return `${resolvedPath.slice(0, -3)}.ts`;
9428
9428
  }
9429
- return resolvedPath2;
9429
+ return resolvedPath;
9430
9430
  }
9431
9431
  const spectrumPrefix = "@spectrum-web-components/core/components/";
9432
9432
  if (!specifier.startsWith(spectrumPrefix)) {
@@ -20349,15 +20349,15 @@ function PathValidationScreen({
20349
20349
  onChangePath,
20350
20350
  onBack
20351
20351
  }) {
20352
- const resolvedPath2 = useMemo(() => resolveUserPath(projectPath), [projectPath]);
20352
+ const resolvedPath = useMemo(() => resolveUserPath(projectPath), [projectPath]);
20353
20353
  const [scan, setScan] = useState5();
20354
20354
  useEffect3(() => {
20355
- setScan(scanFiles(resolvedPath2));
20356
- }, [resolvedPath2]);
20355
+ setScan(scanFiles(resolvedPath));
20356
+ }, [resolvedPath]);
20357
20357
  const phase = phaseOf(scan);
20358
20358
  usePathValidationControls(phase, {
20359
20359
  onConfirm: () => {
20360
- if (scan?.ok) onConfirm({ projectPath: resolvedPath2, filePaths: scan.filePaths });
20360
+ if (scan?.ok) onConfirm({ projectPath: resolvedPath, filePaths: scan.filePaths });
20361
20361
  },
20362
20362
  onChangePath,
20363
20363
  onBack
@@ -20365,11 +20365,11 @@ function PathValidationScreen({
20365
20365
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
20366
20366
  scan === void 0 && /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
20367
20367
  "Scanning ",
20368
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: resolvedPath2 }),
20368
+ /* @__PURE__ */ jsx6(Text6, { bold: true, children: resolvedPath }),
20369
20369
  "..."
20370
20370
  ] }),
20371
- scan?.ok === false && /* @__PURE__ */ jsx6(Failure, { scan, path: resolvedPath2 }),
20372
- scan?.ok === true && /* @__PURE__ */ jsx6(Summary, { scan, path: resolvedPath2 }),
20371
+ scan?.ok === false && /* @__PURE__ */ jsx6(Failure, { scan, path: resolvedPath }),
20372
+ scan?.ok === true && /* @__PURE__ */ jsx6(Summary, { scan, path: resolvedPath }),
20373
20373
  /* @__PURE__ */ jsx6(Box5, { marginTop: 1, gap: 3, children: controlsFor(phase).map((control) => /* @__PURE__ */ jsxs5(Text6, { dimColor: true, children: [
20374
20374
  "[",
20375
20375
  control.keys,
@@ -33197,9 +33197,33 @@ function nextStepHint(name, status) {
33197
33197
  if (status === "unknown") return "run a full test to confirm it is logged in";
33198
33198
  return "";
33199
33199
  }
33200
- function resolvedPath(checks) {
33201
- const path5 = checks?.find((check) => check.step === "path");
33202
- return path5?.ok ? path5.detail : "";
33200
+ function modelLine(name, savedModel) {
33201
+ const model = savedModel.trim();
33202
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
33203
+ }
33204
+ function panelRows(name, checks, settings) {
33205
+ if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
33206
+ const status = statusFromChecks(name, checks, settings.binary);
33207
+ const path5 = checks.find((check) => check.step === "path");
33208
+ if (!path5?.ok) {
33209
+ const rows2 = [
33210
+ {
33211
+ label: "Command",
33212
+ value: settings.binary.trim() ? path5?.detail ?? "not found" : "not found on your PATH",
33213
+ tone: settings.binary.trim() ? "bad" : "muted"
33214
+ }
33215
+ ];
33216
+ const hint2 = nextStepHint(name, status);
33217
+ if (hint2) rows2.push({ label: "Next", value: hint2, tone: "muted" });
33218
+ return rows2;
33219
+ }
33220
+ const rows = [{ label: "Command", value: path5.detail, tone: "ok" }];
33221
+ const version = checks.find((check) => check.step === "version");
33222
+ if (version?.ok) rows.push({ label: "Version", value: version.detail, tone: "ok" });
33223
+ rows.push({ label: "Model", value: modelLine(name, settings.model), tone: "muted" });
33224
+ const hint = nextStepHint(name, status);
33225
+ if (hint) rows.push({ label: "Next", value: hint, tone: "muted" });
33226
+ return rows;
33203
33227
  }
33204
33228
  function statusRows(_name, checks, savedBinary) {
33205
33229
  if (!checks) return [{ label: "Command", value: "checking...", tone: "muted" }];
@@ -33245,7 +33269,7 @@ async function withBinaryEnv(name, binary, run) {
33245
33269
  else process.env[key] = previous;
33246
33270
  }
33247
33271
  }
33248
- var VERSION_TIMEOUT_MS, PROMPT_TIMEOUT_MS, TEST_PROMPT, INSTALL_HINTS, LOGIN_HINTS, fail3, pass;
33272
+ var VERSION_TIMEOUT_MS, PROMPT_TIMEOUT_MS, TEST_PROMPT, INSTALL_HINTS, LOGIN_HINTS, fail3, pass, LIST_STATUS;
33249
33273
  var init_agent_status = __esm({
33250
33274
  "packages/experience-design-system-cli/src/tui/settings/agents/agent-status.ts"() {
33251
33275
  "use strict";
@@ -33269,17 +33293,50 @@ var init_agent_status = __esm({
33269
33293
  };
33270
33294
  fail3 = (step, detail) => ({ step, ok: false, detail });
33271
33295
  pass = (step, detail) => ({ step, ok: true, detail });
33296
+ LIST_STATUS = {
33297
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
33298
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
33299
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
33300
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
33301
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
33302
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
33303
+ };
33304
+ }
33305
+ });
33306
+
33307
+ // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
33308
+ import { Text as Text46 } from "ink";
33309
+ import { jsx as jsx55 } from "react/jsx-runtime";
33310
+ function AgentStatusBadge({
33311
+ name,
33312
+ checks,
33313
+ binary
33314
+ }) {
33315
+ const { symbol, text, tone } = LIST_STATUS[checks ? statusFromChecks(name, checks, binary) : "checking"];
33316
+ return /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[tone], children: `${symbol} ${text}` });
33317
+ }
33318
+ var TONE_COLOR;
33319
+ var init_AgentStatusBadge = __esm({
33320
+ "packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx"() {
33321
+ "use strict";
33322
+ init_home_theme();
33323
+ init_agent_status();
33324
+ TONE_COLOR = {
33325
+ ok: PALETTE.success,
33326
+ bad: PALETTE.error,
33327
+ muted: PALETTE.muted
33328
+ };
33272
33329
  }
33273
33330
  });
33274
33331
 
33275
33332
  // packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx
33276
33333
  import { useEffect as useEffect22, useState as useState29 } from "react";
33277
- import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
33334
+ import { Box as Box44, Text as Text47, useInput as useInput11 } from "ink";
33278
33335
  import TextInput4 from "ink-text-input";
33279
- import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
33336
+ import { Fragment as Fragment17, jsx as jsx56, jsxs as jsxs45 } from "react/jsx-runtime";
33280
33337
  function Section2({ title, children }) {
33281
33338
  return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", marginTop: 1, children: [
33282
- /* @__PURE__ */ jsx55(Text46, { bold: true, color: PALETTE.muted, children: title }),
33339
+ /* @__PURE__ */ jsx56(Text47, { bold: true, color: PALETTE.muted, children: title }),
33283
33340
  children
33284
33341
  ] });
33285
33342
  }
@@ -33369,52 +33426,52 @@ function AgentDetail({
33369
33426
  });
33370
33427
  const status = checks ? statusFromChecks(name, checks, settings.binary) : "checking";
33371
33428
  const hint = nextStepHint(name, status);
33372
- const pointer = (isFocused) => /* @__PURE__ */ jsx55(Text46, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
33429
+ const pointer = (isFocused) => /* @__PURE__ */ jsx56(Text47, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
33373
33430
  return /* @__PURE__ */ jsxs45(Box44, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33374
- /* @__PURE__ */ jsx55(Text46, { bold: true, children: AGENT_LABELS[name] }),
33375
- /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
33431
+ /* @__PURE__ */ jsx56(Text47, { bold: true, children: AGENT_LABELS[name] }),
33432
+ /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: config.defaultAgent === name ? "This is the default agent." : `Runs the \`${AGENT_HINTS[name]}\` command.` }),
33376
33433
  /* @__PURE__ */ jsxs45(Section2, { title: "STATUS", children: [
33377
33434
  statusRows(name, checks, settings.binary).map((row) => /* @__PURE__ */ jsxs45(Box44, { gap: 1, paddingLeft: 2, children: [
33378
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: row.label }) }),
33379
- /* @__PURE__ */ jsx55(Text46, { color: TONE_COLOR[row.tone], children: row.value })
33435
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: row.label }) }),
33436
+ /* @__PURE__ */ jsx56(Text47, { color: TONE_COLOR[row.tone], children: row.value })
33380
33437
  ] }, row.label)),
33381
- hint && /* @__PURE__ */ jsx55(Box44, { paddingLeft: 2, children: /* @__PURE__ */ jsxs45(Text46, { color: PALETTE.muted, children: [
33438
+ hint && /* @__PURE__ */ jsx56(Box44, { paddingLeft: 2, children: /* @__PURE__ */ jsxs45(Text47, { color: PALETTE.muted, children: [
33382
33439
  "Next: ",
33383
33440
  hint
33384
33441
  ] }) })
33385
33442
  ] }),
33386
- /* @__PURE__ */ jsx55(Section2, { title: "SETTINGS", children: FIELDS2.map((field) => {
33443
+ /* @__PURE__ */ jsx56(Section2, { title: "SETTINGS", children: FIELDS2.map((field) => {
33387
33444
  const isFocused = focused === field;
33388
33445
  const value = settings[field];
33389
33446
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
33390
33447
  pointer(isFocused),
33391
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: FIELD_LABEL[field] }) }),
33392
- isFocused && editing ? /* @__PURE__ */ jsx55(
33448
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: FIELD_LABEL[field] }) }),
33449
+ isFocused && editing ? /* @__PURE__ */ jsx56(
33393
33450
  TextInput4,
33394
33451
  {
33395
33452
  value,
33396
33453
  onChange: (next) => setField(field, next),
33397
33454
  onSubmit: () => setEditing(false)
33398
33455
  }
33399
- ) : /* @__PURE__ */ jsx55(Text46, { bold: true, children: value }),
33400
- !value && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: fieldHint(name, field) })
33456
+ ) : /* @__PURE__ */ jsx56(Text47, { bold: true, children: value }),
33457
+ !value && /* @__PURE__ */ jsx56(Text47, { color: PALETTE.muted, children: fieldHint(name, field) })
33401
33458
  ] }, field);
33402
33459
  }) }),
33403
- /* @__PURE__ */ jsx55(Section2, { title: "ACTIONS", children: /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
33460
+ /* @__PURE__ */ jsx56(Section2, { title: "ACTIONS", children: /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
33404
33461
  pointer(focused === "test"),
33405
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted, children: "Run test" }) }),
33406
- /* @__PURE__ */ jsx55(Text46, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
33462
+ /* @__PURE__ */ jsx56(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx56(Text47, { bold: focused === "test", color: focused === "test" ? PALETTE.accent : PALETTE.muted, children: "Run test" }) }),
33463
+ /* @__PURE__ */ jsx56(Text47, { color: testing ? PALETTE.accent : PALETTE.muted, children: testing ? "running..." : "sends one small prompt (uses a few tokens)" })
33407
33464
  ] }) }),
33408
33465
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
33409
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33410
- /* @__PURE__ */ jsxs45(Text46, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
33466
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
33467
+ /* @__PURE__ */ jsxs45(Text47, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
33411
33468
  notice.kind === "success" ? "\u2713" : "\u2717",
33412
33469
  " ",
33413
33470
  notice.text
33414
33471
  ] })
33415
33472
  ] }),
33416
- /* @__PURE__ */ jsx55(Text46, { children: " " }),
33417
- /* @__PURE__ */ jsx55(
33473
+ /* @__PURE__ */ jsx56(Text47, { children: " " }),
33474
+ /* @__PURE__ */ jsx56(
33418
33475
  ControlHints,
33419
33476
  {
33420
33477
  hints: editing ? [
@@ -33433,7 +33490,7 @@ function AgentDetail({
33433
33490
  )
33434
33491
  ] });
33435
33492
  }
33436
- var FOCUS_ORDER, FIELDS2, FIELD_LABEL, LABEL_WIDTH, TONE_COLOR, fieldHint;
33493
+ var FOCUS_ORDER, FIELDS2, FIELD_LABEL, LABEL_WIDTH, fieldHint;
33437
33494
  var init_AgentDetail = __esm({
33438
33495
  "packages/experience-design-system-cli/src/tui/settings/agents/AgentDetail.tsx"() {
33439
33496
  "use strict";
@@ -33441,56 +33498,16 @@ var init_AgentDetail = __esm({
33441
33498
  init_control_hints();
33442
33499
  init_agent_store();
33443
33500
  init_agent_status();
33501
+ init_AgentStatusBadge();
33444
33502
  init_apply_binary_overrides();
33445
33503
  FOCUS_ORDER = ["binary", "model", "test"];
33446
33504
  FIELDS2 = ["binary", "model"];
33447
33505
  FIELD_LABEL = { binary: "Command path", model: "Model" };
33448
33506
  LABEL_WIDTH = "Command path".length;
33449
- TONE_COLOR = {
33450
- ok: PALETTE.success,
33451
- bad: PALETTE.error,
33452
- muted: PALETTE.muted
33453
- };
33454
33507
  fieldHint = (name, field) => field === "binary" ? `(empty: \`${AGENT_HINTS[name]}\` from the PATH)` : `(empty: ${defaultModelLabel(name)})`;
33455
33508
  }
33456
33509
  });
33457
33510
 
33458
- // packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx
33459
- import { Text as Text47 } from "ink";
33460
- import { jsx as jsx56 } from "react/jsx-runtime";
33461
- function AgentStatusBadge({
33462
- name,
33463
- checks,
33464
- binary
33465
- }) {
33466
- const status = checks ? statusFromChecks(name, checks, binary) : "checking";
33467
- return /* @__PURE__ */ jsx56(Text47, { color: STATUS_COLOR[status], children: STATUS_TEXT[status] });
33468
- }
33469
- var STATUS_TEXT, STATUS_COLOR;
33470
- var init_AgentStatusBadge = __esm({
33471
- "packages/experience-design-system-cli/src/tui/settings/agents/AgentStatusBadge.tsx"() {
33472
- "use strict";
33473
- init_home_theme();
33474
- init_agent_status();
33475
- STATUS_TEXT = {
33476
- checking: "checking...",
33477
- ready: "ready",
33478
- "not-configured": "not configured",
33479
- "not-found": "not found",
33480
- "not-logged-in": "not logged in",
33481
- unknown: "found, login not checked"
33482
- };
33483
- STATUS_COLOR = {
33484
- checking: PALETTE.muted,
33485
- ready: PALETTE.success,
33486
- "not-configured": PALETTE.muted,
33487
- "not-found": PALETTE.error,
33488
- "not-logged-in": PALETTE.error,
33489
- unknown: PALETTE.muted
33490
- };
33491
- }
33492
- });
33493
-
33494
33511
  // packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx
33495
33512
  import { useEffect as useEffect23, useState as useState30 } from "react";
33496
33513
  import { Box as Box45, Text as Text48, useInput as useInput12 } from "ink";
@@ -33532,6 +33549,7 @@ function AgentsScreen({ onDone }) {
33532
33549
  useInput12((input, key) => {
33533
33550
  if (!config || open) return;
33534
33551
  const row = ROWS[focus];
33552
+ if (key.upArrow || key.downArrow || key.tab) setNotice(null);
33535
33553
  if (key.upArrow) {
33536
33554
  setFocus((i) => (i - 1 + ROWS.length) % ROWS.length);
33537
33555
  return;
@@ -33582,29 +33600,46 @@ function AgentsScreen({ onDone }) {
33582
33600
  }
33583
33601
  );
33584
33602
  }
33603
+ const focusedRow = ROWS[focus];
33604
+ const focusedAgent = focusedRow.kind === "agent" ? focusedRow.name : null;
33585
33605
  return /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
33586
33606
  /* @__PURE__ */ jsx57(Text48, { bold: true, children: "Agents" }),
33587
33607
  /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "The coding agent the CLI runs, and what was found for each one." }),
33588
33608
  /* @__PURE__ */ jsx57(Text48, { children: " " }),
33589
- ROWS.map((row, index) => {
33590
- const isFocused = index === focus;
33591
- const pointer = /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " });
33592
- if (row.kind === "default") {
33593
- return /* @__PURE__ */ jsx57(Box45, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
33594
- pointer,
33595
- /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : PALETTE.muted, children: "Default agent" }),
33596
- /* @__PURE__ */ jsx57(Text48, { bold: true, children: `\u2039 ${AGENT_LABELS[config.defaultAgent]} \u203A` })
33597
- ] }) }, "default");
33598
- }
33599
- const saved = config.agents[row.name].binary;
33609
+ /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
33610
+ /* @__PURE__ */ jsx57(Text48, { color: focusedRow.kind === "default" ? PALETTE.accent : void 0, children: focusedRow.kind === "default" ? "\u276F" : " " }),
33611
+ /* @__PURE__ */ jsx57(
33612
+ Text48,
33613
+ {
33614
+ bold: focusedRow.kind === "default",
33615
+ color: focusedRow.kind === "default" ? PALETTE.accent : PALETTE.muted,
33616
+ children: "Default agent"
33617
+ }
33618
+ ),
33619
+ /* @__PURE__ */ jsx57(Text48, { bold: true, children: `\u2039 ${AGENT_LABELS[config.defaultAgent]} \u203A` })
33620
+ ] }),
33621
+ /* @__PURE__ */ jsxs46(Box45, { marginTop: 1, gap: 1, children: [
33622
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33623
+ /* @__PURE__ */ jsx57(Text48, { children: " " }),
33624
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "AGENT" }) }),
33625
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: "STATUS" })
33626
+ ] }),
33627
+ AGENT_NAMES.map((name) => {
33628
+ const isFocused = focusedAgent === name;
33600
33629
  return /* @__PURE__ */ jsxs46(Box45, { gap: 1, children: [
33601
- pointer,
33602
- /* @__PURE__ */ jsx57(Box45, { width: 16, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[row.name] }) }),
33603
- /* @__PURE__ */ jsx57(Box45, { width: 26, flexShrink: 0, children: /* @__PURE__ */ jsx57(AgentStatusBadge, { name: row.name, checks: checks[row.name], binary: saved }) }),
33604
- /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: shortenPath(resolvedPath(checks[row.name]) || saved) }),
33605
- row.name === config.defaultAgent && /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: "(default)" })
33606
- ] }, row.name);
33630
+ /* @__PURE__ */ jsx57(Text48, { color: isFocused ? PALETTE.accent : void 0, children: isFocused ? "\u276F" : " " }),
33631
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.success, children: name === config.defaultAgent ? "\u2605" : " " }),
33632
+ /* @__PURE__ */ jsx57(Box45, { width: NAME_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { bold: isFocused, color: isFocused ? PALETTE.accent : void 0, children: AGENT_LABELS[name] }) }),
33633
+ /* @__PURE__ */ jsx57(AgentStatusBadge, { name, checks: checks[name], binary: config.agents[name].binary })
33634
+ ] }, name);
33607
33635
  }),
33636
+ focusedAgent && /* @__PURE__ */ jsxs46(Box45, { flexDirection: "column", marginTop: 1, children: [
33637
+ /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: `\u2500 ${AGENT_LABELS[focusedAgent]} ${"\u2500".repeat(30)}` }),
33638
+ panelRows(focusedAgent, checks[focusedAgent], config.agents[focusedAgent]).map((row) => /* @__PURE__ */ jsxs46(Box45, { gap: 1, paddingLeft: 1, children: [
33639
+ /* @__PURE__ */ jsx57(Box45, { width: PANEL_LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx57(Text48, { color: PALETTE.muted, children: row.label }) }),
33640
+ /* @__PURE__ */ jsx57(Text48, { color: TONE_COLOR[row.tone], children: row.value })
33641
+ ] }, row.label))
33642
+ ] }),
33608
33643
  notice && /* @__PURE__ */ jsxs46(Fragment18, { children: [
33609
33644
  /* @__PURE__ */ jsx57(Text48, { children: " " }),
33610
33645
  /* @__PURE__ */ jsxs46(Text48, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
@@ -33617,20 +33652,20 @@ function AgentsScreen({ onDone }) {
33617
33652
  /* @__PURE__ */ jsx57(
33618
33653
  ControlHints,
33619
33654
  {
33620
- hints: ROWS[focus].kind === "default" ? [
33655
+ hints: focusedRow.kind === "default" ? [
33621
33656
  { keys: "\u2191/\u2193", label: "move" },
33622
33657
  { keys: "\u2190/\u2192", label: "change default agent" },
33623
33658
  { keys: "Esc/q", label: "back" }
33624
33659
  ] : [
33625
33660
  { keys: "\u2191/\u2193", label: "move" },
33626
- { keys: "\u23CE", label: "open" },
33661
+ { keys: "\u23CE", label: "settings and test" },
33627
33662
  { keys: "Esc/q", label: "back" }
33628
33663
  ]
33629
33664
  }
33630
33665
  )
33631
33666
  ] });
33632
33667
  }
33633
- var ROWS, MAX_PATH_WIDTH, shortenPath;
33668
+ var ROWS, NAME_WIDTH, PANEL_LABEL_WIDTH;
33634
33669
  var init_AgentScreens = __esm({
33635
33670
  "packages/experience-design-system-cli/src/tui/settings/agents/AgentScreens.tsx"() {
33636
33671
  "use strict";
@@ -33643,8 +33678,8 @@ var init_AgentScreens = __esm({
33643
33678
  init_AgentDetail();
33644
33679
  init_AgentStatusBadge();
33645
33680
  ROWS = [{ kind: "default" }, ...AGENT_NAMES.map((name) => ({ kind: "agent", name }))];
33646
- MAX_PATH_WIDTH = 44;
33647
- shortenPath = (path5) => path5.length > MAX_PATH_WIDTH ? `\u2026${path5.slice(-(MAX_PATH_WIDTH - 1))}` : path5;
33681
+ NAME_WIDTH = 16;
33682
+ PANEL_LABEL_WIDTH = "Command".length;
33648
33683
  }
33649
33684
  });
33650
33685
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-0b786a83.0",
3
+ "version": "2.37.1-dev-build-9afe163e.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
2
  /**
3
- * Settings > Configuration > Agents: which coding agent the CLI uses, and what was found for each one. Enter on an agent
4
- * opens its screen; the first row picks the default agent (←/→ or Enter cycles it, and the change is saved at once).
3
+ * Settings > Configuration > Agents. The list holds only what is needed to pick a row: the name, a star on the default,
4
+ * and a one-word status. Below it, a panel shows the full detail for the focused agent and follows the cursor, so nothing
5
+ * has to be opened to read it. Enter opens the agent's own screen, where its path and model are edited and the test is run.
6
+ * The first row picks the default agent (←/→ or Enter cycles it, and the change is saved at once).
5
7
  */
6
8
  export declare function AgentsScreen({ onDone }: {
7
9
  onDone: () => void;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import type { AgentName } from '@contentful/experience-design-system-backend-pipeline';
3
- import { type AgentCheck } from './agent-status.js';
4
- /** The one-word state for an agent, shown on its row in the list. `binary` is the saved path, empty when none is saved. */
3
+ import { type AgentCheck, type StatusRow } from './agent-status.js';
4
+ export declare const TONE_COLOR: Record<StatusRow['tone'], string>;
5
+ /** The symbol and one-word state for an agent, shown on its row in the list. `binary` is the saved path, empty when none is saved. */
5
6
  export declare function AgentStatusBadge({ name, checks, binary, }: {
6
7
  name: AgentName;
7
8
  checks: AgentCheck[] | undefined;
@@ -34,6 +34,28 @@ export type StatusRow = {
34
34
  value: string;
35
35
  tone: 'ok' | 'bad' | 'muted';
36
36
  };
37
+ /**
38
+ * The short form of a status for the list, where every row has to be scannable at a glance. The wording is plainer than
39
+ * the detail panel's: "not installed" covers both "nothing saved" and "saved path broken", which the panel tells apart.
40
+ */
41
+ export declare const LIST_STATUS: Record<AgentStatus, {
42
+ symbol: string;
43
+ text: string;
44
+ tone: StatusRow['tone'];
45
+ }>;
46
+ /**
47
+ * The model line for the detail panel: what is saved, or what the agent really runs with when nothing is. Says which of
48
+ * the two it is, so a user can tell their own choice from the built-in default.
49
+ */
50
+ export declare function modelLine(name: AgentName, savedModel: string): string;
51
+ /**
52
+ * The rows of the detail panel under the list, for the focused agent. Everything here is read-only and comes from
53
+ * checks already collected, so moving the cursor never runs anything.
54
+ */
55
+ export declare function panelRows(name: AgentName, checks: readonly AgentCheck[] | undefined, settings: {
56
+ binary: string;
57
+ model: string;
58
+ }): StatusRow[];
37
59
  /** The resolved path of the command, when the checks found it. For the list, where the user wants to see what runs. */
38
60
  export declare function resolvedPath(checks: readonly AgentCheck[] | undefined): string;
39
61
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-0b786a83.0",
3
+ "version": "2.37.1-dev-build-9afe163e.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-0b786a83.0",
3
+ "version": "2.37.1-dev-build-9afe163e.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,8 +45,8 @@
45
45
  "ts-morph": "^27.0.2",
46
46
  "typescript": "^5.9.3",
47
47
  "zod": "^4.6.5",
48
- "@contentful/experience-design-system-backend-pipeline": "2.37.1-dev-build-0b786a83.0",
49
- "@contentful/experience-design-system-types": "2.37.1-dev-build-0b786a83.0"
48
+ "@contentful/experience-design-system-backend-pipeline": "2.37.1-dev-build-9afe163e.0",
49
+ "@contentful/experience-design-system-types": "2.37.1-dev-build-9afe163e.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@tsconfig/node24": "^24.0.4",