@contentful/experience-design-system-cli 2.37.1-dev-build-e611e80b.0 → 2.37.1-dev-build-7652d7c0.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
@@ -8,71 +8,6 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // packages/experience-design-system-cli/src/tui/package-root.ts
12
- import { existsSync, readFileSync } from "node:fs";
13
- import { dirname, join } from "node:path";
14
- import { fileURLToPath } from "node:url";
15
- function findPackageRoot(startUrl, packageName) {
16
- let dir = dirname(fileURLToPath(startUrl));
17
- let found;
18
- while (true) {
19
- const manifestPath = join(dir, "package.json");
20
- if (existsSync(manifestPath)) {
21
- const pkg = JSON.parse(readFileSync(manifestPath, "utf8"));
22
- if (pkg.name === packageName) found = dir;
23
- }
24
- const parent = dirname(dir);
25
- if (parent === dir) return found ?? dir;
26
- dir = parent;
27
- }
28
- }
29
- var init_package_root = __esm({
30
- "packages/experience-design-system-cli/src/tui/package-root.ts"() {
31
- "use strict";
32
- }
33
- });
34
-
35
- // packages/experience-design-system-cli/src/tui/upgrade/version.ts
36
- import { readFileSync as readFileSync2 } from "node:fs";
37
- import { join as join2 } from "node:path";
38
- import semver from "semver";
39
- function readPackageVersion() {
40
- const root = findPackageRoot(import.meta.url, PACKAGE_NAME);
41
- const pkg = JSON.parse(readFileSync2(join2(root, "package.json"), "utf8"));
42
- return pkg.version ?? "unknown";
43
- }
44
- function parseVersionTag(tag) {
45
- const match2 = /^v(\d+\.\d+\.\d+)$/.exec(tag);
46
- return match2 ? match2[1] : void 0;
47
- }
48
- async function checkForUpgrade() {
49
- const current = readPackageVersion();
50
- try {
51
- const response = await fetch(TAGS_URL);
52
- if (!response.ok) return { status: "error" };
53
- const tags = await response.json();
54
- const versions = tags.map((tag) => tag.name ? parseVersionTag(tag.name) : void 0).filter((v) => v !== void 0);
55
- if (versions.length === 0) return { status: "error" };
56
- const latest = versions.reduce((best, v) => semver.gt(v, best) ? v : best);
57
- if (!semver.valid(current)) return { status: "error" };
58
- if (semver.gt(latest, current)) {
59
- return { status: "update-available", current, latest };
60
- }
61
- return { status: "up-to-date", current };
62
- } catch {
63
- return { status: "error" };
64
- }
65
- }
66
- var PACKAGE_NAME, TAGS_URL;
67
- var init_version = __esm({
68
- "packages/experience-design-system-cli/src/tui/upgrade/version.ts"() {
69
- "use strict";
70
- init_package_root();
71
- PACKAGE_NAME = "@contentful/experience-design-system-cli";
72
- TAGS_URL = "https://api.github.com/repos/contentful/experience-design-system-sdk-public/tags?per_page=10";
73
- }
74
- });
75
-
76
11
  // packages/experience-design-system-backend-pipeline/dist/src/agents/types/agent-name.js
77
12
  var AGENT_NAMES;
