@contentful/experience-design-system-cli 2.43.1-dev-build-044e6594.0 → 2.43.1-dev-build-b2134432.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19592,12 +19592,11 @@ function startDebugRun({
19592
19592
  flow,
19593
19593
  step,
19594
19594
  menuOption,
19595
- inputs
19595
+ inputs = {}
19596
19596
  }) {
19597
- const runId = generateRunId();
19598
19597
  const startedAt = Date.now();
19599
19598
  const redactedInputs = redact(inputs);
19600
- const run = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
19599
+ const run = { flow, step, menuOption, inputs: redactedInputs, startedAt };
19601
19600
  pendingRun = run;
19602
19601
  void isDebugModeEnabled().then((enabled) => {
19603
19602
  if (!enabled && pendingRun === run) pendingRun = void 0;
@@ -19618,11 +19617,7 @@ async function settleDebugLogs() {
19618
19617
  function finishDebugRun(args) {
19619
19618
  return track(finishRun(args));
19620
19619
  }
19621
- async function finishRun({
19622
- outputs,
19623
- status,
19624
- exitMethod
19625
- }) {
19620
+ async function finishRun({ outputs, summary, status, exitMethod }) {
19626
19621
  const run = pendingRun;
19627
19622
  if (!run) return;
19628
19623
  pendingRun = void 0;
@@ -19631,7 +19626,7 @@ async function finishRun({
19631
19626
  const log = {
19632
19627
  folder: logFolder(run.flow, run.step),
19633
19628
  menuOption: run.menuOption,
19634
- content: renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs })
19629
+ content: renderMarkdown(run, { outputs: redact(outputs), summary, status, exitMethod, durationMs })
19635
19630
  };
19636
19631
  const root = currentDebugSessionDir();
19637
19632
  if (!root) {
@@ -19671,22 +19666,26 @@ function nextAttemptFilename(dir, menuOption) {
19671
19666
  return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
19672
19667
  }
19673
19668
  function renderMarkdown(run, finish) {
19674
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
19675
- const stepLabel = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
19676
- const flowSlug = run.flow.split("/").join("-");
19677
- return `# Debug Log
19678
-
19679
- - Run ID: ${run.runId}
19680
- - Flow: ${flowSlug}
19681
- - Step: ${stepLabel}
19682
- - Menu option: ${run.menuOption}
19683
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
19684
- - CLI version: ${readPackageVersion()}
19685
- - Platform: ${process.platform} / Node ${process.version}
19686
- - Duration on screen: ${finish.durationMs}ms
19687
- - Status: ${finish.status}
19688
- - Exit method: ${finish.exitMethod}
19669
+ const stepNumber = /^(\d+)-/.exec(run.step)?.[1];
19670
+ const title = stepNumber ? `${run.menuOption} \xB7 step ${stepNumber}` : run.menuOption;
19671
+ const when = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
19672
+ const header = `# ${title}
19673
+
19674
+ ${when} \xB7 ${finish.durationMs}ms on screen \xB7 ${finish.status} (${finish.exitMethod}) \xB7 CLI ${readPackageVersion()} \xB7 ${process.platform} / Node ${process.version}
19675
+ `;
19676
+ if (finish.summary) {
19677
+ const bullets = finish.summary.map((line) => line.startsWith(" ") ? ` - ${line.trim()}` : `- ${line}`);
19678
+ return `${header}
19679
+ ## Summary (for people)
19680
+ ${bullets.join("\n")}
19689
19681
 
19682
+ ## Data (for AI)
19683
+ \`\`\`json
19684
+ ${JSON.stringify(finish.outputs, null, 2)}
19685
+ \`\`\`
19686
+ `;
19687
+ }
19688
+ return `${header}
19690
19689
  ## Inputs
19691
19690
  \`\`\`json
19692
19691
  ${JSON.stringify(run.inputs, null, 2)}
@@ -19874,6 +19873,330 @@ var init_controls = __esm({
19874
19873
  }
19875
19874
  });
19876
19875
 
19876
+ // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts
19877
+ import { execFile as execFile2 } from "node:child_process";
19878
+ import { access as access5, constants } from "node:fs/promises";
19879
+ function effectiveBinary(name, savedBinary) {
19880
+ return savedBinary.trim() || AGENT_BINARIES[name];
19881
+ }
19882
+ function defaultModelLabel(name) {
19883
+ const model = DEFAULT_MODELS[name];
19884
+ return model && model !== "Auto" ? model : "chosen by the agent";
19885
+ }
19886
+ function resolveOnPath(binary) {
19887
+ if (binary.includes("/")) {
19888
+ return access5(binary, constants.X_OK).then(
19889
+ () => binary,
19890
+ () => null
19891
+ );
19892
+ }
19893
+ return new Promise((resolve29) => {
19894
+ execFile2(
19895
+ process.platform === "win32" ? "where" : "which",
19896
+ [binary],
19897
+ (error, stdout) => resolve29(error ? null : stdout.split("\n")[0]?.trim() ?? null)
19898
+ );
19899
+ });
19900
+ }
19901
+ function readVersion(binary) {
19902
+ return new Promise((resolve29) => {
19903
+ execFile2(binary, ["--version"], { timeout: VERSION_TIMEOUT_MS }, (error, stdout) => {
19904
+ const line = stdout.split("\n")[0]?.trim() ?? "";
19905
+ if (!error && line) resolve29(pass("version", line));
19906
+ else resolve29(fail("version", "runs, but did not report a version"));
19907
+ });
19908
+ });
19909
+ }
19910
+ async function inspect(name, binary) {
19911
+ const target = effectiveBinary(name, binary);
19912
+ const found = await resolveOnPath(target);
19913
+ if (!found) return { checks: [fail("path", `\`${target}\` was not found or is not executable`)], found: null };
19914
+ const checks = [pass("path", found)];
19915
+ checks.push(await readVersion(found));
19916
+ if (name === "claude") {
19917
+ const auth = await withBinaryEnv(name, found, () => checkAgentAuth(name));
19918
+ checks.push(
19919
+ auth === "ok" ? pass("login", "logged in") : fail("login", auth === "not-found" ? "binary not found" : `not logged in: ${LOGIN_HINTS.claude}`)
19920
+ );
19921
+ }
19922
+ return { checks, found };
19923
+ }
19924
+ async function inspectAgent(name, binary) {
19925
+ return (await inspect(name, binary)).checks;
19926
+ }
19927
+ async function testAgent(name, binary, model) {
19928
+ const { checks, found } = await inspect(name, binary);
19929
+ if (!found || !checks.every((check) => check.step === "version" || check.ok)) return checks;
19930
+ const started = Date.now();
19931
+ const result = await withBinaryEnv(
19932
+ name,
19933
+ found,
19934
+ () => createLocalCliAgentInvoker().invoke({
19935
+ agent: name,
19936
+ ...model.trim() ? { model: model.trim() } : {},
19937
+ prompt: TEST_PROMPT,
19938
+ timeoutMs: PROMPT_TIMEOUT_MS
19939
+ })
19940
+ );
19941
+ const seconds2 = ((Date.now() - started) / 1e3).toFixed(1);
19942
+ if (result.timedOut) {
19943
+ return [...checks, { ...fail("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
19944
+ }
19945
+ if (result.exitCode !== 0) {
19946
+ const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
19947
+ return [...checks, fail("prompt", reason)];
19948
+ }
19949
+ return [...checks, pass("prompt", `answered in ${seconds2}s`)];
19950
+ }
19951
+ function statusFromChecks(name, checks, savedBinary) {
19952
+ if (checks.length === 0) return "checking";
19953
+ if (checks.some((check) => check.step === "path" && !check.ok)) {
19954
+ return savedBinary.trim() ? "not-found" : "not-configured";
19955
+ }
19956
+ const prompt = checks.find((check) => check.step === "prompt");
19957
+ if (prompt) {
19958
+ if (prompt.ok) return "ready";
19959
+ return prompt.timedOut ? "timed-out" : "test-failed";
19960
+ }
19961
+ const login = checks.find((check) => check.step === "login");
19962
+ if (login) return login.ok ? "ready" : "not-logged-in";
19963
+ return name === "claude" ? "ready" : "unknown";
19964
+ }
19965
+ function setupHint(name, status) {
19966
+ if (status === "not-configured") return `${INSTALL_HINTS[name]}, or set its command path in settings`;
19967
+ if (status === "not-found") return `${INSTALL_HINTS[name]}, or correct the command path in settings`;
19968
+ if (status === "not-logged-in") return LOGIN_HINTS[name];
19969
+ if (status === "test-failed") return `read the test message; if it is a login problem, ${LOGIN_HINTS[name]}`;
19970
+ if (status === "timed-out") return "it may be slow or waiting for input; run the test again, or try it in a terminal";
19971
+ if (status === "unknown") return "run a full test to confirm it is logged in";
19972
+ return "";
19973
+ }
19974
+ function testOutcome(checks) {
19975
+ const prompt = checks?.find((check) => check.step === "prompt");
19976
+ if (!prompt) return void 0;
19977
+ if (prompt.ok) return { ok: true, text: `Test passed: ${prompt.detail}` };
19978
+ if (prompt.timedOut) return { ok: false, text: `Test timed out: ${prompt.detail}` };
19979
+ return { ok: false, text: `Test failed: ${prompt.detail}` };
19980
+ }
19981
+ function modelLine(name, savedModel) {
19982
+ const model = savedModel.trim();
19983
+ return model ? model : `${defaultModelLabel(name)} (built-in default)`;
19984
+ }
19985
+ function baseRows(name, checks, savedBinary) {
19986
+ const path5 = checks.find((check) => check.step === "path");
19987
+ const version2 = checks.find((check) => check.step === "version");
19988
+ const hint = setupHint(name, statusFromChecks(name, checks, savedBinary));
19989
+ const setup = hint ? { label: "Setup", value: hint, tone: "muted" } : void 0;
19990
+ if (!path5?.ok) {
19991
+ const saved = savedBinary.trim() !== "";
19992
+ const command = {
19993
+ label: "Command",
19994
+ value: saved ? path5?.detail ?? "not found" : "not configured (not on the PATH)",
19995
+ tone: saved ? "bad" : "muted"
19996
+ };
19997
+ return { command, version: void 0, setup, found: false };
19998
+ }
19999
+ return {
20000
+ command: { label: "Command", value: path5.detail, tone: "ok" },
20001
+ version: {
20002
+ label: "Version",
20003
+ value: version2?.ok ? version2.detail : "could not be read",
20004
+ tone: version2?.ok ? "ok" : "muted"
20005
+ },
20006
+ setup,
20007
+ found: true
20008
+ };
20009
+ }
20010
+ function panelRows(name, checks, settings) {
20011
+ if (!checks) return checking;
20012
+ const { command, version: version2, setup, found } = baseRows(name, checks, settings.binary);
20013
+ const model = { label: "Model", value: modelLine(name, settings.model), tone: "muted" };
20014
+ return [command, ...found ? [...version2?.tone === "ok" ? [version2] : [], model] : [], ...setup ? [setup] : []];
20015
+ }
20016
+ function statusRows(name, checks, savedBinary) {
20017
+ if (!checks) return checking;
20018
+ const { command, version: version2, setup, found } = baseRows(name, checks, savedBinary);
20019
+ if (!found) return [command];
20020
+ const login = checks.find((check) => check.step === "login");
20021
+ const prompt = checks.find((check) => check.step === "prompt");
20022
+ let loginRow;
20023
+ if (login) {
20024
+ loginRow = { label: "Login", value: login.detail, tone: login.ok ? "ok" : "bad" };
20025
+ } else if (prompt) {
20026
+ loginRow = {
20027
+ label: "Login",
20028
+ value: prompt.ok ? "confirmed by the test" : prompt.timedOut ? "unknown (the test timed out)" : "see the test result",
20029
+ tone: prompt.ok ? "ok" : prompt.timedOut ? "muted" : "bad"
20030
+ };
20031
+ } else {
20032
+ loginRow = { label: "Login", value: "not checked (use Run test)", tone: "muted" };
20033
+ }
20034
+ const testRow = prompt ? [{ label: "Test", value: prompt.detail, tone: prompt.ok ? "ok" : "bad" }] : [];
20035
+ return [command, ...version2 ? [version2] : [], loginRow, ...testRow, ...setup ? [setup] : []];
20036
+ }
20037
+ async function withBinaryEnv(name, binary, run) {
20038
+ const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
20039
+ const previous = process.env[key];
20040
+ process.env[key] = binary;
20041
+ try {
20042
+ return await run();
20043
+ } finally {
20044
+ if (previous === void 0) delete process.env[key];
20045
+ else process.env[key] = previous;
20046
+ }
20047
+ }
20048
+ var VERSION_TIMEOUT_MS, PROMPT_TIMEOUT_MS, TEST_PROMPT, INSTALL_HINTS, LOGIN_HINTS, fail, pass, LIST_STATUS, checking;
20049
+ var init_agent_status = __esm({
20050
+ "packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts"() {
20051
+ "use strict";
20052
+ init_src3();
20053
+ VERSION_TIMEOUT_MS = 5e3;
20054
+ PROMPT_TIMEOUT_MS = 6e4;
20055
+ TEST_PROMPT = "Reply with the single word: ok";
20056
+ INSTALL_HINTS = {
20057
+ claude: "npm install -g @anthropic-ai/claude-code",
20058
+ codex: "npm install -g @openai/codex",
20059
+ opencode: "npm install -g opencode-ai",
20060
+ cursor: "install Cursor\u2019s `cursor-agent` command",
20061
+ copilot: "npm install -g @github/copilot"
20062
+ };
20063
+ LOGIN_HINTS = {
20064
+ claude: "run `claude login`",
20065
+ codex: "set OPENAI_API_KEY, or sign in with a ChatGPT account",
20066
+ opencode: "run `opencode auth`",
20067
+ cursor: "sign in from Cursor",
20068
+ copilot: "run `copilot` and sign in"
20069
+ };
20070
+ fail = (step, detail) => ({ step, ok: false, detail });
20071
+ pass = (step, detail) => ({ step, ok: true, detail });
20072
+ LIST_STATUS = {
20073
+ checking: { symbol: "\u2026", text: "checking", tone: "muted" },
20074
+ ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
20075
+ "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
20076
+ "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
20077
+ "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
20078
+ "test-failed": { symbol: "\u2717", text: "test failed", tone: "bad" },
20079
+ "timed-out": { symbol: "\u2717", text: "test timed out", tone: "bad" },
20080
+ unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
20081
+ };
20082
+ checking = [{ label: "Command", value: "checking...", tone: "muted" }];
20083
+ }
20084
+ });
20085
+
20086
+ // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-debug.ts
20087
+ function agentSnapshot(config) {
20088
+ const snapshot = { default_agent: config.defaultAgent };
20089
+ for (const name of AGENT_NAMES) {
20090
+ snapshot[`${name}.model`] = config.agents[name].model;
20091
+ snapshot[`${name}.binary`] = config.agents[name].binary;
20092
+ }
20093
+ return snapshot;
20094
+ }
20095
+ function environmentFrom(checks, savedBinary, envValue) {
20096
+ const path5 = checks.find((check) => check.step === "path");
20097
+ const version2 = checks.find((check) => check.step === "version");
20098
+ const overridden = envValue !== void 0 && envValue !== "" && envValue !== savedBinary.trim();
20099
+ return {
20100
+ found: path5?.ok === true,
20101
+ resolved_path: path5?.ok ? path5.detail : "",
20102
+ version: version2?.ok ? version2.detail : "",
20103
+ env_override: overridden ? envValue : ""
20104
+ };
20105
+ }
20106
+ async function describeAgents(config) {
20107
+ const entries = await Promise.all(
20108
+ AGENT_NAMES.map(async (name) => {
20109
+ const saved = config.agents[name].binary;
20110
+ const checks = await inspectAgent(name, saved);
20111
+ return [name, environmentFrom(checks, saved, process.env[`EDS_AGENT_BINARY_${name.toUpperCase()}`])];
20112
+ })
20113
+ );
20114
+ return Object.fromEntries(entries);
20115
+ }
20116
+ async function agentReadiness(config) {
20117
+ const entries = await Promise.all(
20118
+ AGENT_NAMES.map(async (name) => {
20119
+ const saved = config.agents[name].binary;
20120
+ const checks = await inspectAgent(name, saved);
20121
+ const version2 = checks.find((check) => check.step === "version");
20122
+ return [
20123
+ name,
20124
+ { status: statusFromChecks(name, checks, saved), version: version2?.ok ? version2.detail : "" }
20125
+ ];
20126
+ })
20127
+ );
20128
+ return Object.fromEntries(entries);
20129
+ }
20130
+ var init_agent_debug = __esm({
20131
+ "packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-debug.ts"() {
20132
+ "use strict";
20133
+ init_src3();
20134
+ init_agent_status();
20135
+ }
20136
+ });
20137
+
20138
+ // packages/experience-design-system-cli/src/tui/import/steps/00-preflight/log.ts
20139
+ async function collectPreflightContext() {
20140
+ try {
20141
+ const [config, settings] = await Promise.all([readAgentConfig(), readSettings2()]);
20142
+ const baseDir = settings["contentfulBaseDir"];
20143
+ return {
20144
+ settings: {
20145
+ default_agent: config.defaultAgent,
20146
+ base_dir_set: typeof baseDir === "string" && baseDir !== "",
20147
+ analytics: analyticsEnabled()
20148
+ },
20149
+ agents: await agentReadiness(config)
20150
+ };
20151
+ } catch {
20152
+ return void 0;
20153
+ }
20154
+ }
20155
+ function preflightLog(chosen, terminal, context) {
20156
+ const { columns, rows } = terminal;
20157
+ const label = IMPORT_TARGET_OPTIONS.find((option) => option.target === chosen)?.label;
20158
+ const summary = [
20159
+ label ? `Chose: ${label}` : "Left the import without choosing",
20160
+ columns && rows ? `Terminal: ${columns} \xD7 ${rows}` : "Terminal: size unknown"
20161
+ ];
20162
+ if (context) {
20163
+ const { settings, agents } = context;
20164
+ summary.push(
20165
+ "Settings:",
20166
+ ` Default agent: ${AGENT_LABELS[settings.default_agent]}`,
20167
+ ` Base directory: ${settings.base_dir_set ? "set" : "not set"}`,
20168
+ ` Analytics: ${settings.analytics ? "on" : "off"}`,
20169
+ "Agents:",
20170
+ ...AGENT_NAMES.map((name) => ` ${agentLine(name, agents[name])}`)
20171
+ );
20172
+ } else {
20173
+ summary.push("Settings and agents: not collected");
20174
+ }
20175
+ return {
20176
+ summary,
20177
+ data: {
20178
+ chosen,
20179
+ terminal: { columns: columns ?? null, rows: rows ?? null },
20180
+ ...context ? { settings: context.settings, agents: context.agents } : {}
20181
+ }
20182
+ };
20183
+ }
20184
+ function agentLine(name, { status, version: version2 }) {
20185
+ const number = /\d+(?:\.\d+)+/.exec(version2)?.[0];
20186
+ return `${AGENT_LABELS[name]}: ${LIST_STATUS[status].text}${number ? ` (${number})` : ""}`;
20187
+ }
20188
+ var init_log = __esm({
20189
+ "packages/experience-design-system-cli/src/tui/import/steps/00-preflight/log.ts"() {
20190
+ "use strict";
20191
+ init_src3();
20192
+ init_config();
20193
+ init_agent_debug();
20194
+ init_agent_status();
20195
+ init_agent_store();
20196
+ init_logic();
20197
+ }
20198
+ });
20199
+
19877
20200
  // packages/experience-design-system-cli/src/tui/zip.ts
19878
20201
  import { crc32, deflateRawSync } from "node:zlib";
19879
20202
  function dosDateTime(date) {
@@ -20442,32 +20765,30 @@ import { Box as Box9, Text as Text9 } from "ink";
20442
20765
  import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
20443
20766
  function PreflightScreen({ onChoose, onQuit }) {
20444
20767
  const [focus, setFocus] = useState5(0);
20445
- const viewed = useRef([optionAt(0)]).current;
20768
+ const context = useRef(void 0);
20446
20769
  useEffect5(() => {
20447
- startDebugRun({
20448
- flow: "import/preflight",
20449
- step: "00-preflight",
20450
- menuOption: "Preflight",
20451
- inputs: { options: IMPORT_TARGET_OPTIONS.map((option) => option.target), initial_focus: optionAt(0) }
20770
+ startDebugRun({ flow: "import/preflight", step: "00-preflight", menuOption: "Preflight" });
20771
+ void collectPreflightContext().then((collected) => {
20772
+ context.current = collected;
20452
20773
  });
20453
20774
  }, []);
20454
- const moveTo = (next) => {
20455
- setFocus(next);
20456
- if (viewed[viewed.length - 1] !== optionAt(next)) viewed.push(optionAt(next));
20775
+ const finish = (chosen) => {
20776
+ const { summary, data } = preflightLog(
20777
+ chosen,
20778
+ { columns: process.stdout.columns, rows: process.stdout.rows },
20779
+ context.current
20780
+ );
20781
+ void finishDebugRun({ summary, outputs: data, status: "success", exitMethod: chosen ? "saved" : "discarded" });
20457
20782
  };
20458
20783
  const choose = (target) => {
20459
- void finishDebugRun({
20460
- outputs: { chosen: target, viewed, steps_that_will_run: overviewFor(target).map((step) => step.description) },
20461
- status: "success",
20462
- exitMethod: "saved"
20463
- });
20784
+ finish(target);
20464
20785
  onChoose(target);
20465
20786
  };
20466
20787
  const quit = () => {
20467
- void finishDebugRun({ outputs: { chosen: null, viewed }, status: "success", exitMethod: "discarded" });
20788
+ finish(null);
20468
20789
  onQuit();
20469
20790
  };
20470
- usePreflightControls({ focus, onFocus: moveTo, onChoose: choose, onQuit: quit });
20791
+ usePreflightControls({ focus, onFocus: setFocus, onChoose: choose, onQuit: quit });
20471
20792
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
20472
20793
  /* @__PURE__ */ jsx9(StepHeader, { step: "setup" }),
20473
20794
  /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, paddingX: 2, paddingBottom: 1, children: [
@@ -20491,6 +20812,7 @@ var init_screen = __esm({
20491
20812
  init_theme();
20492
20813
  init_debug_store();
20493
20814
  init_controls();
20815
+ init_log();
20494
20816
  init_logic();
20495
20817
  init_shared2();
20496
20818
  init_ControlHints();
@@ -22143,13 +22465,13 @@ async function runExtraction(input, onProgress, deps = realDeps) {
22143
22465
  onProgress(progress);
22144
22466
  const auth = await deps.checkAgentAuth(input.agent);
22145
22467
  if (auth === "not-found" || auth === "unauthenticated") {
22146
- return fail(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
22468
+ return fail2(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
22147
22469
  }
22148
22470
  let selectionPrompt;
22149
22471
  try {
22150
22472
  selectionPrompt = await resolveSelectionPrompt(input.promptOverrides);
22151
22473
  } catch (error) {
22152
- return fail("selection agent", errorMessage2(error));
22474
+ return fail2("selection agent", errorMessage2(error));
22153
22475
  }
22154
22476
  const tokenGeneration = input.rawTokensPath !== "" ? deps.runGenerateTokensSession({
22155
22477
  rawTokensPath: input.rawTokensPath,
@@ -22212,14 +22534,14 @@ async function runExtraction(input, onProgress, deps = realDeps) {
22212
22534
  onSessionCreated: (sessionId) => startSelection(sessionId)
22213
22535
  });
22214
22536
  } catch (error) {
22215
- return fail("analyze extract", errorMessage2(error));
22537
+ return fail2("analyze extract", errorMessage2(error));
22216
22538
  }
22217
22539
  if (selection) await selection;
22218
22540
  if (!selection && entities) await entities;
22219
- if (extracted.components.length === 0) return fail("analyze extract", noComponentsMessage(input.projectPath));
22220
- if (selectionError) return fail("selection agent", errorMessage2(selectionError));
22541
+ if (extracted.components.length === 0) return fail2("analyze extract", noComponentsMessage(input.projectPath));
22542
+ if (selectionError) return fail2("selection agent", errorMessage2(selectionError));
22221
22543
  const tokens = await tokenGeneration;
22222
- if (tokens && !tokens.ok) return fail(tokens.step, tokens.message);
22544
+ if (tokens && !tokens.ok) return fail2(tokens.step, tokens.message);
22223
22545
  const extraction = {
22224
22546
  sessionId: extracted.sessionId,
22225
22547
  outDir,
@@ -22259,7 +22581,7 @@ async function resolveSelectionPrompt(overrides) {
22259
22581
  }
22260
22582
  return {};
22261
22583
  }
22262
- var TOKENS_SKILL_PATH, realDeps, fail, errorMessage2;
22584
+ var TOKENS_SKILL_PATH, realDeps, fail2, errorMessage2;
22263
22585
  var init_run = __esm({
22264
22586
  "packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run.ts"() {
22265
22587
  "use strict";
@@ -22275,7 +22597,7 @@ var init_run = __esm({
22275
22597
  runGenerateTokensSession,
22276
22598
  runSelection
22277
22599
  };
22278
- fail = (step, message) => ({ ok: false, step, message });
22600
+ fail2 = (step, message) => ({ ok: false, step, message });
22279
22601
  errorMessage2 = (error) => error instanceof Error ? error.message : String(error);
22280
22602
  }
22281
22603
  });
@@ -22423,7 +22745,7 @@ function scopeGateLogOutputs(components, decisions) {
22423
22745
  };
22424
22746
  }
22425
22747
  var MAX_NAMES, capped;
22426
- var init_log = __esm({
22748
+ var init_log2 = __esm({
22427
22749
  "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/log.ts"() {
22428
22750
  "use strict";
22429
22751
  MAX_NAMES = 20;
@@ -25322,7 +25644,7 @@ var init_screen8 = __esm({
25322
25644
  "use strict";
25323
25645
  init_debug_store();
25324
25646
  init_StepHeader();
25325
- init_log();
25647
+ init_log2();
25326
25648
  init_tokens_column();
25327
25649
  init_load();
25328
25650
  init_logic10();
@@ -25649,12 +25971,12 @@ async function runGeneration(input, onProgress, deps = realDeps4) {
25649
25971
  try {
25650
25972
  await deps.saveDecisions({ sessionId: input.sessionId, decisions: input.decisions });
25651
25973
  } catch (error) {
25652
- return fail2("save decisions", errorMessage3(error));
25974
+ return fail3("save decisions", errorMessage3(error));
25653
25975
  }
25654
25976
  if (accepted.length === 0) return { ok: true, generation: { route: "push", acceptedCount: 0 } };
25655
25977
  const auth = await deps.checkAgentAuth(input.agent);
25656
25978
  if (auth === "not-found" || auth === "unauthenticated") {
25657
- return fail2(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
25979
+ return fail3(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
25658
25980
  }
25659
25981
  let generated;
25660
25982
  try {
@@ -25670,18 +25992,18 @@ async function runGeneration(input, onProgress, deps = realDeps4) {
25670
25992
  onProgress: (event) => update({ components: applyProgressEvent2(event, progress.components, accepted.length) })
25671
25993
  });
25672
25994
  } catch (error) {
25673
- return fail2("generate components", errorMessage3(error));
25995
+ return fail3("generate components", errorMessage3(error));
25674
25996
  }
25675
- if (generated.emptySession) return fail2("generate components", "no raw components in session");
25997
+ if (generated.emptySession) return fail3("generate components", "no raw components in session");
25676
25998
  if (!generated.allOk) {
25677
25999
  const firstFailure = generated.results.find((r) => r.failed);
25678
- return fail2("generate components", firstFailure?.error ?? "unknown error");
26000
+ return fail3("generate components", firstFailure?.error ?? "unknown error");
25679
26001
  }
25680
26002
  let plan;
25681
26003
  try {
25682
26004
  plan = await deps.prepareMapTokens(input, input.sessionId);
25683
26005
  } catch (error) {
25684
- return fail2("map tokens", errorMessage3(error));
26006
+ return fail3("map tokens", errorMessage3(error));
25685
26007
  }
25686
26008
  update({ mapTokensEligible: plan.eligible });
25687
26009
  if (plan.eligible) {
@@ -25698,7 +26020,7 @@ async function runGeneration(input, onProgress, deps = realDeps4) {
25698
26020
  });
25699
26021
  } catch (error) {
25700
26022
  const message = error instanceof MapTokensRunFailure ? error.message : error instanceof Error ? error.message : String(error);
25701
- return fail2("map tokens", message);
26023
+ return fail3("map tokens", message);
25702
26024
  }
25703
26025
  }
25704
26026
  update({ mapTokens: "complete" });
@@ -25752,7 +26074,7 @@ function applyProgressEvent2(event, previous, total) {
25752
26074
  }
25753
26075
  return previous;
25754
26076
  }
25755
- var COMPONENTS_SKILL_PATH, MAP_TOKENS_SKILL_PATH, realDeps4, fail2, errorMessage3;
26077
+ var COMPONENTS_SKILL_PATH, MAP_TOKENS_SKILL_PATH, realDeps4, fail3, errorMessage3;
25756
26078
  var init_run2 = __esm({
25757
26079
  "packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts"() {
25758
26080
  "use strict";
@@ -25770,7 +26092,7 @@ var init_run2 = __esm({
25770
26092
  runMapTokens,
25771
26093
  prepareMapTokens
25772
26094
  };
25773
- fail2 = (step, message) => ({ ok: false, step, message });
26095
+ fail3 = (step, message) => ({ ok: false, step, message });
25774
26096
  errorMessage3 = (error) => error instanceof Error ? error.message : String(error);
25775
26097
  }
25776
26098
  });
@@ -34567,254 +34889,6 @@ var init_PageContainer3 = __esm({
34567
34889
  }
34568
34890
  });
34569
34891
 
34570
- // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts
34571
- import { execFile as execFile2 } from "node:child_process";
34572
- import { access as access5, constants } from "node:fs/promises";
34573
- function effectiveBinary(name, savedBinary) {
34574
- return savedBinary.trim() || AGENT_BINARIES[name];
34575
- }
34576
- function defaultModelLabel(name) {
34577
- const model = DEFAULT_MODELS[name];
34578
- return model && model !== "Auto" ? model : "chosen by the agent";
34579
- }
34580
- function resolveOnPath(binary) {
34581
- if (binary.includes("/")) {
34582
- return access5(binary, constants.X_OK).then(
34583
- () => binary,
34584
- () => null
34585
- );
34586
- }
34587
- return new Promise((resolve29) => {
34588
- execFile2(
34589
- process.platform === "win32" ? "where" : "which",
34590
- [binary],
34591
- (error, stdout) => resolve29(error ? null : stdout.split("\n")[0]?.trim() ?? null)
34592
- );
34593
- });
34594
- }
34595
- function readVersion(binary) {
34596
- return new Promise((resolve29) => {
34597
- execFile2(binary, ["--version"], { timeout: VERSION_TIMEOUT_MS }, (error, stdout) => {
34598
- const line = stdout.split("\n")[0]?.trim() ?? "";
34599
- if (!error && line) resolve29(pass("version", line));
34600
- else resolve29(fail3("version", "runs, but did not report a version"));
34601
- });
34602
- });
34603
- }
34604
- async function inspect(name, binary) {
34605
- const target = effectiveBinary(name, binary);
34606
- const found = await resolveOnPath(target);
34607
- if (!found) return { checks: [fail3("path", `\`${target}\` was not found or is not executable`)], found: null };
34608
- const checks = [pass("path", found)];
34609
- checks.push(await readVersion(found));
34610
- if (name === "claude") {
34611
- const auth = await withBinaryEnv(name, found, () => checkAgentAuth(name));
34612
- checks.push(
34613
- auth === "ok" ? pass("login", "logged in") : fail3("login", auth === "not-found" ? "binary not found" : `not logged in: ${LOGIN_HINTS.claude}`)
34614
- );
34615
- }
34616
- return { checks, found };
34617
- }
34618
- async function inspectAgent(name, binary) {
34619
- return (await inspect(name, binary)).checks;
34620
- }
34621
- async function testAgent(name, binary, model) {
34622
- const { checks, found } = await inspect(name, binary);
34623
- if (!found || !checks.every((check) => check.step === "version" || check.ok)) return checks;
34624
- const started = Date.now();
34625
- const result = await withBinaryEnv(
34626
- name,
34627
- found,
34628
- () => createLocalCliAgentInvoker().invoke({
34629
- agent: name,
34630
- ...model.trim() ? { model: model.trim() } : {},
34631
- prompt: TEST_PROMPT,
34632
- timeoutMs: PROMPT_TIMEOUT_MS
34633
- })
34634
- );
34635
- const seconds2 = ((Date.now() - started) / 1e3).toFixed(1);
34636
- if (result.timedOut) {
34637
- return [...checks, { ...fail3("prompt", `no answer within ${PROMPT_TIMEOUT_MS / 1e3}s`), timedOut: true }];
34638
- }
34639
- if (result.exitCode !== 0) {
34640
- const reason = result.stderr.trim().split("\n").pop()?.slice(0, 160) || `exited with code ${result.exitCode}`;
34641
- return [...checks, fail3("prompt", reason)];
34642
- }
34643
- return [...checks, pass("prompt", `answered in ${seconds2}s`)];
34644
- }
34645
- function statusFromChecks(name, checks, savedBinary) {
34646
- if (checks.length === 0) return "checking";
34647
- if (checks.some((check) => check.step === "path" && !check.ok)) {
34648
- return savedBinary.trim() ? "not-found" : "not-configured";
34649
- }
34650
- const prompt = checks.find((check) => check.step === "prompt");
34651
- if (prompt) {
34652
- if (prompt.ok) return "ready";
34653
- return prompt.timedOut ? "timed-out" : "test-failed";
34654
- }
34655
- const login = checks.find((check) => check.step === "login");
34656
- if (login) return login.ok ? "ready" : "not-logged-in";
34657
- return name === "claude" ? "ready" : "unknown";
34658
- }
34659
- function setupHint(name, status) {
34660
- if (status === "not-configured") return `${INSTALL_HINTS[name]}, or set its command path in settings`;
34661
- if (status === "not-found") return `${INSTALL_HINTS[name]}, or correct the command path in settings`;
34662
- if (status === "not-logged-in") return LOGIN_HINTS[name];
34663
- if (status === "test-failed") return `read the test message; if it is a login problem, ${LOGIN_HINTS[name]}`;
34664
- if (status === "timed-out") return "it may be slow or waiting for input; run the test again, or try it in a terminal";
34665
- if (status === "unknown") return "run a full test to confirm it is logged in";
34666
- return "";
34667
- }
34668
- function testOutcome(checks) {
34669
- const prompt = checks?.find((check) => check.step === "prompt");
34670
- if (!prompt) return void 0;
34671
- if (prompt.ok) return { ok: true, text: `Test passed: ${prompt.detail}` };
34672
- if (prompt.timedOut) return { ok: false, text: `Test timed out: ${prompt.detail}` };
34673
- return { ok: false, text: `Test failed: ${prompt.detail}` };
34674
- }
34675
- function modelLine(name, savedModel) {
34676
- const model = savedModel.trim();
34677
- return model ? model : `${defaultModelLabel(name)} (built-in default)`;
34678
- }
34679
- function baseRows(name, checks, savedBinary) {
34680
- const path5 = checks.find((check) => check.step === "path");
34681
- const version2 = checks.find((check) => check.step === "version");
34682
- const hint = setupHint(name, statusFromChecks(name, checks, savedBinary));
34683
- const setup = hint ? { label: "Setup", value: hint, tone: "muted" } : void 0;
34684
- if (!path5?.ok) {
34685
- const saved = savedBinary.trim() !== "";
34686
- const command = {
34687
- label: "Command",
34688
- value: saved ? path5?.detail ?? "not found" : "not configured (not on the PATH)",
34689
- tone: saved ? "bad" : "muted"
34690
- };
34691
- return { command, version: void 0, setup, found: false };
34692
- }
34693
- return {
34694
- command: { label: "Command", value: path5.detail, tone: "ok" },
34695
- version: {
34696
- label: "Version",
34697
- value: version2?.ok ? version2.detail : "could not be read",
34698
- tone: version2?.ok ? "ok" : "muted"
34699
- },
34700
- setup,
34701
- found: true
34702
- };
34703
- }
34704
- function panelRows(name, checks, settings) {
34705
- if (!checks) return checking;
34706
- const { command, version: version2, setup, found } = baseRows(name, checks, settings.binary);
34707
- const model = { label: "Model", value: modelLine(name, settings.model), tone: "muted" };
34708
- return [command, ...found ? [...version2?.tone === "ok" ? [version2] : [], model] : [], ...setup ? [setup] : []];
34709
- }
34710
- function statusRows(name, checks, savedBinary) {
34711
- if (!checks) return checking;
34712
- const { command, version: version2, setup, found } = baseRows(name, checks, savedBinary);
34713
- if (!found) return [command];
34714
- const login = checks.find((check) => check.step === "login");
34715
- const prompt = checks.find((check) => check.step === "prompt");
34716
- let loginRow;
34717
- if (login) {
34718
- loginRow = { label: "Login", value: login.detail, tone: login.ok ? "ok" : "bad" };
34719
- } else if (prompt) {
34720
- loginRow = {
34721
- label: "Login",
34722
- value: prompt.ok ? "confirmed by the test" : prompt.timedOut ? "unknown (the test timed out)" : "see the test result",
34723
- tone: prompt.ok ? "ok" : prompt.timedOut ? "muted" : "bad"
34724
- };
34725
- } else {
34726
- loginRow = { label: "Login", value: "not checked (use Run test)", tone: "muted" };
34727
- }
34728
- const testRow = prompt ? [{ label: "Test", value: prompt.detail, tone: prompt.ok ? "ok" : "bad" }] : [];
34729
- return [command, ...version2 ? [version2] : [], loginRow, ...testRow, ...setup ? [setup] : []];
34730
- }
34731
- async function withBinaryEnv(name, binary, run) {
34732
- const key = `EDS_AGENT_BINARY_${name.toUpperCase()}`;
34733
- const previous = process.env[key];
34734
- process.env[key] = binary;
34735
- try {
34736
- return await run();
34737
- } finally {
34738
- if (previous === void 0) delete process.env[key];
34739
- else process.env[key] = previous;
34740
- }
34741
- }
34742
- var VERSION_TIMEOUT_MS, PROMPT_TIMEOUT_MS, TEST_PROMPT, INSTALL_HINTS, LOGIN_HINTS, fail3, pass, LIST_STATUS, checking;
34743
- var init_agent_status = __esm({
34744
- "packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-status.ts"() {
34745
- "use strict";
34746
- init_src3();
34747
- VERSION_TIMEOUT_MS = 5e3;
34748
- PROMPT_TIMEOUT_MS = 6e4;
34749
- TEST_PROMPT = "Reply with the single word: ok";
34750
- INSTALL_HINTS = {
34751
- claude: "npm install -g @anthropic-ai/claude-code",
34752
- codex: "npm install -g @openai/codex",
34753
- opencode: "npm install -g opencode-ai",
34754
- cursor: "install Cursor\u2019s `cursor-agent` command",
34755
- copilot: "npm install -g @github/copilot"
34756
- };
34757
- LOGIN_HINTS = {
34758
- claude: "run `claude login`",
34759
- codex: "set OPENAI_API_KEY, or sign in with a ChatGPT account",
34760
- opencode: "run `opencode auth`",
34761
- cursor: "sign in from Cursor",
34762
- copilot: "run `copilot` and sign in"
34763
- };
34764
- fail3 = (step, detail) => ({ step, ok: false, detail });
34765
- pass = (step, detail) => ({ step, ok: true, detail });
34766
- LIST_STATUS = {
34767
- checking: { symbol: "\u2026", text: "checking", tone: "muted" },
34768
- ready: { symbol: "\u25CF", text: "ready", tone: "ok" },
34769
- "not-configured": { symbol: "\u25CB", text: "not installed", tone: "muted" },
34770
- "not-found": { symbol: "\u25CB", text: "not installed", tone: "bad" },
34771
- "not-logged-in": { symbol: "\u25D0", text: "not logged in", tone: "bad" },
34772
- "test-failed": { symbol: "\u2717", text: "test failed", tone: "bad" },
34773
- "timed-out": { symbol: "\u2717", text: "test timed out", tone: "bad" },
34774
- unknown: { symbol: "\u25D0", text: "installed, login unknown", tone: "muted" }
34775
- };
34776
- checking = [{ label: "Command", value: "checking...", tone: "muted" }];
34777
- }
34778
- });
34779
-
34780
- // packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-debug.ts
34781
- function agentSnapshot(config) {
34782
- const snapshot = { default_agent: config.defaultAgent };
34783
- for (const name of AGENT_NAMES) {
34784
- snapshot[`${name}.model`] = config.agents[name].model;
34785
- snapshot[`${name}.binary`] = config.agents[name].binary;
34786
- }
34787
- return snapshot;
34788
- }
34789
- function environmentFrom(checks, savedBinary, envValue) {
34790
- const path5 = checks.find((check) => check.step === "path");
34791
- const version2 = checks.find((check) => check.step === "version");
34792
- const overridden = envValue !== void 0 && envValue !== "" && envValue !== savedBinary.trim();
34793
- return {
34794
- found: path5?.ok === true,
34795
- resolved_path: path5?.ok ? path5.detail : "",
34796
- version: version2?.ok ? version2.detail : "",
34797
- env_override: overridden ? envValue : ""
34798
- };
34799
- }
34800
- async function describeAgents(config) {
34801
- const entries = await Promise.all(
34802
- AGENT_NAMES.map(async (name) => {
34803
- const saved = config.agents[name].binary;
34804
- const checks = await inspectAgent(name, saved);
34805
- return [name, environmentFrom(checks, saved, process.env[`EDS_AGENT_BINARY_${name.toUpperCase()}`])];
34806
- })
34807
- );
34808
- return Object.fromEntries(entries);
34809
- }
34810
- var init_agent_debug = __esm({
34811
- "packages/experience-design-system-cli/src/tui/settings/configuration/agents/agent-debug.ts"() {
34812
- "use strict";
34813
- init_src3();
34814
- init_agent_status();
34815
- }
34816
- });
34817
-
34818
34892
  // packages/experience-design-system-cli/src/tui/settings/configuration/agents/AgentStatusBadge.tsx
34819
34893
  import { Text as Text49 } from "ink";
34820
34894
  import { jsx as jsx59 } from "react/jsx-runtime";