78
13
  var init_agent_name = __esm({
@@ -837,7 +772,7 @@ async function runAgent(options) {
837
772
  promptLen: prompt.length,
838
773
  promptHead: prompt.slice(0, 500)
839
774
  });
840
- return new Promise((resolve27) => {
775
+ return new Promise((resolve25) => {
841
776
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
842
777
  const child = spawn(binary, args, {
843
778
  stdio: ["pipe", "pipe", "pipe"],
@@ -886,7 +821,7 @@ async function runAgent(options) {
886
821
  stderrLen: stderr.length,
887
822
  stderrTail: stderr.slice(-1e3)
888
823
  });
889
- resolve27(result);
824
+ resolve25(result);
890
825
  });
891
826
  });
892
827
  }
@@ -908,7 +843,7 @@ async function checkAgentAuth(agent) {
908
843
  return "not-found";
909
844
  if (agent !== "claude")
910
845
  return "ok";
911
- return new Promise((resolve27) => {
846
+ return new Promise((resolve25) => {
912
847
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
913
848
  let stdout = "";
914
849
  let done = false;
@@ -917,7 +852,7 @@ async function checkAgentAuth(agent) {
917
852
  return;
918
853
  done = true;
919
854
  child.kill("SIGTERM");
920
- resolve27("unauthenticated");
855
+ resolve25("unauthenticated");
921
856
  }, 5e3);
922
857
  child.stdout?.on("data", (chunk) => {
923
858
  stdout += chunk.toString();
@@ -928,14 +863,14 @@ async function checkAgentAuth(agent) {
928
863
  done = true;
929
864
  clearTimeout(timer);
930
865
  if (code !== 0) {
931
- resolve27("unauthenticated");
866
+ resolve25("unauthenticated");
932
867
  return;
933
868
  }
934
869
  try {
935
870
  const status = JSON.parse(stdout);
936
- resolve27(status.loggedIn ? "ok" : "unauthenticated");
871
+ resolve25(status.loggedIn ? "ok" : "unauthenticated");
937
872
  } catch {
938
- resolve27("unauthenticated");
873
+ resolve25("unauthenticated");
939
874
  }
940
875
  });
941
876
  });
@@ -945,9 +880,9 @@ async function binaryIsOnPath(binary) {
945
880
  const fs = await import("node:fs/promises");
946
881
  return fs.access(binary).then(() => true, () => false);
947
882
  }
948
- return new Promise((resolve27) => {
883
+ return new Promise((resolve25) => {
949
884
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
950
- child.on("close", (code) => resolve27(code === 0));
885
+ child.on("close", (code) => resolve25(code === 0));
951
886
  });
952
887
  }
953
888
  var init_check_agent_auth = __esm({
@@ -2081,253 +2016,6 @@ var init_cache_keys = __esm({
2081
2016
  }
2082
2017
  });
2083
2018
 
2084
- // packages/experience-design-system-types/dist/src/config/index.js
2085
- import { randomBytes as randomBytes3 } from "node:crypto";
2086
- import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
2087
- import { homedir as homedir3 } from "node:os";
2088
- import { dirname as dirname13, join as join17 } from "node:path";
2089
- function configRoot2() {
2090
- return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
2091
- }
2092
- async function readSettings2() {
2093
- try {
2094
- return JSON.parse(await readFile18(configFilePath2(), "utf8"));
2095
- } catch {
2096
- return {};
2097
- }
2098
- }
2099
- async function writeSettings2(settings) {
2100
- const path5 = configFilePath2();
2101
- await mkdir6(dirname13(path5), { recursive: true });
2102
- const tmp = `${path5}.${process.pid}.${randomBytes3(4).toString("hex")}.tmp`;
2103
- await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
2104
- `, { mode: 384 });
2105
- await rename2(tmp, path5);
2106
- }
2107
- async function updateSettings2(patch) {
2108
- await writeSettings2({ ...await readSettings2(), ...patch });
2109
- }
2110
- var configFilePath2;
2111
- var init_config = __esm({
2112
- "packages/experience-design-system-types/dist/src/config/index.js"() {
2113
- "use strict";
2114
- configFilePath2 = () => join17(configRoot2(), "config.json");
2115
- }
2116
- });
2117
-
2118
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
2119
- async function readDebugModeSetting() {
2120
- const { debugMode } = await readSettings2();
2121
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
2122
- }
2123
- async function writeDebugModeSetting(setting) {
2124
- await updateSettings2({ debugMode: setting });
2125
- }
2126
- var DEFAULT_DEBUG_MODE_SETTING;
2127
- var init_debug_mode_store = __esm({
2128
- "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
2129
- "use strict";
2130
- init_config();
2131
- DEFAULT_DEBUG_MODE_SETTING = {
2132
- enabled: true
2133
- };
2134
- }
2135
- });
2136
-
2137
- // packages/experience-design-system-cli/src/tui/debug-store.ts
2138
- var debug_store_exports = {};
2139
- __export(debug_store_exports, {
2140
- currentDebugSessionDir: () => currentDebugSessionDir,
2141
- currentSessionDir: () => currentSessionDir,
2142
- finishDebugRun: () => finishDebugRun,
2143
- startDebugRun: () => startDebugRun,
2144
- startDebugSessionIn: () => startDebugSessionIn,
2145
- startImportRun: () => startImportRun
2146
- });
2147
- import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
2148
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
2149
- import { join as join24, resolve as resolve26 } from "node:path";
2150
- function generateRunId() {
2151
- const now = /* @__PURE__ */ new Date();
2152
- const pad = (n) => String(n).padStart(2, "0");
2153
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
2154
- }
2155
- function datePrefix(now = /* @__PURE__ */ new Date()) {
2156
- const pad = (n) => String(n).padStart(2, "0");
2157
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
2158
- }
2159
- function slugify(value) {
2160
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2161
- }
2162
- async function readBaseDir() {
2163
- try {
2164
- const dir = (await readSettings2())["contentfulBaseDir"];
2165
- return typeof dir === "string" && dir !== "" ? resolve26(dir) : void 0;
2166
- } catch {
2167
- return void 0;
2168
- }
2169
- }
2170
- function nextSessionId(contentfulDir) {
2171
- const today = datePrefix();
2172
- const existing = existsSync9(contentfulDir) ? readdirSync4(contentfulDir) : [];
2173
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2174
- const maxSeq = existing.reduce((max, entry) => {
2175
- const match2 = seqPattern.exec(entry);
2176
- return match2 ? Math.max(max, Number(match2[1])) : max;
2177
- }, 0);
2178
- return `${today}-session-${maxSeq + 1}`;
2179
- }
2180
- function startSession(base, { replace }) {
2181
- const contentfulDir = join24(base, ".contentful");
2182
- if (replace || !sessionDir) sessionDir = join24(contentfulDir, nextSessionId(contentfulDir));
2183
- return sessionDir;
2184
- }
2185
- function currentDebugSessionDir() {
2186
- return sessionDir && join24(sessionDir, "debug");
2187
- }
2188
- function currentSessionDir() {
2189
- return sessionDir;
2190
- }
2191
- async function startDebugSessionIn(base, { replace = false } = {}) {
2192
- try {
2193
- if (!await isDebugModeEnabled()) return;
2194
- await mkdir9(join24(startSession(resolve26(base), { replace }), "debug"), { recursive: true });
2195
- } catch {
2196
- }
2197
- }
2198
- function nextImportRunDir(session) {
2199
- const existing = existsSync9(session) ? readdirSync4(session) : [];
2200
- const maxRun = existing.reduce((max, entry) => {
2201
- const match2 = /^dsi-import-(\d+)$/.exec(entry);
2202
- return match2 ? Math.max(max, Number(match2[1])) : max;
2203
- }, 0);
2204
- return join24(session, `dsi-import-${maxRun + 1}`);
2205
- }
2206
- async function startImportRun(projectPath) {
2207
- await startDebugSessionIn(projectPath);
2208
- if (!sessionDir) return join24(resolve26(projectPath), ".contentful");
2209
- const dir = nextImportRunDir(sessionDir);
2210
- await mkdir9(dir, { recursive: true });
2211
- return dir;
2212
- }
2213
- async function isDebugModeEnabled() {
2214
- try {
2215
- return (await readDebugModeSetting()).enabled;
2216
- } catch {
2217
- return true;
2218
- }
2219
- }
2220
- function redact(value) {
2221
- const clone = { ...value };
2222
- if ("cma_token" in clone) {
2223
- const raw = clone.cma_token;
2224
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2225
- }
2226
- return clone;
2227
- }
2228
- function startDebugRun({
2229
- flow,
2230
- step,
2231
- menuOption,
2232
- inputs
2233
- }) {
2234
- const runId = generateRunId();
2235
- const startedAt = Date.now();
2236
- const redactedInputs = redact(inputs);
2237
- isDebugModeEnabled().then((enabled) => {
2238
- if (!enabled) return;
2239
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2240
- });
2241
- }
2242
- async function finishDebugRun({
2243
- outputs,
2244
- status,
2245
- exitMethod
2246
- }) {
2247
- const run = pendingRun;
2248
- if (!run) return;
2249
- pendingRun = void 0;
2250
- const durationMs = Date.now() - run.startedAt;
2251
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2252
- const root = currentDebugSessionDir();
2253
- if (!root) return;
2254
- const flowSegments = run.flow.split("/");
2255
- const dir = join24(root, ...flowSegments);
2256
- await mkdir9(dir, { recursive: true });
2257
- const filename = nextAttemptFilename(dir, run.menuOption);
2258
- await writeFile8(join24(dir, filename), content, { mode: 384 });
2259
- }
2260
- function nextAttemptFilename(dir, menuOption) {
2261
- const today = datePrefix();
2262
- const optionSlug = slugify(menuOption);
2263
- const existing = existsSync9(dir) ? readdirSync4(dir) : [];
2264
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2265
- const maxAttempt = existing.reduce((max, entry) => {
2266
- const match2 = attemptPattern.exec(entry);
2267
- return match2 ? Math.max(max, Number(match2[1])) : max;
2268
- }, 0);
2269
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2270
- }
2271
- function renderMarkdown(run, finish) {
2272
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2273
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2274
- const flowSlug = run.flow.split("/").join("-");
2275
- return `# Debug Log
2276
-
2277
- - Run ID: ${run.runId}
2278
- - Flow: ${flowSlug}
2279
- - Step: ${stepLabel2}
2280
- - Menu option: ${run.menuOption}
2281
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2282
- - CLI version: ${readPackageVersion()}
2283
- - Platform: ${process.platform} / Node ${process.version}
2284
- - Duration on screen: ${finish.durationMs}ms
2285
- - Status: ${finish.status}
2286
- - Exit method: ${finish.exitMethod}
2287
-
2288
- ## Inputs
2289
- \`\`\`json
2290
- ${JSON.stringify(run.inputs, null, 2)}
2291
- \`\`\`
2292
-
2293
- ## Outputs
2294
- \`\`\`json
2295
- ${JSON.stringify(finish.outputs, null, 2)}
2296
- \`\`\`
2297
- `;
2298
- }
2299
- function handleCrash() {
2300
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2301
- }
2302
- var pendingRun, sessionDir;
2303
- var init_debug_store = __esm({
2304
- "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2305
- "use strict";
2306
- init_config();
2307
- init_version();
2308
- init_debug_mode_store();
2309
- void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
2310
- if (!enabled || !base) return void 0;
2311
- return mkdir9(join24(startSession(base, { replace: false }), "debug"), { recursive: true });
2312
- });
2313
- process.once("uncaughtException", (err) => {
2314
- void handleCrash().finally(() => {
2315
- throw err;
2316
- });
2317
- });
2318
- process.once("unhandledRejection", (reason) => {
2319
- void handleCrash().finally(() => {
2320
- throw reason;
2321
- });
2322
- });
2323
- process.once("SIGINT", () => {
2324
- void handleCrash().finally(() => {
2325
- process.exit(130);
2326
- });
2327
- });
2328
- }
2329
- });
2330
-
2331
2019
  // packages/experience-design-system-cli/app.tsx
2332
2020
  import { join as join25 } from "node:path";
2333
2021
  import { useEffect as useEffect26, useState as useState33 } from "react";
@@ -2367,8 +2055,60 @@ function brandBar(width, ramp = BRAND_RAMP) {
2367
2055
  }
2368
2056
  var FOCUS_MARKER = "\u276F";
2369
2057
 
2370
- // packages/experience-design-system-cli/src/tui/home/home.tsx
2371
- init_version();
2058
+ // packages/experience-design-system-cli/src/tui/upgrade/version.ts
2059
+ import { readFileSync as readFileSync2 } from "node:fs";
2060
+ import { join as join2 } from "node:path";
2061
+ import semver from "semver";
2062
+
2063
+ // packages/experience-design-system-cli/src/tui/package-root.ts
2064
+ import { existsSync, readFileSync } from "node:fs";
2065
+ import { dirname, join } from "node:path";
2066
+ import { fileURLToPath } from "node:url";
2067
+ function findPackageRoot(startUrl, packageName) {
2068
+ let dir = dirname(fileURLToPath(startUrl));
2069
+ let found;
2070
+ while (true) {
2071
+ const manifestPath = join(dir, "package.json");
2072
+ if (existsSync(manifestPath)) {
2073
+ const pkg = JSON.parse(readFileSync(manifestPath, "utf8"));
2074
+ if (pkg.name === packageName) found = dir;
2075
+ }
2076
+ const parent = dirname(dir);
2077
+ if (parent === dir) return found ?? dir;
2078
+ dir = parent;
2079
+ }
2080
+ }
2081
+
2082
+ // packages/experience-design-system-cli/src/tui/upgrade/version.ts
2083
+ var PACKAGE_NAME = "@contentful/experience-design-system-cli";
2084
+ var TAGS_URL = "https://api.github.com/repos/contentful/experience-design-system-sdk-public/tags?per_page=10";
2085
+ function readPackageVersion() {
2086
+ const root = findPackageRoot(import.meta.url, PACKAGE_NAME);
2087
+ const pkg = JSON.parse(readFileSync2(join2(root, "package.json"), "utf8"));
2088
+ return pkg.version ?? "unknown";
2089
+ }
2090
+ function parseVersionTag(tag) {
2091
+ const match2 = /^v(\d+\.\d+\.\d+)$/.exec(tag);
2092
+ return match2 ? match2[1] : void 0;
2093
+ }
2094
+ async function checkForUpgrade() {
2095
+ const current = readPackageVersion();
2096
+ try {
2097
+ const response = await fetch(TAGS_URL);
2098
+ if (!response.ok) return { status: "error" };
2099
+ const tags = await response.json();
2100
+ const versions = tags.map((tag) => tag.name ? parseVersionTag(tag.name) : void 0).filter((v) => v !== void 0);
2101
+ if (versions.length === 0) return { status: "error" };
2102
+ const latest = versions.reduce((best, v) => semver.gt(v, best) ? v : best);
2103
+ if (!semver.valid(current)) return { status: "error" };
2104
+ if (semver.gt(latest, current)) {
2105
+ return { status: "update-available", current, latest };
2106
+ }
2107
+ return { status: "up-to-date", current };
2108
+ } catch {
2109
+ return { status: "error" };
2110
+ }
2111
+ }
2372
2112
 
2373
2113
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2374
2114
  import { useEffect, useState } from "react";
@@ -4993,7 +4733,7 @@ async function getCliCacheVersion() {
4993
4733
  return _cliCacheVersionCache;
4994
4734
  }
4995
4735
  }
4996
- function storeExtractCache(db, filePath, fileHash, cliVersion, components) {
4736
+ function storeExtractCache(db, filePath, fileHash, cliVersion2, components) {
4997
4737
  const now = (/* @__PURE__ */ new Date()).toISOString();
4998
4738
  const componentsJson = JSON.stringify(components);
4999
4739
  db.prepare(`INSERT INTO extract_cache (file_path, file_hash, cli_version, created_at, updated_at, components_json)
@@ -5001,12 +4741,12 @@ function storeExtractCache(db, filePath, fileHash, cliVersion, components) {
5001
4741
  ON CONFLICT(file_hash, cli_version) DO UPDATE SET
5002
4742
  file_path = excluded.file_path,
5003
4743
  updated_at = excluded.updated_at,
5004
- components_json = excluded.components_json`).run(filePath, fileHash, cliVersion, now, now, componentsJson);
4744
+ components_json = excluded.components_json`).run(filePath, fileHash, cliVersion2, now, now, componentsJson);
5005
4745
  }
5006
- function lookupExtractCache(db, fileHash, cliVersion) {
4746
+ function lookupExtractCache(db, fileHash, cliVersion2) {
5007
4747
  const row = db.prepare(`SELECT file_path, file_hash, cli_version, created_at, updated_at, components_json
5008
4748
  FROM extract_cache
5009
- WHERE file_hash = ? AND cli_version = ?`).get(fileHash, cliVersion);
4749
+ WHERE file_hash = ? AND cli_version = ?`).get(fileHash, cliVersion2);
5010
4750
  if (!row)
5011
4751
  return null;
5012
4752
  let components = [];
@@ -5024,31 +4764,31 @@ function lookupExtractCache(db, fileHash, cliVersion) {
5024
4764
  components
5025
4765
  };
5026
4766
  }
5027
- function storeCompositionCache(db, inputHash, cliVersion, agentOutput) {
4767
+ function storeCompositionCache(db, inputHash, cliVersion2, agentOutput) {
5028
4768
  const now = (/* @__PURE__ */ new Date()).toISOString();
5029
4769
  db.prepare(`INSERT INTO composition_cache (input_hash, cli_version, agent_output, created_at, updated_at)
5030
4770
  VALUES (?, ?, ?, ?, ?)
5031
4771
  ON CONFLICT(input_hash, cli_version) DO UPDATE SET
5032
4772
  agent_output = excluded.agent_output,
5033
- updated_at = excluded.updated_at`).run(inputHash, cliVersion, agentOutput, now, now);
4773
+ updated_at = excluded.updated_at`).run(inputHash, cliVersion2, agentOutput, now, now);
5034
4774
  }
5035
- function lookupCompositionCache(db, inputHash, cliVersion) {
5036
- const row = db.prepare(`SELECT agent_output FROM composition_cache WHERE input_hash = ? AND cli_version = ?`).get(inputHash, cliVersion);
4775
+ function lookupCompositionCache(db, inputHash, cliVersion2) {
4776
+ const row = db.prepare(`SELECT agent_output FROM composition_cache WHERE input_hash = ? AND cli_version = ?`).get(inputHash, cliVersion2);
5037
4777
  return row ? row.agent_output : null;
5038
4778
  }
5039
- function storeSelectCache(db, componentHash, promptHash, cliVersion, decision, reason) {
4779
+ function storeSelectCache(db, componentHash, promptHash, cliVersion2, decision, reason) {
5040
4780
  const now = (/* @__PURE__ */ new Date()).toISOString();
5041
4781
  db.prepare(`INSERT INTO select_cache (component_hash, prompt_hash, cli_version, decision, reason, created_at, updated_at)
5042
4782
  VALUES (?, ?, ?, ?, ?, ?, ?)
5043
4783
  ON CONFLICT(component_hash, prompt_hash, cli_version) DO UPDATE SET
5044
4784
  decision = excluded.decision,
5045
4785
  reason = excluded.reason,
5046
- updated_at = excluded.updated_at`).run(componentHash, promptHash, cliVersion, decision, reason, now, now);
4786
+ updated_at = excluded.updated_at`).run(componentHash, promptHash, cliVersion2, decision, reason, now, now);
5047
4787
  }
5048
- function lookupSelectCache(db, componentHash, promptHash, cliVersion) {
4788
+ function lookupSelectCache(db, componentHash, promptHash, cliVersion2) {
5049
4789
  const row = db.prepare(`SELECT component_hash, prompt_hash, cli_version, decision, reason, created_at, updated_at
5050
4790
  FROM select_cache
5051
- WHERE component_hash = ? AND prompt_hash = ? AND cli_version = ?`).get(componentHash, promptHash, cliVersion);
4791
+ WHERE component_hash = ? AND prompt_hash = ? AND cli_version = ?`).get(componentHash, promptHash, cliVersion2);
5052
4792
  if (!row)
5053
4793
  return null;
5054
4794
  return {
@@ -12567,11 +12307,11 @@ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node
12567
12307
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
12568
12308
  import { resolve as resolve15 } from "node:path";
12569
12309
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
12570
- const sessionDir2 = resolve15(artifactsRoot, sessionId);
12310
+ const sessionDir = resolve15(artifactsRoot, sessionId);
12571
12311
  return {
12572
- sessionDir: sessionDir2,
12573
- eventsPath: resolve15(sessionDir2, "events.jsonl"),
12574
- statePath: resolve15(sessionDir2, "current-review-state.json")
12312
+ sessionDir,
12313
+ eventsPath: resolve15(sessionDir, "events.jsonl"),
12314
+ statePath: resolve15(sessionDir, "current-review-state.json")
12575
12315
  };
12576
12316
  }
12577
12317
 
@@ -13137,9 +12877,63 @@ async function loadAcceptedNames(sessionId) {
13137
12877
  }
13138
12878
  }
13139
12879
 
13140
- // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/index.js
13141
- import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
13142
-
12880
+ // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/index.js
12881
+ import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
12882
+
12883
+ // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/helpers/generate-session-id.js
12884
+ import { randomBytes as randomBytes3 } from "node:crypto";
12885
+ var ADJECTIVES2 = [
12886
+ "bright",
12887
+ "calm",
12888
+ "dark",
12889
+ "fast",
12890
+ "green",
12891
+ "happy",
12892
+ "keen",
12893
+ "light",
12894
+ "long",
12895
+ "loud",
12896
+ "pale",
12897
+ "quick",
12898
+ "sharp",
12899
+ "slow",
12900
+ "soft",
12901
+ "warm",
12902
+ "wild",
12903
+ "wise"
12904
+ ];
12905
+ var NOUNS2 = [
12906
+ "cloud",
12907
+ "creek",
12908
+ "dawn",
12909
+ "dusk",
12910
+ "field",
12911
+ "flame",
12912
+ "frost",
12913
+ "grove",
12914
+ "hill",
12915
+ "lake",
12916
+ "leaf",
12917
+ "moon",
12918
+ "peak",
12919
+ "rain",
12920
+ "river",
12921
+ "rock",
12922
+ "snow",
12923
+ "star",
12924
+ "storm",
12925
+ "tide",
12926
+ "tree",
12927
+ "wave",
12928
+ "wind"
12929
+ ];
12930
+ function generateSessionId2() {
12931
+ const adj = ADJECTIVES2[Math.floor(Math.random() * ADJECTIVES2.length)];
12932
+ const noun = NOUNS2[Math.floor(Math.random() * NOUNS2.length)];
12933
+ const hex = randomBytes3(2).toString("hex");
12934
+ return `${adj}-${noun}-${hex}`;
12935
+ }
12936
+
13143
12937
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/migration.js
13144
12938
  import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
13145
12939
 
@@ -13770,7 +13564,7 @@ function errorMessage(error) {
13770
13564
  return error instanceof Error && error.message ? error.message : String(error);
13771
13565
  }
13772
13566
  function defaultSleep(delayMs) {
13773
- return new Promise((resolve27) => setTimeout(resolve27, delayMs));
13567
+ return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13774
13568
  }
13775
13569
 
13776
13570
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -14011,7 +13805,7 @@ var ApiClient = class {
14011
13805
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
14012
13806
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
14013
13807
  const jitter = Math.random() * baseDelay * 0.15;
14014
- await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
13808
+ await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
14015
13809
  }
14016
13810
  }
14017
13811
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -14945,6 +14739,172 @@ function loadTokenLeaves(db, sessionId) {
14945
14739
  return db.prepare("SELECT path, type FROM raw_tokens WHERE session_id = ? ORDER BY path").all(sessionId);
14946
14740
  }
14947
14741
 
14742
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/client/cli-info.js
14743
+ var cliVersionString = "0.0.0-unknown";
14744
+ function cliVersion() {
14745
+ return cliVersionString;
14746
+ }
14747
+
14748
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/client/opt-out.js
14749
+ var persistedDisabled = false;
14750
+ function analyticsEnabled() {
14751
+ return !persistedDisabled && !process.env["DISABLE_ANALYTICS"];
14752
+ }
14753
+
14754
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/client/segment-client.js
14755
+ import { Analytics } from "@segment/analytics-node";
14756
+ var DEFAULT_WRITE_KEY = "6DmxiEPN3SV1vbRTTMcNqDzCvkfwT06N";
14757
+ var analyticsClient = null;
14758
+ function resolveWriteKey() {
14759
+ const key = (process.env["SEGMENT_WRITE_KEY"] ?? "").trim();
14760
+ return key.length > 0 ? key : DEFAULT_WRITE_KEY;
14761
+ }
14762
+ function getClient() {
14763
+ if (!analyticsEnabled())
14764
+ return null;
14765
+ const writeKey = resolveWriteKey();
14766
+ if (!writeKey)
14767
+ return null;
14768
+ if (!analyticsClient) {
14769
+ analyticsClient = new Analytics({ writeKey });
14770
+ analyticsClient.on("error", () => {
14771
+ });
14772
+ }
14773
+ return analyticsClient;
14774
+ }
14775
+ async function trackEvent(event, properties, anonymousId, options) {
14776
+ const client2 = getClient();
14777
+ if (!client2)
14778
+ return;
14779
+ try {
14780
+ client2.track({
14781
+ event,
14782
+ properties,
14783
+ anonymousId,
14784
+ timestamp: /* @__PURE__ */ new Date()
14785
+ });
14786
+ if (options?.flush)
14787
+ await flushAnalytics();
14788
+ } catch {
14789
+ }
14790
+ }
14791
+ async function flushAnalytics() {
14792
+ if (!analyticsClient)
14793
+ return;
14794
+ try {
14795
+ await analyticsClient.closeAndFlush();
14796
+ } catch {
14797
+ } finally {
14798
+ analyticsClient = null;
14799
+ }
14800
+ }
14801
+
14802
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/constants.js
14803
+ var ANALYTICS_SESSION_ENV = "EDS_ANALYTICS_SESSION_ID";
14804
+ var IMPORT_PIPELINE_ENV = "EDS_IMPORT_PIPELINE";
14805
+
14806
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/session.js
14807
+ function resolveAnalyticsSessionId(explicit) {
14808
+ const inherited = process.env[ANALYTICS_SESSION_ENV]?.trim();
14809
+ if (inherited)
14810
+ return inherited;
14811
+ const passed = explicit?.trim();
14812
+ if (passed)
14813
+ return passed;
14814
+ return generateSessionId2();
14815
+ }
14816
+ function isPipelineAnalyticsChild() {
14817
+ return Boolean(process.env[ANALYTICS_SESSION_ENV]?.trim());
14818
+ }
14819
+
14820
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/tracker/pending-command.js
14821
+ var state = {
14822
+ pending: null,
14823
+ sessionId: void 0,
14824
+ sessionStartedEmitted: false
14825
+ };
14826
+ function isPipelineStep() {
14827
+ return process.env[IMPORT_PIPELINE_ENV] === "1";
14828
+ }
14829
+ function buildBaseProps(command) {
14830
+ return {
14831
+ dsi_session_id: state.sessionId,
14832
+ command,
14833
+ ...isPipelineStep() ? { is_pipeline_step: true } : {}
14834
+ };
14835
+ }
14836
+ function mergeContext(target, source) {
14837
+ if (source.space_key !== void 0)
14838
+ target.space_key = source.space_key;
14839
+ if (source.environment_key !== void 0)
14840
+ target.environment_key = source.environment_key;
14841
+ if (source.x_contentful_request_id !== void 0) {
14842
+ target.x_contentful_request_id = source.x_contentful_request_id;
14843
+ }
14844
+ }
14845
+ function setCommandContext(context) {
14846
+ if (!state.pending)
14847
+ return;
14848
+ mergeContext(state.pending.context, context);
14849
+ mergeContext(state.pending.completion, context);
14850
+ }
14851
+ function enrichCommandResult(fields) {
14852
+ if (!state.pending)
14853
+ return;
14854
+ Object.assign(state.pending.completion, fields);
14855
+ mergeContext(state.pending.context, fields);
14856
+ }
14857
+
14858
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/os.js
14859
+ var OS_NAMES2 = {
14860
+ android: "Android",
14861
+ aix: "Linux",
14862
+ darwin: "macOS",
14863
+ freebsd: "Linux",
14864
+ linux: "Linux",
14865
+ openbsd: "Linux",
14866
+ sunos: "Linux",
14867
+ win32: "Windows"
14868
+ };
14869
+ function getOsName() {
14870
+ return OS_NAMES2[process.platform] ?? "other";
14871
+ }
14872
+
14873
+ // packages/experience-design-system-backend-pipeline/dist/src/analytics/tracker/emit-events.js
14874
+ async function bindAnalyticsSessionId(explicit, context) {
14875
+ const id = resolveAnalyticsSessionId(explicit);
14876
+ await bindAnalyticsSession(id, context);
14877
+ return id;
14878
+ }
14879
+ async function bindAnalyticsSession(id, context) {
14880
+ state.sessionId = id;
14881
+ if (context)
14882
+ setCommandContext(context);
14883
+ await emitInvokedIfReady();
14884
+ }
14885
+ async function emitSessionStarted(entryCommand) {
14886
+ if (!state.sessionId || state.sessionStartedEmitted)
14887
+ return;
14888
+ state.sessionStartedEmitted = true;
14889
+ await trackEvent("dsi_cli_session_started", {
14890
+ dsi_session_id: state.sessionId,
14891
+ entry_command: entryCommand,
14892
+ cli_version: cliVersion(),
14893
+ node_version: process.version,
14894
+ os_name: getOsName()
14895
+ }, state.sessionId, { flush: true });
14896
+ await emitInvokedIfReady();
14897
+ }
14898
+ async function emitInvokedIfReady() {
14899
+ if (!state.pending || state.pending.invoked || !state.sessionId)
14900
+ return;
14901
+ state.pending.invoked = true;
14902
+ await trackEvent("dsi_cli_command_invoked", {
14903
+ ...buildBaseProps(state.pending.command),
14904
+ ...state.pending.context
14905
+ }, state.sessionId, { flush: true });
14906
+ }
14907
+
14948
14908
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/map-tokens/run-map-tokens.js
14949
14909
  var DEFAULT_TIMEOUT_MS2 = 5 * 60 * 1e3;
14950
14910
  var MapTokensRunFailure = class _MapTokensRunFailure extends Error {
@@ -14974,23 +14934,34 @@ async function runMapTokens(request) {
14974
14934
  if (!sessionId) {
14975
14935
  throw new MapTokensRunFailure({ type: "no-session" });
14976
14936
  }
14937
+ await bindAnalyticsSessionId(sessionId);
14977
14938
  const tokenLeaves = loadTokenLeaves(db, sessionId);
14978
14939
  const knownTokenPaths = new Set(tokenLeaves.map((t) => t.path));
14940
+ const diagnostics = [];
14979
14941
  if (request.tokenMapInline) {
14980
14942
  const validMappings = {};
14981
14943
  for (const [rawName, path5] of Object.entries(request.tokenMapInline)) {
14982
- if (knownTokenPaths.has(path5))
14944
+ if (knownTokenPaths.has(path5)) {
14983
14945
  validMappings[rawName] = path5;
14946
+ } else {
14947
+ diagnostics.push(`Token map '${rawName}' -> '${path5}': path not found in session tokens \u2014 skipped.`);
14948
+ }
14984
14949
  }
14985
14950
  replaceRawTokenNamePaths(db, sessionId, validMappings, "manual");
14986
14951
  }
14987
14952
  const rawDefaults = loadRawDefaults(db, sessionId);
14988
14953
  const defaultResolution = resolveTokenDefaults(rawDefaults.map((row) => ({ rawDefault: row.default_reference, tokenKind: row.cdf_token_kind })), tokenLeaves);
14954
+ for (const diagnostic of defaultResolution.diagnostics)
14955
+ diagnostics.push(diagnostic.message);
14989
14956
  const manualMappings = new Map(getRawTokenNamePathRows(db, sessionId).filter((row) => row.source === "manual").map((row) => [row.rawName, row.path]));
14990
14957
  const automaticMappings = {};
14991
14958
  for (const [rawName, path5] of Object.entries(defaultResolution.mappings)) {
14992
- if (manualMappings.get(rawName) === void 0)
14959
+ const manualPath = manualMappings.get(rawName);
14960
+ if (manualPath === void 0) {
14993
14961
  automaticMappings[rawName] = path5;
14962
+ } else if (manualPath !== path5) {
14963
+ diagnostics.push(`Token default '${rawName}' automatically resolves to '${path5}', but manual mapping '${manualPath}' is retained.`);
14964
+ }
14994
14965
  }
14995
14966
  replaceRawTokenNamePaths(db, sessionId, automaticMappings, "automatic");
14996
14967
  const cdfEntries = loadCDFComponents(db, sessionId);
@@ -15001,7 +14972,7 @@ async function runMapTokens(request) {
15001
14972
  const { groups, tokens } = getDtcgTokensForSession(db, sessionId);
15002
14973
  const tokenCount = tokens.length;
15003
14974
  if (mappablePropCount === 0 || tokenCount === 0) {
15004
- return { type: "nothing-to-map", sessionId, mappablePropCount, tokenCount };
14975
+ return { type: "nothing-to-map", sessionId, mappablePropCount, tokenCount, diagnostics };
15005
14976
  }
15006
14977
  const generatedCdf = Object.fromEntries(cdfEntries.map((c2) => [c2.key, c2.entry]));
15007
14978
  const tokenTree = rebuildDTCGTree(groups, tokens);
@@ -15019,7 +14990,7 @@ async function runMapTokens(request) {
15019
14990
  });
15020
14991
  if (request.printPrompt) {
15021
14992
  const prompt2 = await buildMapPrompt();
15022
- return { type: "printed-prompt", sessionId, prompt: prompt2 };
14993
+ return { type: "printed-prompt", sessionId, prompt: prompt2, diagnostics };
15023
14994
  }
15024
14995
  if (request.skipAgent) {
15025
14996
  const stepId2 = createStep(db, sessionId, "map tokens", {
@@ -15028,7 +14999,7 @@ async function runMapTokens(request) {
15028
14999
  skipAgent: "true"
15029
15000
  });
15030
15001
  updateStep(db, stepId2, "complete", { applied: "0", skipAgent: "true" });
15031
- return { type: "skipped", sessionId, stepId: stepId2 };
15002
+ return { type: "skipped", sessionId, stepId: stepId2, diagnostics };
15032
15003
  }
15033
15004
  const agent = request.agent;
15034
15005
  const noCache = request.cache === false || process.env["EDS_NO_CACHE"] === "1";
@@ -15040,7 +15011,7 @@ async function runMapTokens(request) {
15040
15011
  const applied2 = copyMapTokensFromCache(db, cached.sourceSessionId, sessionId);
15041
15012
  const stepId2 = createStep(db, sessionId, "map tokens", { agent, model: request.model ?? "" });
15042
15013
  updateStep(db, stepId2, "complete", { cached: "true", applied: String(applied2) });
15043
- return { type: "cached", sessionId, applied: applied2, stepId: stepId2 };
15014
+ return { type: "cached", sessionId, applied: applied2, stepId: stepId2, diagnostics };
15044
15015
  }
15045
15016
  }
15046
15017
  const binary = resolveBinary(agent);
@@ -15067,7 +15038,7 @@ async function runMapTokens(request) {
15067
15038
  storeCache(db, inputHash, "token_mapping", "__map_tokens__", sessionId, false, promptHash);
15068
15039
  }
15069
15040
  updateStep(db, stepId, "complete", { applied: String(applied), warnings: String(warnings.length) });
15070
- return { type: "applied", sessionId, applied, warnings, stepId };
15041
+ return { type: "applied", sessionId, applied, warnings, stepId, diagnostics };
15071
15042
  } finally {
15072
15043
  db.close();
15073
15044
  }
@@ -16124,7 +16095,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
16124
16095
  const message = error instanceof Error ? error.message : String(error);
16125
16096
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
16126
16097
  throw error;
16127
- await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
16098
+ await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16128
16099
  }
16129
16100
  }
16130
16101
  }
@@ -16287,6 +16258,9 @@ async function runExtractAndComposeSession(request) {
16287
16258
  outDir
16288
16259
  });
16289
16260
  await onSessionCreated?.(sessionId);
16261
+ await bindAnalyticsSessionId(sessionId);
16262
+ if (!isPipelineAnalyticsChild())
16263
+ await emitSessionStarted("analyze_extract");
16290
16264
  const stepId = createStep(db, sessionId, "analyze extract", { project: projectPath });
16291
16265
  if (cacheHits === 0 && !noCache) {
16292
16266
  await persistExtractCache(db, sourceFiles, extraction.components, cacheVersion);
@@ -16314,6 +16288,7 @@ async function runExtractAndComposeSession(request) {
16314
16288
  await persistSlotCycles(db, sessionId, composition.components);
16315
16289
  storeScannedFiles(db, sessionId, sourceFiles.map((f) => relative2(projectPath, f)));
16316
16290
  await retryDatabaseWrite(() => updateStep(db, stepId, "complete", { sessionId }));
16291
+ enrichCommandResult({ extracted_component_count: composition.components.length });
16317
16292
  return {
16318
16293
  sessionId,
16319
16294
  compositionPhase: composition.phase,
@@ -16376,6 +16351,7 @@ async function runGenerateTokensSession(request) {
16376
16351
  outDir
16377
16352
  });
16378
16353
  await onSessionCreated?.(tokenSessionId);
16354
+ await bindAnalyticsSessionId(tokenSessionId);
16379
16355
  const tokenPromptHash = await hashPromptForSkill("tokens", agent, agentModel, skillPath);
16380
16356
  const warnings = [];
16381
16357
  onProgress?.({ kind: "resolving" });
@@ -16752,6 +16728,7 @@ async function runGenerateComponentsSession(request) {
16752
16728
  const existingTokensHash = existingTokensInline ? [hashContent(existingTokensInline)] : [];
16753
16729
  const agent = request.agent;
16754
16730
  const promptHash = await hashPromptForSkill("components", agent, request.agentModel, effectiveSkillPath, existingTokensHash, prompt.text);
16731
+ await bindAnalyticsSessionId(request.sessionId);
16755
16732
  const db = openPipelineDb();
16756
16733
  try {
16757
16734
  const acceptedNames = await loadAcceptedNames(request.sessionId);
@@ -16951,7 +16928,6 @@ function useCredentialsControls(handlers) {
16951
16928
  }
16952
16929
 
16953
16930
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16954
- init_version();
16955
16931
  function cliUserAgent() {
16956
16932
  return buildUserAgent(readPackageVersion());
16957
16933
  }
@@ -17296,34 +17272,11 @@ function RunningStep({
17296
17272
  }
17297
17273
 
17298
17274
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-reuse/logic.ts
17299
- import { access as access5, readdir as readdir2, stat as stat4 } from "node:fs/promises";
17275
+ import { access as access5, stat as stat4 } from "node:fs/promises";
17300
17276
  import { join as join16 } from "node:path";
17301
- async function findLatestTokens(contentfulDir) {
17302
- const candidates = [join16(contentfulDir, "tokens.json")];
17303
- try {
17304
- for (const session of await readdir2(contentfulDir, { withFileTypes: true })) {
17305
- if (!session.isDirectory()) continue;
17306
- for (const run of await readdir2(join16(contentfulDir, session.name), { withFileTypes: true }).catch(() => [])) {
17307
- if (run.isDirectory() && /^dsi-import-\d+$/.test(run.name)) {
17308
- candidates.push(join16(contentfulDir, session.name, run.name, "tokens.json"));
17309
- }
17310
- }
17311
- }
17312
- } catch {
17313
- }
17314
- const found = [];
17315
- for (const path5 of candidates) {
17316
- try {
17317
- found.push({ path: path5, mtimeMs: (await stat4(path5)).mtimeMs });
17318
- } catch {
17319
- }
17320
- }
17321
- return found.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.path ?? null;
17322
- }
17323
- async function inspectTokens({ rawTokensPath, contentfulDir, cache }) {
17277
+ async function inspectTokens({ rawTokensPath, outDir, cache }) {
17324
17278
  if (!cache) return { kind: "none" };
17325
- const tokensPath = await findLatestTokens(contentfulDir);
17326
- if (!tokensPath) return { kind: "none" };
17279
+ const tokensPath = join16(outDir, "tokens.json");
17327
17280
  try {
17328
17281
  await access5(tokensPath);
17329
17282
  } catch {
@@ -17474,8 +17427,34 @@ function ExtractionScreen({
17474
17427
  );
17475
17428
  }
17476
17429
 
17477
- // packages/experience-design-system-cli/app.tsx
17478
- init_config();
17430
+ // packages/experience-design-system-types/dist/src/config/index.js
17431
+ import { randomBytes as randomBytes4 } from "node:crypto";
17432
+ import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
17433
+ import { homedir as homedir3 } from "node:os";
17434
+ import { dirname as dirname13, join as join17 } from "node:path";
17435
+ function configRoot2() {
17436
+ return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
17437
+ }
17438
+ var configFilePath2 = () => join17(configRoot2(), "config.json");
17439
+ var debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
17440
+ async function readSettings2() {
17441
+ try {
17442
+ return JSON.parse(await readFile18(configFilePath2(), "utf8"));
17443
+ } catch {
17444
+ return {};
17445
+ }
17446
+ }
17447
+ async function writeSettings2(settings) {
17448
+ const path5 = configFilePath2();
17449
+ await mkdir6(dirname13(path5), { recursive: true });
17450
+ const tmp = `${path5}.${process.pid}.${randomBytes4(4).toString("hex")}.tmp`;
17451
+ await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
17452
+ `, { mode: 384 });
17453
+ await rename2(tmp, path5);
17454
+ }
17455
+ async function updateSettings2(patch) {
17456
+ await writeSettings2({ ...await readSettings2(), ...patch });
17457
+ }
17479
17458
 
17480
17459
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17481
17460
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
@@ -17514,13 +17493,13 @@ async function runSelection(options) {
17514
17493
  const db = openPipelineDb();
17515
17494
  let components;
17516
17495
  const cachedDecisions = /* @__PURE__ */ new Map();
17517
- const cliVersion = await getCliCacheVersion();
17496
+ const cliVersion2 = await getCliCacheVersion();
17518
17497
  const promptHash = await hashSelectPrompt(options);
17519
17498
  try {
17520
17499
  components = loadRawComponents(db, options.sessionId);
17521
17500
  if (!options.noCache) {
17522
17501
  for (const component of components) {
17523
- const cached = lookupSelectCache(db, hashComponentShape(component), promptHash, cliVersion);
17502
+ const cached = lookupSelectCache(db, hashComponentShape(component), promptHash, cliVersion2);
17524
17503
  if (cached) cachedDecisions.set(component.name, { decision: cached.decision, reason: cached.reason });
17525
17504
  }
17526
17505
  }
@@ -17575,7 +17554,7 @@ async function runSelection(options) {
17575
17554
  writeDb,
17576
17555
  hashComponentShape(component),
17577
17556
  promptHash,
17578
- cliVersion,
17557
+ cliVersion2,
17579
17558
  rejected ? "rejected" : "accepted",
17580
17559
  rejected ? reason : null
17581
17560
  );
@@ -17602,7 +17581,7 @@ var realDeps = {
17602
17581
  var fail = (step, message) => ({ ok: false, step, message });
17603
17582
  var errorMessage2 = (error) => error instanceof Error ? error.message : String(error);
17604
17583
  async function runExtraction(input, onProgress, deps = realDeps) {
17605
- const outDir = input.outDir ?? join19(resolve22(input.projectPath), ".contentful");
17584
+ const outDir = join19(resolve22(input.projectPath), ".contentful");
17606
17585
  let progress = initialProgress({
17607
17586
  hasCredentials: input.credentials !== null,
17608
17587
  hasRawTokens: input.rawTokensPath !== "",
@@ -17735,7 +17714,7 @@ async function resolveSelectionPrompt(overrides) {
17735
17714
 
17736
17715
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17737
17716
  function useExtraction(input) {
17738
- const [state, setState] = useState8();
17717
+ const [state2, setState] = useState8();
17739
17718
  const current = useRef2();
17740
17719
  useEffect5(() => {
17741
17720
  current.current = input;
@@ -17760,7 +17739,7 @@ function useExtraction(input) {
17760
17739
  if (current.current === input) current.current = void 0;
17761
17740
  };
17762
17741
  }, [input]);
17763
- return state;
17742
+ return state2;
17764
17743
  }
17765
17744
 
17766
17745
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/screen.tsx
@@ -19851,62 +19830,62 @@ function buildFlatDimPredicate(input) {
19851
19830
  }
19852
19831
 
19853
19832
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/state.ts
19854
- function apply(state, entries) {
19855
- const next = new Map(state);
19833
+ function apply(state2, entries) {
19834
+ const next = new Map(state2);
19856
19835
  for (const [name, decision] of entries) next.set(name, decision);
19857
19836
  return next;
19858
19837
  }
19859
- function reduceDecisions(state, action, components, graph) {
19838
+ function reduceDecisions(state2, action, components, graph) {
19860
19839
  switch (action.type) {
19861
19840
  case "accept": {
19862
- if (state.get(action.name) === "accepted") return state;
19841
+ if (state2.get(action.name) === "accepted") return state2;
19863
19842
  return apply(
19864
- state,
19843
+ state2,
19865
19844
  acceptCascade(graph, action.name).map((name) => [name, "accepted"])
19866
19845
  );
19867
19846
  }
19868
19847
  case "reject": {
19869
- if (state.get(action.name) === "rejected") return state;
19848
+ if (state2.get(action.name) === "rejected") return state2;
19870
19849
  const { toReject, toDeselect } = rejectCascade(graph, action.name);
19871
- return apply(state, [
19850
+ return apply(state2, [
19872
19851
  ...toReject.map((name) => [name, "rejected"]),
19873
19852
  ...toDeselect.map((name) => [name, "undecided"])
19874
19853
  ]);
19875
19854
  }
19876
19855
  case "toggle-all": {
19877
19856
  const nonCycle = components.filter((c2) => !graph.cycleParticipants.has(c2.name)).map((c2) => c2.name);
19878
- const anyNotAccepted = nonCycle.some((name) => state.get(name) !== "accepted");
19857
+ const anyNotAccepted = nonCycle.some((name) => state2.get(name) !== "accepted");
19879
19858
  if (anyNotAccepted) {
19880
- return apply(state, [
19859
+ return apply(state2, [
19881
19860
  ...nonCycle.map((name) => [name, "accepted"]),
19882
19861
  ...reachableCycleMembers(graph, nonCycle).map((name) => [name, "accepted"])
19883
19862
  ]);
19884
19863
  }
19885
- return apply(state, [
19864
+ return apply(state2, [
19886
19865
  ...nonCycle.map((name) => [name, "rejected"]),
19887
- ...components.filter((c2) => graph.cycleParticipants.has(c2.name) && state.get(c2.name) === "accepted").map((c2) => [c2.name, "undecided"])
19866
+ ...components.filter((c2) => graph.cycleParticipants.has(c2.name) && state2.get(c2.name) === "accepted").map((c2) => [c2.name, "undecided"])
19888
19867
  ]);
19889
19868
  }
19890
19869
  case "accept-unflagged": {
19891
19870
  const seeds = components.filter((c2) => !graph.cycleParticipants.has(c2.name) && !isAiFlagged(c2)).map((c2) => c2.name);
19892
- return apply(state, [
19871
+ return apply(state2, [
19893
19872
  ...seeds.map((name) => [name, "accepted"]),
19894
19873
  ...reachableCycleMembers(graph, seeds).map((name) => [name, "accepted"])
19895
19874
  ]);
19896
19875
  }
19897
19876
  }
19898
19877
  }
19899
- function rejectNeedsConfirmation(graph, name, state) {
19900
- if (state.get(name) === "rejected") return false;
19878
+ function rejectNeedsConfirmation(graph, name, state2) {
19879
+ if (state2.get(name) === "rejected") return false;
19901
19880
  const { toReject, toDeselect } = rejectCascade(graph, name);
19902
19881
  const ancestors = toReject.filter((n) => n !== name);
19903
19882
  return ancestors.length + toDeselect.length >= 2;
19904
19883
  }
19905
- function partitionDecisions(components, state) {
19884
+ function partitionDecisions(components, state2) {
19906
19885
  const accepted = [];
19907
19886
  const rejected = [];
19908
19887
  for (const c2 of components) {
19909
- if (state.get(c2.name) === "accepted") accepted.push(c2.name);
19888
+ if (state2.get(c2.name) === "accepted") accepted.push(c2.name);
19910
19889
  else rejected.push(c2.name);
19911
19890
  }
19912
19891
  return { accepted, rejected };
@@ -20737,7 +20716,7 @@ async function runGeneration(input, onProgress, deps = realDeps3) {
20737
20716
  update({ mapTokens: "running" });
20738
20717
  try {
20739
20718
  const mapTokensOptions = await buildMapTokensOptions(input);
20740
- await deps.runMapTokens({
20719
+ const mapResult = await deps.runMapTokens({
20741
20720
  sessionId: input.sessionId,
20742
20721
  agent: input.agent,
20743
20722
  ...input.agentModel ? { model: input.agentModel } : {},
@@ -20745,6 +20724,11 @@ async function runGeneration(input, onProgress, deps = realDeps3) {
20745
20724
  skillPathOverride: MAP_TOKENS_SKILL_PATH,
20746
20725
  ...mapTokensOptions
20747
20726
  });
20727
+ if (mapResult.diagnostics.length > 0) {
20728
+ process.stderr.write(`Unresolved token defaults:
20729
+ ${mapResult.diagnostics.map((d) => ` ${d}`).join("\n")}
20730
+ `);
20731
+ }
20748
20732
  } catch (error) {
20749
20733
  const message = error instanceof MapTokensRunFailure ? error.message : error instanceof Error ? error.message : String(error);
20750
20734
  return fail2("map tokens", message);
@@ -20798,7 +20782,7 @@ function applyProgressEvent2(event, previous, total) {
20798
20782
 
20799
20783
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts
20800
20784
  function useGeneration(input) {
20801
- const [state, setState] = useState14();
20785
+ const [state2, setState] = useState14();
20802
20786
  const current = useRef6();
20803
20787
  useEffect9(() => {
20804
20788
  current.current = input;
@@ -20816,7 +20800,7 @@ function useGeneration(input) {
20816
20800
  if (current.current === input) current.current = void 0;
20817
20801
  };
20818
20802
  }, [input]);
20819
- return state;
20803
+ return state2;
20820
20804
  }
20821
20805
 
20822
20806
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
@@ -21581,7 +21565,7 @@ function parseToState(json) {
21581
21565
  });
21582
21566
  return { state: { componentDescription, props, slots }, error: null };
21583
21567
  }
21584
- function serializeState(state, originalJson) {
21568
+ function serializeState(state2, originalJson) {
21585
21569
  let wrapperKey = null;
21586
21570
  try {
21587
21571
  const orig = JSON.parse(originalJson);
@@ -21595,7 +21579,7 @@ function serializeState(state, originalJson) {
21595
21579
  } catch {
21596
21580
  }
21597
21581
  const $properties = {};
21598
- for (const p of state.props) {
21582
+ for (const p of state2.props) {
21599
21583
  const def = {
21600
21584
  $type: p.type,
21601
21585
  $category: p.category
@@ -21618,10 +21602,10 @@ function serializeState(state, originalJson) {
21618
21602
  $type: "component",
21619
21603
  $properties
21620
21604
  };
21621
- if (state.componentDescription) entry.$description = state.componentDescription;
21622
- if (state.slots.length > 0) {
21605
+ if (state2.componentDescription) entry.$description = state2.componentDescription;
21606
+ if (state2.slots.length > 0) {
21623
21607
  entry.$slots = {};
21624
- for (const s of state.slots) {
21608
+ for (const s of state2.slots) {
21625
21609
  const slotDef = {};
21626
21610
  if (s.description) slotDef.$description = s.description;
21627
21611
  if (s.required) slotDef.$required = true;
@@ -24711,71 +24695,71 @@ function ReviewReloadDialog({ open }) {
24711
24695
 
24712
24696
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/review-input.ts
24713
24697
  var PANEL_CONTENT_HEIGHT = 12;
24714
- function handleReviewOverlayInput(input, key, state) {
24715
- if (state.loading) return true;
24716
- if (state.loadError) {
24717
- if (input === "q" || key.escape || key.return) state.onQuit();
24698
+ function handleReviewOverlayInput(input, key, state2) {
24699
+ if (state2.loading) return true;
24700
+ if (state2.loadError) {
24701
+ if (input === "q" || key.escape || key.return) state2.onQuit();
24718
24702
  return true;
24719
24703
  }
24720
- if (state.showFinalize) {
24704
+ if (state2.showFinalize) {
24721
24705
  if (key.downArrow) {
24722
- state.finalizePreview.scrollBy(1);
24706
+ state2.finalizePreview.scrollBy(1);
24723
24707
  return true;
24724
24708
  }
24725
24709
  if (key.upArrow) {
24726
- state.finalizePreview.scrollBy(-1);
24710
+ state2.finalizePreview.scrollBy(-1);
24727
24711
  return true;
24728
24712
  }
24729
24713
  return true;
24730
24714
  }
24731
- if (state.dialogOpen || state.showHelp) return true;
24732
- if (state.showReloadDialog) {
24715
+ if (state2.dialogOpen || state2.showHelp) return true;
24716
+ if (state2.showReloadDialog) {
24733
24717
  if (key.return) {
24734
- state.reloadFromSave();
24735
- state.setShowReloadDialog(false);
24718
+ state2.reloadFromSave();
24719
+ state2.setShowReloadDialog(false);
24736
24720
  return true;
24737
24721
  }
24738
24722
  if (key.escape) {
24739
- state.setShowReloadDialog(false);
24723
+ state2.setShowReloadDialog(false);
24740
24724
  return true;
24741
24725
  }
24742
24726
  return true;
24743
24727
  }
24744
24728
  if (key.ctrl && input === "z") {
24745
- state.handleUndo();
24729
+ state2.handleUndo();
24746
24730
  return true;
24747
24731
  }
24748
24732
  if (key.ctrl && input === "y") {
24749
- state.handleRedo();
24733
+ state2.handleRedo();
24750
24734
  return true;
24751
24735
  }
24752
24736
  if (key.ctrl && input === "r") {
24753
- state.setShowReloadDialog(true);
24737
+ state2.setShowReloadDialog(true);
24754
24738
  return true;
24755
24739
  }
24756
24740
  return false;
24757
24741
  }
24758
- function handleTokenReviewInput(input, key, state) {
24759
- if (state.panelOpen !== "token-review") return false;
24760
- const suggestions = state.currentTokenSuggestions();
24761
- const row = suggestions[state.tokenReviewRow];
24762
- if (state.tokenReviewEditing) {
24742
+ function handleTokenReviewInput(input, key, state2) {
24743
+ if (state2.panelOpen !== "token-review") return false;
24744
+ const suggestions = state2.currentTokenSuggestions();
24745
+ const row = suggestions[state2.tokenReviewRow];
24746
+ if (state2.tokenReviewEditing) {
24763
24747
  if (key.ctrl && input === "s" && row) {
24764
- state.handleTokenEditSave(row);
24748
+ state2.handleTokenEditSave(row);
24765
24749
  return true;
24766
24750
  }
24767
24751
  if (row && row.paths.length > 0) {
24768
24752
  if (key.upArrow || input === "k") {
24769
- state.setTokenReviewEditCursor((cursor) => Math.max(0, cursor - 1));
24753
+ state2.setTokenReviewEditCursor((cursor) => Math.max(0, cursor - 1));
24770
24754
  return true;
24771
24755
  }
24772
24756
  if (key.downArrow || input === "j") {
24773
- state.setTokenReviewEditCursor((cursor) => Math.min(row.paths.length - 1, cursor + 1));
24757
+ state2.setTokenReviewEditCursor((cursor) => Math.min(row.paths.length - 1, cursor + 1));
24774
24758
  return true;
24775
24759
  }
24776
24760
  if (input === " " || key.return) {
24777
- const path5 = row.paths[state.tokenReviewEditCursor];
24778
- state.setTokenReviewEditSelection((previous) => {
24761
+ const path5 = row.paths[state2.tokenReviewEditCursor];
24762
+ state2.setTokenReviewEditSelection((previous) => {
24779
24763
  const next = new Set(previous);
24780
24764
  if (next.has(path5) && next.size === 1) return next;
24781
24765
  if (next.has(path5)) next.delete(path5);
@@ -24786,34 +24770,34 @@ function handleTokenReviewInput(input, key, state) {
24786
24770
  }
24787
24771
  }
24788
24772
  if (key.escape) {
24789
- state.setTokenReviewEditing(false);
24773
+ state2.setTokenReviewEditing(false);
24790
24774
  return true;
24791
24775
  }
24792
24776
  return true;
24793
24777
  }
24794
24778
  if (key.upArrow || input === "k") {
24795
- state.setTokenReviewRow((rowIndex) => Math.max(0, rowIndex - 1));
24779
+ state2.setTokenReviewRow((rowIndex) => Math.max(0, rowIndex - 1));
24796
24780
  return true;
24797
24781
  }
24798
24782
  if (key.downArrow || input === "j") {
24799
- state.setTokenReviewRow((rowIndex) => Math.min(Math.max(0, suggestions.length - 1), rowIndex + 1));
24783
+ state2.setTokenReviewRow((rowIndex) => Math.min(Math.max(0, suggestions.length - 1), rowIndex + 1));
24800
24784
  return true;
24801
24785
  }
24802
24786
  if (key.return && row) {
24803
- state.setTokenReviewEditCursor(0);
24804
- state.setTokenReviewEditSelection(new Set(row.allowed));
24805
- state.setTokenReviewEditing(true);
24787
+ state2.setTokenReviewEditCursor(0);
24788
+ state2.setTokenReviewEditSelection(new Set(row.allowed));
24789
+ state2.setTokenReviewEditing(true);
24806
24790
  return true;
24807
24791
  }
24808
24792
  if (key.escape || input === "t") {
24809
- state.setPanelOpen("none");
24793
+ state2.setPanelOpen("none");
24810
24794
  return true;
24811
24795
  }
24812
24796
  return true;
24813
24797
  }
24814
- function setReviewPanel(state, panel) {
24815
- state.setPanelOpen(panel);
24816
- state.setPanelScrollOffset(() => 0);
24798
+ function setReviewPanel(state2, panel) {
24799
+ state2.setPanelOpen(panel);
24800
+ state2.setPanelScrollOffset(() => 0);
24817
24801
  }
24818
24802
  function rationalePanelForInput(input, propKey, componentKey) {
24819
24803
  if (input === propKey) return "prop-rationale";
@@ -24821,70 +24805,70 @@ function rationalePanelForInput(input, propKey, componentKey) {
24821
24805
  if (input === "s") return "source";
24822
24806
  return null;
24823
24807
  }
24824
- function handleRationalePanelInput(input, key, state) {
24825
- if (state.panelOpen === "none" || state.panelOpen === "token-review") return false;
24826
- const next = computeNextScrollOffset(state.panelScrollOffset, input, key, 9999, PANEL_CONTENT_HEIGHT);
24808
+ function handleRationalePanelInput(input, key, state2) {
24809
+ if (state2.panelOpen === "none" || state2.panelOpen === "token-review") return false;
24810
+ const next = computeNextScrollOffset(state2.panelScrollOffset, input, key, 9999, PANEL_CONTENT_HEIGHT);
24827
24811
  if (next !== null) {
24828
- state.setPanelScrollOffset(() => next);
24812
+ state2.setPanelScrollOffset(() => next);
24829
24813
  return true;
24830
24814
  }
24831
24815
  if (key.escape) {
24832
- setReviewPanel(state, "none");
24816
+ setReviewPanel(state2, "none");
24833
24817
  return true;
24834
24818
  }
24835
24819
  const togglable = !key.ctrl && !key.tab && !key.meta && !key.return;
24836
24820
  if (!togglable) return true;
24837
- const panel = rationalePanelForInput(input, state.propKey, state.componentKey);
24838
- if (panel) setReviewPanel(state, state.panelOpen === panel ? "none" : panel);
24821
+ const panel = rationalePanelForInput(input, state2.propKey, state2.componentKey);
24822
+ if (panel) setReviewPanel(state2, state2.panelOpen === panel ? "none" : panel);
24839
24823
  return true;
24840
24824
  }
24841
- function handleReviewPanelShortcuts(input, key, state) {
24842
- if (handleTokenReviewInput(input, key, state)) return true;
24843
- if (handleRationalePanelInput(input, key, state)) return true;
24844
- const rationaleKeyOk = !state.textEntryActive && !state.showJson && !key.ctrl && !key.tab && !key.meta && !key.return;
24825
+ function handleReviewPanelShortcuts(input, key, state2) {
24826
+ if (handleTokenReviewInput(input, key, state2)) return true;
24827
+ if (handleRationalePanelInput(input, key, state2)) return true;
24828
+ const rationaleKeyOk = !state2.textEntryActive && !state2.showJson && !key.ctrl && !key.tab && !key.meta && !key.return;
24845
24829
  if (!rationaleKeyOk) return false;
24846
- const panel = rationalePanelForInput(input, state.propKey, state.componentKey);
24830
+ const panel = rationalePanelForInput(input, state2.propKey, state2.componentKey);
24847
24831
  if (panel) {
24848
- setReviewPanel(state, panel);
24832
+ setReviewPanel(state2, panel);
24849
24833
  return true;
24850
24834
  }
24851
- if (input === "t" && state.currentTokenSuggestions().length > 0) {
24852
- state.setPanelOpen("token-review");
24853
- state.setTokenReviewRow(0);
24835
+ if (input === "t" && state2.currentTokenSuggestions().length > 0) {
24836
+ state2.setPanelOpen("token-review");
24837
+ state2.setTokenReviewRow(0);
24854
24838
  return true;
24855
24839
  }
24856
24840
  return false;
24857
24841
  }
24858
- function handleReviewViewToggleInput(input, state) {
24842
+ function handleReviewViewToggleInput(input, state2) {
24859
24843
  if (input === "J") {
24860
- state.setShowJson((previous) => !previous);
24861
- state.setJsonScrollOffset(0);
24862
- state.pendingGRef.current = false;
24844
+ state2.setShowJson((previous) => !previous);
24845
+ state2.setJsonScrollOffset(0);
24846
+ state2.pendingGRef.current = false;
24863
24847
  return true;
24864
24848
  }
24865
24849
  return false;
24866
24850
  }
24867
- function handleJsonPanelInput(input, key, state) {
24868
- if (state.sidebarFocused || !state.showJson) return false;
24869
- const totalLines = state.jsonValue.split("\n").length;
24870
- const maxOffset = Math.max(0, totalLines - state.height);
24851
+ function handleJsonPanelInput(input, key, state2) {
24852
+ if (state2.sidebarFocused || !state2.showJson) return false;
24853
+ const totalLines = state2.jsonValue.split("\n").length;
24854
+ const maxOffset = Math.max(0, totalLines - state2.height);
24871
24855
  if (input === "g" && !key.ctrl) {
24872
- if (state.pendingGRef.current) {
24873
- state.pendingGRef.current = false;
24874
- state.setJsonScrollOffset(() => 0);
24856
+ if (state2.pendingGRef.current) {
24857
+ state2.pendingGRef.current = false;
24858
+ state2.setJsonScrollOffset(() => 0);
24875
24859
  return true;
24876
24860
  }
24877
- state.pendingGRef.current = true;
24861
+ state2.pendingGRef.current = true;
24878
24862
  return true;
24879
24863
  }
24880
- const next = computeNextScrollOffset(state.jsonScrollOffset, input, key, totalLines, state.height);
24864
+ const next = computeNextScrollOffset(state2.jsonScrollOffset, input, key, totalLines, state2.height);
24881
24865
  if (next !== null) {
24882
- state.pendingGRef.current = false;
24866
+ state2.pendingGRef.current = false;
24883
24867
  const clamped = Math.min(maxOffset, Math.max(0, next));
24884
- state.setJsonScrollOffset(() => clamped);
24868
+ state2.setJsonScrollOffset(() => clamped);
24885
24869
  return true;
24886
24870
  }
24887
- state.pendingGRef.current = false;
24871
+ state2.pendingGRef.current = false;
24888
24872
  return true;
24889
24873
  }
24890
24874
 
@@ -27233,38 +27217,38 @@ function buildRunTeaserLine(runId) {
27233
27217
 
27234
27218
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/screen.tsx
27235
27219
  import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
27236
- function totalStepsFor(state) {
27237
- const hasTokenStage = !!state.tokensPath || !!state.rawTokensPath;
27238
- return 3 + (hasTokenStage ? 1 : 0) + 2 + (state.mapTokensEligible === true ? 1 : 0);
27220
+ function totalStepsFor(state2) {
27221
+ const hasTokenStage = !!state2.tokensPath || !!state2.rawTokensPath;
27222
+ return 3 + (hasTokenStage ? 1 : 0) + 2 + (state2.mapTokensEligible === true ? 1 : 0);
27239
27223
  }
27240
27224
  function canEditFromPreview(cdf) {
27241
27225
  if (!cdf) return false;
27242
27226
  return parseCDFComponents(cdf).components.length > 0;
27243
27227
  }
27244
27228
  function FlowScreen({
27245
- state,
27229
+ state: state2,
27246
27230
  controller,
27247
27231
  livePreview = true,
27248
27232
  generatePromptPath,
27249
27233
  onExit
27250
27234
  }) {
27251
- const totalSteps = totalStepsFor(state);
27235
+ const totalSteps = totalStepsFor(state2);
27252
27236
  const quit = () => onExit(0);
27253
27237
  const content = (() => {
27254
- switch (state.step) {
27238
+ switch (state2.step) {
27255
27239
  case "final-review":
27256
27240
  return /* @__PURE__ */ jsx52(
27257
27241
  GenerateReviewStep,
27258
27242
  {
27259
- extractSessionId: state.extractSessionId,
27260
- tokenSessionId: state.tokenSessionId,
27243
+ extractSessionId: state2.extractSessionId,
27244
+ tokenSessionId: state2.tokenSessionId,
27261
27245
  livePreview,
27262
- spaceId: state.spaceId,
27263
- environmentId: state.environmentId,
27264
- cmaToken: state.cmaToken,
27265
- host: state.host,
27266
- tokensPath: state.tokensPath,
27267
- initialFinalizeError: state.finalizeErrorBanner,
27246
+ spaceId: state2.spaceId,
27247
+ environmentId: state2.environmentId,
27248
+ cmaToken: state2.cmaToken,
27249
+ host: state2.host,
27250
+ tokensPath: state2.tokensPath,
27251
+ initialFinalizeError: state2.finalizeErrorBanner,
27268
27252
  onFinalize: controller.finalize,
27269
27253
  onQuit: quit
27270
27254
  }
@@ -27280,27 +27264,27 @@ function FlowScreen({
27280
27264
  }
27281
27265
  );
27282
27266
  case "preview-gate":
27283
- if (!state.serverPreview) return null;
27267
+ if (!state2.serverPreview) return null;
27284
27268
  return /* @__PURE__ */ jsx52(
27285
27269
  WizardPreviewStep,
27286
27270
  {
27287
- preview: state.serverPreview,
27288
- spaceId: state.spaceId,
27289
- environmentId: state.environmentId,
27271
+ preview: state2.serverPreview,
27272
+ spaceId: state2.spaceId,
27273
+ environmentId: state2.environmentId,
27290
27274
  stepNumber: totalSteps,
27291
27275
  totalSteps,
27292
27276
  onConfirm: controller.confirmPreview,
27293
- ...canEditFromPreview(state.cdf) ? { onEdit: controller.editDefinitions } : {},
27277
+ ...canEditFromPreview(state2.cdf) ? { onEdit: controller.editDefinitions } : {},
27294
27278
  onQuit: quit
27295
27279
  }
27296
27280
  );
27297
27281
  case "pushing":
27298
- return /* @__PURE__ */ jsx52(PushingStep, { stepNumber: totalSteps, totalSteps, progress: state.pushProgress });
27282
+ return /* @__PURE__ */ jsx52(PushingStep, { stepNumber: totalSteps, totalSteps, progress: state2.pushProgress });
27299
27283
  case "path-prompt":
27300
27284
  return /* @__PURE__ */ jsx52(
27301
27285
  PathPrompt,
27302
27286
  {
27303
- defaultPath: state.outDir,
27287
+ defaultPath: state2.outDir,
27304
27288
  onSubmit: (submitted) => void controller.submitPath(submitted),
27305
27289
  onCancel: quit
27306
27290
  }
@@ -27316,12 +27300,12 @@ function FlowScreen({
27316
27300
  }
27317
27301
  );
27318
27302
  case "print-gate": {
27319
- const teaser = buildRunTeaserLine(state.lastRunId);
27303
+ const teaser = buildRunTeaserLine(state2.lastRunId);
27320
27304
  return /* @__PURE__ */ jsx52(
27321
27305
  GateStep,
27322
27306
  {
27323
27307
  message: "Files saved",
27324
- summary: state.componentsPath ? `components.json \u2192 ${state.componentsPath}` : void 0,
27308
+ summary: state2.componentsPath ? `components.json \u2192 ${state2.componentsPath}` : void 0,
27325
27309
  context: teaser ? `Your files are saved to disk. ${teaser}` : "Your files are saved to disk. Run `experiences import` again when you're ready to push to Contentful.",
27326
27310
  continueLabel: "Exit",
27327
27311
  onContinue: quit,
@@ -27330,17 +27314,17 @@ function FlowScreen({
27330
27314
  );
27331
27315
  }
27332
27316
  case "done": {
27333
- const totalFailed = state.pushResult.componentTypes.failed + state.pushResult.designTokens.failed;
27317
+ const totalFailed = state2.pushResult.componentTypes.failed + state2.pushResult.designTokens.failed;
27334
27318
  return /* @__PURE__ */ jsx52(
27335
27319
  DoneStep,
27336
27320
  {
27337
- componentTypes: state.pushResult.componentTypes,
27338
- designTokens: state.pushResult.designTokens,
27339
- summary: state.pushResult.summary,
27340
- failures: state.pushResult.failures,
27341
- spaceId: state.spaceId,
27342
- environmentId: state.environmentId,
27343
- host: state.host,
27321
+ componentTypes: state2.pushResult.componentTypes,
27322
+ designTokens: state2.pushResult.designTokens,
27323
+ summary: state2.pushResult.summary,
27324
+ failures: state2.pushResult.failures,
27325
+ spaceId: state2.spaceId,
27326
+ environmentId: state2.environmentId,
27327
+ host: state2.host,
27344
27328
  onExit: () => onExit(totalFailed > 0 ? 1 : 0)
27345
27329
  }
27346
27330
  );
@@ -27349,8 +27333,8 @@ function FlowScreen({
27349
27333
  return /* @__PURE__ */ jsx52(
27350
27334
  PreviewValidationErrorScreen,
27351
27335
  {
27352
- errors: state.previewValidationErrors,
27353
- missingNames: state.previewValidationMissingNames,
27336
+ errors: state2.previewValidationErrors,
27337
+ missingNames: state2.previewValidationMissingNames,
27354
27338
  onEdit: controller.editDefinitions,
27355
27339
  onSkip: () => void controller.skipValidationErrors(),
27356
27340
  onQuit: quit
@@ -27360,10 +27344,10 @@ function FlowScreen({
27360
27344
  return /* @__PURE__ */ jsx52(
27361
27345
  ErrorStep,
27362
27346
  {
27363
- stepName: state.errorStep,
27364
- message: state.errorMessage,
27347
+ stepName: state2.errorStep,
27348
+ message: state2.errorMessage,
27365
27349
  onExit: () => onExit(1),
27366
- onAcknowledgeBreakingChanges: state.errorAllowBreakingChangeAcknowledgment && state.cdf ? controller.acknowledgeBreakingChanges : void 0
27350
+ onAcknowledgeBreakingChanges: state2.errorAllowBreakingChangeAcknowledgment && state2.cdf ? controller.acknowledgeBreakingChanges : void 0
27367
27351
  }
27368
27352
  );
27369
27353
  }
@@ -27381,11 +27365,11 @@ import { useEffect as useEffect20, useRef as useRef12, useSyncExternalStore } fr
27381
27365
  import { appendFileSync, writeFileSync } from "node:fs";
27382
27366
  import { mkdir as mkdir8 } from "node:fs/promises";
27383
27367
  import { tmpdir } from "node:os";
27384
- import { join as join23, resolve as resolve25 } from "node:path";
27368
+ import { join as join23 } from "node:path";
27385
27369
 
27386
27370
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27387
- function shouldBypassPreview(state) {
27388
- return state.credentialsSkipped === true;
27371
+ function shouldBypassPreview(state2) {
27372
+ return state2.credentialsSkipped === true;
27389
27373
  }
27390
27374
  function buildSkippedPreviewTransition() {
27391
27375
  return { step: "done", serverPreview: null };
@@ -27394,8 +27378,8 @@ function resolveCycleGateAction(opts) {
27394
27378
  if (!opts.hasCycles) return "proceed";
27395
27379
  return "block";
27396
27380
  }
27397
- function shouldRefusePush(state) {
27398
- return state.credentialsSkipped === true;
27381
+ function shouldRefusePush(state2) {
27382
+ return state2.credentialsSkipped === true;
27399
27383
  }
27400
27384
  function buildSkippedPushTransition() {
27401
27385
  return { step: "print-gate" };
@@ -27752,7 +27736,7 @@ var realSaveDeps = () => ({
27752
27736
  writeFile: (path5, contents) => writeFile7(path5, contents),
27753
27737
  appendRun,
27754
27738
  buildSourceFingerprint,
27755
- sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
27739
+ sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27756
27740
  warn: (message) => process.stderr.write(message)
27757
27741
  });
27758
27742
  async function runPrintFiles(input, deps, onPatch) {
@@ -27790,17 +27774,17 @@ async function runPrintFiles(input, deps, onPatch) {
27790
27774
  return { ok: true, patch: nextStateAfterPrint({ skipGate: input.skipGate, componentsPath }) };
27791
27775
  }
27792
27776
  async function recordRun(input, deps) {
27793
- const { state } = input;
27777
+ const { state: state2 } = input;
27794
27778
  try {
27795
27779
  let sourceFingerprint = null;
27796
27780
  try {
27797
- if (state.extractSessionId) {
27781
+ if (state2.extractSessionId) {
27798
27782
  const db = deps.openDb();
27799
27783
  try {
27800
27784
  sourceFingerprint = await deps.buildSourceFingerprint({
27801
27785
  db,
27802
- extractSessionId: state.extractSessionId,
27803
- rawTokensPath: state.rawTokensPath || null
27786
+ extractSessionId: state2.extractSessionId,
27787
+ rawTokensPath: state2.rawTokensPath || null
27804
27788
  });
27805
27789
  } finally {
27806
27790
  db.close();
@@ -27811,16 +27795,16 @@ async function recordRun(input, deps) {
27811
27795
  `);
27812
27796
  }
27813
27797
  const record3 = await deps.appendRun({
27814
- projectPath: state.projectPath,
27798
+ projectPath: state2.projectPath,
27815
27799
  savePath: input.savePath,
27816
- componentCount: state.generatedAcceptedCount || state.generatedCount,
27817
- tokenCount: state.tokenCount,
27818
- tokensPath: (state.tokenSessionId ? state.tokensPath || null : null) || null,
27819
- tokenSessionId: state.tokenSessionId,
27820
- agent: state.agent,
27800
+ componentCount: state2.generatedAcceptedCount || state2.generatedCount,
27801
+ tokenCount: state2.tokenCount,
27802
+ tokensPath: (state2.tokenSessionId ? state2.tokensPath || null : null) || null,
27803
+ tokenSessionId: state2.tokenSessionId,
27804
+ agent: state2.agent,
27821
27805
  pushedTo: null,
27822
- extractSessionId: state.extractSessionId ?? "",
27823
- generateSessionId: state.generateSessionId,
27806
+ extractSessionId: state2.extractSessionId ?? "",
27807
+ generateSessionId: state2.generateSessionId,
27824
27808
  sourceFingerprint
27825
27809
  });
27826
27810
  return record3.id;
@@ -27956,7 +27940,7 @@ function namesToSkip(errors) {
27956
27940
  return [...new Set(errors.map((e) => e.componentName))];
27957
27941
  }
27958
27942
  function createFlowController(start, deps) {
27959
- let state = initialFlowState(start);
27943
+ let state2 = initialFlowState(start);
27960
27944
  const listeners = /* @__PURE__ */ new Set();
27961
27945
  let allowEmptyDeleteAll = false;
27962
27946
  let pendingSave = {};
@@ -27965,27 +27949,27 @@ function createFlowController(start, deps) {
27965
27949
  deps.log({ update: sanitizeForLog(patch) });
27966
27950
  } catch {
27967
27951
  }
27968
- if (patch.step !== void 0 && patch.step !== state.step) {
27952
+ if (patch.step !== void 0 && patch.step !== state2.step) {
27969
27953
  try {
27970
27954
  deps.beforeStepChange?.();
27971
27955
  } catch {
27972
27956
  }
27973
27957
  }
27974
- state = { ...state, ...patch };
27958
+ state2 = { ...state2, ...patch };
27975
27959
  for (const listener of listeners) listener();
27976
27960
  };
27977
27961
  const preview = async () => {
27978
- if (!state.credentialsSkipped) update({ step: "previewing" });
27962
+ if (!state2.credentialsSkipped) update({ step: "previewing" });
27979
27963
  update(
27980
27964
  await runPreview(
27981
27965
  {
27982
- state,
27983
- extractSessionId: state.extractSessionId,
27984
- tokensPath: state.tokensPath,
27985
- spaceId: state.spaceId,
27986
- environmentId: state.environmentId,
27987
- cmaToken: state.cmaToken,
27988
- host: state.host,
27966
+ state: state2,
27967
+ extractSessionId: state2.extractSessionId,
27968
+ tokensPath: state2.tokensPath,
27969
+ spaceId: state2.spaceId,
27970
+ environmentId: state2.environmentId,
27971
+ cmaToken: state2.cmaToken,
27972
+ host: state2.host,
27989
27973
  deleteAll: allowEmptyDeleteAll
27990
27974
  },
27991
27975
  deps.preview
@@ -27993,18 +27977,18 @@ function createFlowController(start, deps) {
27993
27977
  );
27994
27978
  };
27995
27979
  const push = async (acknowledgeBreakingChanges) => {
27996
- if (!state.cdf) return;
27980
+ if (!state2.cdf) return;
27997
27981
  update(
27998
27982
  await runPush(
27999
27983
  {
28000
- state,
28001
- cdf: state.cdf,
28002
- spaceId: state.spaceId,
28003
- environmentId: state.environmentId,
28004
- cmaToken: state.cmaToken,
28005
- host: state.host,
27984
+ state: state2,
27985
+ cdf: state2.cdf,
27986
+ spaceId: state2.spaceId,
27987
+ environmentId: state2.environmentId,
27988
+ cmaToken: state2.cmaToken,
27989
+ host: state2.host,
28006
27990
  acknowledgeBreakingChanges,
28007
- preview: state.serverPreview
27991
+ preview: state2.serverPreview
28008
27992
  },
28009
27993
  deps.push,
28010
27994
  update
@@ -28020,11 +28004,11 @@ function createFlowController(start, deps) {
28020
28004
  const { skipGate, andPush } = pendingSave;
28021
28005
  const written = await runPrintFiles(
28022
28006
  {
28023
- extractSessionId: state.extractSessionId,
28007
+ extractSessionId: state2.extractSessionId,
28024
28008
  outDir: path5,
28025
28009
  ...skipGate ? { skipGate: true } : {},
28026
- ...state.tokenSessionId ? { tokenSessionId: state.tokenSessionId } : {},
28027
- ...state.tokensPath ? { tokensPath: state.tokensPath } : {},
28010
+ ...state2.tokenSessionId ? { tokenSessionId: state2.tokenSessionId } : {},
28011
+ ...state2.tokensPath ? { tokensPath: state2.tokensPath } : {},
28028
28012
  ...allowEmptyDeleteAll ? { allowEmpty: true } : {}
28029
28013
  },
28030
28014
  deps.save,
@@ -28032,21 +28016,21 @@ function createFlowController(start, deps) {
28032
28016
  );
28033
28017
  update(written.patch);
28034
28018
  if (!written.ok) return;
28035
- const runId = await recordRun({ state, savePath: path5 }, deps.save);
28019
+ const runId = await recordRun({ state: state2, savePath: path5 }, deps.save);
28036
28020
  if (runId) update({ lastRunId: runId });
28037
28021
  if (andPush) await preview();
28038
28022
  };
28039
28023
  const detectAcceptedCycles = () => {
28040
- if (!state.extractSessionId) return [];
28024
+ if (!state2.extractSessionId) return [];
28041
28025
  try {
28042
- const accepted = deps.loadAcceptedComponents(state.extractSessionId);
28026
+ const accepted = deps.loadAcceptedComponents(state2.extractSessionId);
28043
28027
  return findSlotCycles3(buildComponentGraph3(accepted));
28044
28028
  } catch {
28045
28029
  return [];
28046
28030
  }
28047
28031
  };
28048
28032
  const begin = () => {
28049
- if (!state.extractSessionId || !start.handoff.generation) {
28033
+ if (!state2.extractSessionId || !start.handoff.generation) {
28050
28034
  update({
28051
28035
  step: "error",
28052
28036
  errorStep: "start import",
@@ -28063,7 +28047,7 @@ function createFlowController(start, deps) {
28063
28047
  };
28064
28048
  begin();
28065
28049
  return {
28066
- getState: () => state,
28050
+ getState: () => state2,
28067
28051
  subscribe: (listener) => {
28068
28052
  listeners.add(listener);
28069
28053
  return () => listeners.delete(listener);
@@ -28086,7 +28070,7 @@ function createFlowController(start, deps) {
28086
28070
  },
28087
28071
  async submitPath(submitted) {
28088
28072
  await deps.mkdir(submitted);
28089
- if (resolve25(submitted) !== resolve25(state.outDir) && await deps.detectSaveConflict(submitted)) {
28073
+ if (await deps.detectSaveConflict(submitted)) {
28090
28074
  const subdir = deps.buildTimestampedSubdir(submitted);
28091
28075
  await deps.mkdir(subdir);
28092
28076
  await proceedToWrite(subdir);
@@ -28098,9 +28082,9 @@ function createFlowController(start, deps) {
28098
28082
  acknowledgeBreakingChanges: () => void push(true),
28099
28083
  editDefinitions: () => update({ step: "final-review" }),
28100
28084
  async skipValidationErrors() {
28101
- if (state.extractSessionId) {
28102
- const names = namesToSkip(state.previewValidationErrors);
28103
- if (names.length > 0) await deps.rejectComponentsByName(state.extractSessionId, names);
28085
+ if (state2.extractSessionId) {
28086
+ const names = namesToSkip(state2.previewValidationErrors);
28087
+ if (names.length > 0) await deps.rejectComponentsByName(state2.extractSessionId, names);
28104
28088
  }
28105
28089
  await preview();
28106
28090
  }
@@ -28122,32 +28106,184 @@ function useFlow(start, options = {}) {
28122
28106
  });
28123
28107
  }
28124
28108
  const current = controller.current;
28125
- const state = useSyncExternalStore(
28109
+ const state2 = useSyncExternalStore(
28126
28110
  (listener) => current?.subscribe(listener) ?? (() => void 0),
28127
28111
  () => current?.getState()
28128
28112
  );
28129
28113
  useEffect20(() => {
28130
28114
  if (!start) controller.current = void 0;
28131
28115
  }, [start]);
28132
- return current && state ? { controller: current, state } : void 0;
28116
+ return current && state2 ? { controller: current, state: state2 } : void 0;
28133
28117
  }
28134
28118
 
28135
28119
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
28136
28120
  import { useEffect as useEffect21, useState as useState27 } from "react";
28137
28121
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
28138
- init_debug_store();
28122
+
28123
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
28124
+ import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
28125
+ import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
28126
+ import { join as join24 } from "node:path";
28127
+
28128
+ // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
28129
+ var DEFAULT_DEBUG_MODE_SETTING = {
28130
+ enabled: true
28131
+ };
28132
+ async function readDebugModeSetting() {
28133
+ const { debugMode } = await readSettings2();
28134
+ return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
28135
+ }
28136
+ async function writeDebugModeSetting(setting) {
28137
+ await updateSettings2({ debugMode: setting });
28138
+ }
28139
+
28140
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
28141
+ var pendingRun;
28142
+ function generateRunId() {
28143
+ const now = /* @__PURE__ */ new Date();
28144
+ const pad = (n) => String(n).padStart(2, "0");
28145
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
28146
+ }
28147
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
28148
+ const pad = (n) => String(n).padStart(2, "0");
28149
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
28150
+ }
28151
+ function slugify(value) {
28152
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
28153
+ }
28154
+ function generateSessionId3() {
28155
+ const today = datePrefix();
28156
+ const root = debugSessionsDir2();
28157
+ const existing = existsSync9(root) ? readdirSync4(root) : [];
28158
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
28159
+ const maxSeq = existing.reduce((max, entry) => {
28160
+ const match2 = seqPattern.exec(entry);
28161
+ return match2 ? Math.max(max, Number(match2[1])) : max;
28162
+ }, 0);
28163
+ return `${today}-session-${maxSeq + 1}`;
28164
+ }
28165
+ var SESSION_ID = generateSessionId3();
28166
+ function sessionDebugDir() {
28167
+ return join24(debugSessionsDir2(), SESSION_ID);
28168
+ }
28169
+ function currentDebugSessionDir() {
28170
+ return sessionDebugDir();
28171
+ }
28172
+ void isDebugModeEnabled().then((enabled) => {
28173
+ if (!enabled) return void 0;
28174
+ return mkdir9(sessionDebugDir(), { recursive: true });
28175
+ });
28176
+ async function isDebugModeEnabled() {
28177
+ try {
28178
+ return (await readDebugModeSetting()).enabled;
28179
+ } catch {
28180
+ return true;
28181
+ }
28182
+ }
28183
+ function redact(value) {
28184
+ const clone = { ...value };
28185
+ if ("cma_token" in clone) {
28186
+ const raw = clone.cma_token;
28187
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
28188
+ }
28189
+ return clone;
28190
+ }
28191
+ function startDebugRun({
28192
+ flow,
28193
+ step,
28194
+ menuOption,
28195
+ inputs
28196
+ }) {
28197
+ const runId = generateRunId();
28198
+ const startedAt = Date.now();
28199
+ const redactedInputs = redact(inputs);
28200
+ isDebugModeEnabled().then((enabled) => {
28201
+ if (!enabled) return;
28202
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
28203
+ });
28204
+ }
28205
+ async function finishDebugRun({
28206
+ outputs,
28207
+ status,
28208
+ exitMethod
28209
+ }) {
28210
+ const run = pendingRun;
28211
+ if (!run) return;
28212
+ pendingRun = void 0;
28213
+ const durationMs = Date.now() - run.startedAt;
28214
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
28215
+ const flowSegments = run.flow.split("/");
28216
+ const dir = join24(sessionDebugDir(), ...flowSegments);
28217
+ await mkdir9(dir, { recursive: true });
28218
+ const filename = nextAttemptFilename(dir, run.menuOption);
28219
+ await writeFile8(join24(dir, filename), content, { mode: 384 });
28220
+ }
28221
+ function nextAttemptFilename(dir, menuOption) {
28222
+ const today = datePrefix();
28223
+ const optionSlug = slugify(menuOption);
28224
+ const existing = existsSync9(dir) ? readdirSync4(dir) : [];
28225
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
28226
+ const maxAttempt = existing.reduce((max, entry) => {
28227
+ const match2 = attemptPattern.exec(entry);
28228
+ return match2 ? Math.max(max, Number(match2[1])) : max;
28229
+ }, 0);
28230
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
28231
+ }
28232
+ function renderMarkdown(run, finish) {
28233
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
28234
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
28235
+ const flowSlug = run.flow.split("/").join("-");
28236
+ return `# Debug Log
28237
+
28238
+ - Run ID: ${run.runId}
28239
+ - Flow: ${flowSlug}
28240
+ - Step: ${stepLabel2}
28241
+ - Menu option: ${run.menuOption}
28242
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
28243
+ - CLI version: ${readPackageVersion()}
28244
+ - Platform: ${process.platform} / Node ${process.version}
28245
+ - Duration on screen: ${finish.durationMs}ms
28246
+ - Status: ${finish.status}
28247
+ - Exit method: ${finish.exitMethod}
28248
+
28249
+ ## Inputs
28250
+ \`\`\`json
28251
+ ${JSON.stringify(run.inputs, null, 2)}
28252
+ \`\`\`
28253
+
28254
+ ## Outputs
28255
+ \`\`\`json
28256
+ ${JSON.stringify(finish.outputs, null, 2)}
28257
+ \`\`\`
28258
+ `;
28259
+ }
28260
+ function handleCrash() {
28261
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28262
+ }
28263
+ process.once("uncaughtException", (err) => {
28264
+ void handleCrash().finally(() => {
28265
+ throw err;
28266
+ });
28267
+ });
28268
+ process.once("unhandledRejection", (reason) => {
28269
+ void handleCrash().finally(() => {
28270
+ throw reason;
28271
+ });
28272
+ });
28273
+ process.once("SIGINT", () => {
28274
+ void handleCrash().finally(() => {
28275
+ process.exit(130);
28276
+ });
28277
+ });
28139
28278
 
28140
28279
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28141
- init_config();
28142
- init_debug_store();
28143
- init_debug_mode_store();
28144
- init_version();
28145
28280
  async function readHelpInfo() {
28146
28281
  const debugMode = await readDebugModeSetting();
28147
28282
  return {
28148
28283
  storage: [
28149
28284
  { label: "Config folder", value: configRoot2() },
28150
- { label: "Settings file", value: configFilePath2() }
28285
+ { label: "Settings file", value: configFilePath2() },
28286
+ { label: "Debug logs", value: debugSessionsDir2() }
28151
28287
  ],
28152
28288
  troubleshooting: [
28153
28289
  { label: "CLI version", value: readPackageVersion() },
@@ -28156,7 +28292,7 @@ async function readHelpInfo() {
28156
28292
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28157
28293
  {
28158
28294
  label: "This session",
28159
- value: !debugMode.enabled ? "no logs written while Debug Mode is off" : currentDebugSessionDir() ?? "not started: set the Root Project Directory in Settings, or start an import"
28295
+ value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28160
28296
  }
28161
28297
  ]
28162
28298
  };
@@ -28273,7 +28409,6 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28273
28409
  import TextInput4 from "ink-text-input";
28274
28410
 
28275
28411
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28276
- init_config();
28277
28412
  var readV1Store = readSettings2;
28278
28413
  var writeV1Store = writeSettings2;
28279
28414
 
@@ -28286,8 +28421,7 @@ async function readCredentials() {
28286
28421
  cmaToken: store.cmaToken || "",
28287
28422
  host: store.host || "",
28288
28423
  defaultComponentDir: store.defaultComponentDir || "",
28289
- defaultTokenFile: store.defaultTokenFile || "",
28290
- contentfulBaseDir: store.contentfulBaseDir || ""
28424
+ defaultTokenFile: store.defaultTokenFile || ""
28291
28425
  };
28292
28426
  }
28293
28427
  async function writeCredentials(config) {
@@ -28303,7 +28437,6 @@ async function writeCredentials(config) {
28303
28437
  }
28304
28438
 
28305
28439
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28306
- init_debug_store();
28307
28440
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28308
28441
  var FIELD_ORDER = [
28309
28442
  "spaceId",
@@ -28311,8 +28444,7 @@ var FIELD_ORDER = [
28311
28444
  "cmaToken",
28312
28445
  "host",
28313
28446
  "defaultComponentDir",
28314
- "defaultTokenFile",
28315
- "contentfulBaseDir"
28447
+ "defaultTokenFile"
28316
28448
  ];
28317
28449
  function debugFields(config) {
28318
28450
  return {
@@ -28321,23 +28453,17 @@ function debugFields(config) {
28321
28453
  cma_token: config?.cmaToken ?? "",
28322
28454
  host: config?.host ?? "",
28323
28455
  default_component_dir: config?.defaultComponentDir ?? "",
28324
- default_token_file: config?.defaultTokenFile ?? "",
28325
- contentful_base_dir: config?.contentfulBaseDir ?? ""
28456
+ default_token_file: config?.defaultTokenFile ?? ""
28326
28457
  };
28327
28458
  }
28328
28459
  var FIELD_LABELS = {
28329
28460
  spaceId: "Space ID",
28330
28461
  environmentId: "Environment ID",
28331
28462
  cmaToken: "CMA Token",
28332
- host: "API Host",
28333
- defaultComponentDir: "Default component directory",
28334
- defaultTokenFile: "Default token file",
28335
- contentfulBaseDir: "Root Project Directory"
28463
+ host: "API Host (optional)",
28464
+ defaultComponentDir: "Default component directory (optional)",
28465
+ defaultTokenFile: "Default token file (optional)"
28336
28466
  };
28337
- var FIELD_HINTS = {
28338
- contentfulBaseDir: "(where .contentful goes)"
28339
- };
28340
- var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28341
28467
  function ConfigurationScreen({ onDone }) {
28342
28468
  const [stage, setStage] = useState29("loading");
28343
28469
  const [config, setConfig] = useState29(null);
@@ -28373,7 +28499,6 @@ function ConfigurationScreen({ onDone }) {
28373
28499
  setNotice(null);
28374
28500
  writeCredentials(config).then(() => {
28375
28501
  setLastSaved(config);
28376
- if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28377
28502
  setNotice({ kind: "success", text: "Configuration saved" });
28378
28503
  setStage("form");
28379
28504
  }).catch((err) => {
@@ -28439,7 +28564,10 @@ function ConfigurationScreen({ onDone }) {
28439
28564
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28440
28565
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28441
28566
  /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28442
- /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28567
+ /* @__PURE__ */ jsxs45(Text46, { bold: isActive, children: [
28568
+ FIELD_LABELS[field],
28569
+ ":"
28570
+ ] }),
28443
28571
  isActive && editing ? /* @__PURE__ */ jsx55(
28444
28572
  TextInput4,
28445
28573
  {
@@ -28448,8 +28576,7 @@ function ConfigurationScreen({ onDone }) {
28448
28576
  onSubmit: () => setEditing(false),
28449
28577
  mask: field === "cmaToken" ? "\u2022" : void 0
28450
28578
  }
28451
- ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28452
- FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28579
+ ) : /* @__PURE__ */ jsx55(Text46, { children: display || /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" }) })
28453
28580
  ] }, field);
28454
28581
  }) }),
28455
28582
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
@@ -28501,7 +28628,6 @@ async function writeAnalyticsSetting(setting) {
28501
28628
  }
28502
28629
 
28503
28630
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28504
- init_debug_store();
28505
28631
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28506
28632
  function OptInAnalyticsScreen({ onDone }) {
28507
28633
  const [loading, setLoading] = useState30(true);
@@ -28562,8 +28688,6 @@ function OptInAnalyticsScreen({ onDone }) {
28562
28688
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28563
28689
  import { useEffect as useEffect24, useState as useState31 } from "react";
28564
28690
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28565
- init_version();
28566
- init_debug_store();
28567
28691
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28568
28692
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28569
28693
  function UpgradeScreen({ onDone }) {
@@ -28635,8 +28759,6 @@ function renderBody(upgradeCheck) {
28635
28759
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28636
28760
  import { useEffect as useEffect25, useState as useState32 } from "react";
28637
28761
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28638
- init_debug_mode_store();
28639
- init_debug_store();
28640
28762
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28641
28763
  function DebugModeScreen({ onDone }) {
28642
28764
  const [loading, setLoading] = useState32(true);
@@ -28737,16 +28859,16 @@ function App({ importOptions, inkClear }) {
28737
28859
  const finishCredentials = async (result, projectPath2, tokens, filePaths) => {
28738
28860
  if (!result.skipped) await writeCredentials({ ...result.credentials });
28739
28861
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
28740
- const state = await inspectTokens({
28862
+ const state2 = await inspectTokens({
28741
28863
  rawTokensPath: tokens,
28742
- contentfulDir: join25(resolveUserPath(projectPath2), ".contentful"),
28864
+ outDir: join25(resolveUserPath(projectPath2), ".contentful"),
28743
28865
  cache: importOptions.cache
28744
28866
  });
28745
- if (state.kind === "cached") {
28867
+ if (state2.kind === "cached") {
28746
28868
  setPendingLaunch({
28747
28869
  launch,
28748
28870
  credentials: result,
28749
- cached: { tokensPath: state.tokensPath, sourceChanged: state.sourceChanged }
28871
+ cached: { tokensPath: state2.tokensPath, sourceChanged: state2.sourceChanged }
28750
28872
  });
28751
28873
  return;
28752
28874
  }
@@ -28760,7 +28882,6 @@ function App({ importOptions, inkClear }) {
28760
28882
  const settings = await readSettings2();
28761
28883
  const { agent, agentModel } = resolveAgentChoice(launch.agent, settings);
28762
28884
  const generatePromptPath = typeof settings.generatePromptPath === "string" ? settings.generatePromptPath : void 0;
28763
- const outDir = await (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).startImportRun(resolveUserPath(launch.projectPath ?? ""));
28764
28885
  setExtractionRun({
28765
28886
  ...generatePromptPath ? { generatePromptPath } : {},
28766
28887
  // the later steps get the same agent, so they use what the stage used
@@ -28769,7 +28890,6 @@ function App({ importOptions, inkClear }) {
28769
28890
  tokenStrategy,
28770
28891
  input: {
28771
28892
  projectPath: resolveUserPath(launch.projectPath ?? ""),
28772
- outDir,
28773
28893
  filePaths: launch.filePaths ?? [],
28774
28894
  rawTokensPath: launch.tokens ?? "",
28775
28895
  tokenStrategy,