@contentful/experience-design-system-cli 2.37.1-dev-build-5654e400.0 → 2.37.1-dev-build-5bd13138.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,6 +8,71 @@ 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
+
11
76
  // packages/experience-design-system-backend-pipeline/dist/src/agents/types/agent-name.js
12
77
  var AGENT_NAMES;
13
78
  var init_agent_name = __esm({
@@ -772,7 +837,7 @@ async function runAgent(options) {
772
837
  promptLen: prompt.length,
773
838
  promptHead: prompt.slice(0, 500)
774
839
  });
775
- return new Promise((resolve25) => {
840
+ return new Promise((resolve26) => {
776
841
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
777
842
  const child = spawn(binary, args, {
778
843
  stdio: ["pipe", "pipe", "pipe"],
@@ -821,7 +886,7 @@ async function runAgent(options) {
821
886
  stderrLen: stderr.length,
822
887
  stderrTail: stderr.slice(-1e3)
823
888
  });
824
- resolve25(result);
889
+ resolve26(result);
825
890
  });
826
891
  });
827
892
  }
@@ -843,7 +908,7 @@ async function checkAgentAuth(agent) {
843
908
  return "not-found";
844
909
  if (agent !== "claude")
845
910
  return "ok";
846
- return new Promise((resolve25) => {
911
+ return new Promise((resolve26) => {
847
912
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
848
913
  let stdout = "";
849
914
  let done = false;
@@ -852,7 +917,7 @@ async function checkAgentAuth(agent) {
852
917
  return;
853
918
  done = true;
854
919
  child.kill("SIGTERM");
855
- resolve25("unauthenticated");
920
+ resolve26("unauthenticated");
856
921
  }, 5e3);
857
922
  child.stdout?.on("data", (chunk) => {
858
923
  stdout += chunk.toString();
@@ -863,14 +928,14 @@ async function checkAgentAuth(agent) {
863
928
  done = true;
864
929
  clearTimeout(timer);
865
930
  if (code !== 0) {
866
- resolve25("unauthenticated");
931
+ resolve26("unauthenticated");
867
932
  return;
868
933
  }
869
934
  try {
870
935
  const status = JSON.parse(stdout);
871
- resolve25(status.loggedIn ? "ok" : "unauthenticated");
936
+ resolve26(status.loggedIn ? "ok" : "unauthenticated");
872
937
  } catch {
873
- resolve25("unauthenticated");
938
+ resolve26("unauthenticated");
874
939
  }
875
940
  });
876
941
  });
@@ -880,9 +945,9 @@ async function binaryIsOnPath(binary) {
880
945
  const fs = await import("node:fs/promises");
881
946
  return fs.access(binary).then(() => true, () => false);
882
947
  }
883
- return new Promise((resolve25) => {
948
+ return new Promise((resolve26) => {
884
949
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
885
- child.on("close", (code) => resolve25(code === 0));
950
+ child.on("close", (code) => resolve26(code === 0));
886
951
  });
887
952
  }
888
953
  var init_check_agent_auth = __esm({
@@ -2016,9 +2081,242 @@ var init_cache_keys = __esm({
2016
2081
  }
2017
2082
  });
2018
2083
 
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, debugSessionsDir2;
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
+ debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
2116
+ }
2117
+ });
2118
+
2119
+ // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
2120
+ async function readDebugModeSetting() {
2121
+ const { debugMode } = await readSettings2();
2122
+ return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
2123
+ }
2124
+ async function writeDebugModeSetting(setting) {
2125
+ await updateSettings2({ debugMode: setting });
2126
+ }
2127
+ var DEFAULT_DEBUG_MODE_SETTING;
2128
+ var init_debug_mode_store = __esm({
2129
+ "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
2130
+ "use strict";
2131
+ init_config();
2132
+ DEFAULT_DEBUG_MODE_SETTING = {
2133
+ enabled: true
2134
+ };
2135
+ }
2136
+ });
2137
+
2138
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
2139
+ var debug_store_exports = {};
2140
+ __export(debug_store_exports, {
2141
+ currentDebugSessionDir: () => currentDebugSessionDir,
2142
+ finishDebugRun: () => finishDebugRun,
2143
+ setDebugOutDir: () => setDebugOutDir,
2144
+ startDebugRun: () => startDebugRun
2145
+ });
2146
+ import { cp, mkdir as mkdir7, rename as rename3, rm, writeFile as writeFile7 } from "node:fs/promises";
2147
+ import { existsSync as existsSync8, readdirSync as readdirSync3 } from "node:fs";
2148
+ import { join as join18, resolve as resolve20 } from "node:path";
2149
+ function generateRunId() {
2150
+ const now = /* @__PURE__ */ new Date();
2151
+ const pad = (n) => String(n).padStart(2, "0");
2152
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
2153
+ }
2154
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
2155
+ const pad = (n) => String(n).padStart(2, "0");
2156
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
2157
+ }
2158
+ function slugify(value) {
2159
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2160
+ }
2161
+ function generateSessionId3() {
2162
+ const today = datePrefix();
2163
+ const root = debugSessionsDir2();
2164
+ const existing = existsSync8(root) ? readdirSync3(root) : [];
2165
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2166
+ const maxSeq = existing.reduce((max, entry) => {
2167
+ const match2 = seqPattern.exec(entry);
2168
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2169
+ }, 0);
2170
+ return `${today}-session-${maxSeq + 1}`;
2171
+ }
2172
+ function sessionDebugDir() {
2173
+ return join18(projectSessionsRoot ?? debugSessionsDir2(), SESSION_ID);
2174
+ }
2175
+ function currentDebugSessionDir() {
2176
+ return sessionDebugDir();
2177
+ }
2178
+ async function setDebugOutDir(outDir) {
2179
+ if (!await isDebugModeEnabled()) return;
2180
+ const nextRoot = join18(resolve20(outDir), "debug", "sessions");
2181
+ const from = sessionDebugDir();
2182
+ const to = join18(nextRoot, SESSION_ID);
2183
+ if (from === to) return;
2184
+ try {
2185
+ await mkdir7(nextRoot, { recursive: true });
2186
+ if (existsSync8(from)) {
2187
+ try {
2188
+ await rename3(from, to);
2189
+ } catch {
2190
+ await cp(from, to, { recursive: true });
2191
+ await rm(from, { recursive: true, force: true });
2192
+ }
2193
+ } else {
2194
+ await mkdir7(to, { recursive: true });
2195
+ }
2196
+ projectSessionsRoot = nextRoot;
2197
+ } catch {
2198
+ }
2199
+ }
2200
+ async function isDebugModeEnabled() {
2201
+ try {
2202
+ return (await readDebugModeSetting()).enabled;
2203
+ } catch {
2204
+ return true;
2205
+ }
2206
+ }
2207
+ function redact(value) {
2208
+ const clone = { ...value };
2209
+ if ("cma_token" in clone) {
2210
+ const raw = clone.cma_token;
2211
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2212
+ }
2213
+ return clone;
2214
+ }
2215
+ function startDebugRun({
2216
+ flow,
2217
+ step,
2218
+ menuOption,
2219
+ inputs
2220
+ }) {
2221
+ const runId = generateRunId();
2222
+ const startedAt = Date.now();
2223
+ const redactedInputs = redact(inputs);
2224
+ isDebugModeEnabled().then((enabled) => {
2225
+ if (!enabled) return;
2226
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2227
+ });
2228
+ }
2229
+ async function finishDebugRun({
2230
+ outputs,
2231
+ status,
2232
+ exitMethod
2233
+ }) {
2234
+ const run = pendingRun;
2235
+ if (!run) return;
2236
+ pendingRun = void 0;
2237
+ const durationMs = Date.now() - run.startedAt;
2238
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2239
+ const flowSegments = run.flow.split("/");
2240
+ const dir = join18(sessionDebugDir(), ...flowSegments);
2241
+ await mkdir7(dir, { recursive: true });
2242
+ const filename = nextAttemptFilename(dir, run.menuOption);
2243
+ await writeFile7(join18(dir, filename), content, { mode: 384 });
2244
+ }
2245
+ function nextAttemptFilename(dir, menuOption) {
2246
+ const today = datePrefix();
2247
+ const optionSlug = slugify(menuOption);
2248
+ const existing = existsSync8(dir) ? readdirSync3(dir) : [];
2249
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2250
+ const maxAttempt = existing.reduce((max, entry) => {
2251
+ const match2 = attemptPattern.exec(entry);
2252
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2253
+ }, 0);
2254
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2255
+ }
2256
+ function renderMarkdown(run, finish) {
2257
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2258
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2259
+ const flowSlug = run.flow.split("/").join("-");
2260
+ return `# Debug Log
2261
+
2262
+ - Run ID: ${run.runId}
2263
+ - Flow: ${flowSlug}
2264
+ - Step: ${stepLabel2}
2265
+ - Menu option: ${run.menuOption}
2266
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2267
+ - CLI version: ${readPackageVersion()}
2268
+ - Platform: ${process.platform} / Node ${process.version}
2269
+ - Duration on screen: ${finish.durationMs}ms
2270
+ - Status: ${finish.status}
2271
+ - Exit method: ${finish.exitMethod}
2272
+
2273
+ ## Inputs
2274
+ \`\`\`json
2275
+ ${JSON.stringify(run.inputs, null, 2)}
2276
+ \`\`\`
2277
+
2278
+ ## Outputs
2279
+ \`\`\`json
2280
+ ${JSON.stringify(finish.outputs, null, 2)}
2281
+ \`\`\`
2282
+ `;
2283
+ }
2284
+ function handleCrash() {
2285
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2286
+ }
2287
+ var pendingRun, SESSION_ID, projectSessionsRoot;
2288
+ var init_debug_store = __esm({
2289
+ "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2290
+ "use strict";
2291
+ init_config();
2292
+ init_version();
2293
+ init_debug_mode_store();
2294
+ SESSION_ID = generateSessionId3();
2295
+ void isDebugModeEnabled().then((enabled) => {
2296
+ if (!enabled) return void 0;
2297
+ return mkdir7(sessionDebugDir(), { recursive: true });
2298
+ });
2299
+ process.once("uncaughtException", (err) => {
2300
+ void handleCrash().finally(() => {
2301
+ throw err;
2302
+ });
2303
+ });
2304
+ process.once("unhandledRejection", (reason) => {
2305
+ void handleCrash().finally(() => {
2306
+ throw reason;
2307
+ });
2308
+ });
2309
+ process.once("SIGINT", () => {
2310
+ void handleCrash().finally(() => {
2311
+ process.exit(130);
2312
+ });
2313
+ });
2314
+ }
2315
+ });
2316
+
2019
2317
  // packages/experience-design-system-cli/app.tsx
2020
2318
  import { join as join25 } from "node:path";
2021
- import { useEffect as useEffect26, useState as useState33 } from "react";
2319
+ import { useEffect as useEffect27, useState as useState33 } from "react";
2022
2320
 
2023
2321
  // packages/experience-design-system-cli/src/tui/home/home.tsx
2024
2322
  import { useEffect as useEffect2, useState as useState2 } from "react";
@@ -2055,60 +2353,8 @@ function brandBar(width, ramp = BRAND_RAMP) {
2055
2353
  }
2056
2354
  var FOCUS_MARKER = "\u276F";
2057
2355
 
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
- }
2356
+ // packages/experience-design-system-cli/src/tui/home/home.tsx
2357
+ init_version();
2112
2358
 
2113
2359
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2114
2360
  import { useEffect, useState } from "react";
@@ -4132,12 +4378,12 @@ function renameEmptySlots(db, sessionId, componentId, componentName, slotCount)
4132
4378
  return { renames: [], warnings: [] };
4133
4379
  const renames = [];
4134
4380
  const warnings = [];
4135
- const rename3 = db.prepare(`UPDATE raw_slots SET name = ? WHERE session_id = ? AND component_id = ? AND name = ? AND position = ?`);
4381
+ const rename4 = db.prepare(`UPDATE raw_slots SET name = ? WHERE session_id = ? AND component_id = ? AND name = ? AND position = ?`);
4136
4382
  db.exec("BEGIN");
4137
4383
  try {
4138
4384
  for (const slot of emptySlots) {
4139
4385
  const newName = slotCount === 1 ? "children" : `slot_${slot.position}`;
4140
- rename3.run(newName, sessionId, componentId, slot.name, slot.position);
4386
+ rename4.run(newName, sessionId, componentId, slot.name, slot.position);
4141
4387
  renames.push({ oldName: slot.name, newName });
4142
4388
  warnings.push(`${componentName}: slot at position ${slot.position} had empty name \u2014 renamed to "${newName}" for classification`);
4143
4389
  }
@@ -4887,7 +5133,7 @@ function getTsxExtractionContext(filePaths, componentFilePattern) {
4887
5133
  project: createTsxProject(getTsxProjectFiles(filePaths))
4888
5134
  };
4889
5135
  }
4890
- function extractTsxComponents(filePaths, componentFilePattern, extract) {
5136
+ function extractTsxComponents(filePaths, componentFilePattern, extract2) {
4891
5137
  const extractionContext = getTsxExtractionContext(filePaths, componentFilePattern);
4892
5138
  if (!extractionContext) {
4893
5139
  return { components: [], warnings: [], exclusions: [] };
@@ -4901,7 +5147,7 @@ function extractTsxComponents(filePaths, componentFilePattern, extract) {
4901
5147
  const sourceFile = project.getSourceFile(filePath);
4902
5148
  if (!sourceFile)
4903
5149
  continue;
4904
- components.push(...extract(sourceFile, exclusions));
5150
+ components.push(...extract2(sourceFile, exclusions));
4905
5151
  } catch (e) {
4906
5152
  warnings.push(`Failed to extract from ${filePath}: ${e instanceof Error ? e.message : String(e)}`);
4907
5153
  }
@@ -13510,7 +13756,7 @@ function errorMessage(error) {
13510
13756
  return error instanceof Error && error.message ? error.message : String(error);
13511
13757
  }
13512
13758
  function defaultSleep(delayMs) {
13513
- return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13759
+ return new Promise((resolve26) => setTimeout(resolve26, delayMs));
13514
13760
  }
13515
13761
 
13516
13762
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -13751,7 +13997,7 @@ var ApiClient = class {
13751
13997
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13752
13998
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13753
13999
  const jitter = Math.random() * baseDelay * 0.15;
13754
- await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
14000
+ await new Promise((resolve26) => setTimeout(resolve26, baseDelay + jitter));
13755
14001
  }
13756
14002
  }
13757
14003
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -15864,7 +16110,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
15864
16110
  const message = error instanceof Error ? error.message : String(error);
15865
16111
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
15866
16112
  throw error;
15867
- await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16113
+ await new Promise((resolve26) => setTimeout(resolve26, Math.min(250 * attempt, 2e3)));
15868
16114
  }
15869
16115
  }
15870
16116
  }
@@ -16281,12 +16527,12 @@ async function runOneGenerateComponent(options, component, index, total) {
16281
16527
  if (renames.length > 0) {
16282
16528
  const renameMap = new Map(renames.map((r) => [r.oldName, r.newName]));
16283
16529
  effectiveSlots = component.slots.map((s) => renameMap.has(s.name) ? { ...s, name: renameMap.get(s.name) } : s);
16284
- for (const rename3 of renames) {
16530
+ for (const rename4 of renames) {
16285
16531
  onProgress?.({
16286
16532
  kind: "component:slot-renamed",
16287
16533
  componentName: component.name,
16288
- oldName: rename3.oldName,
16289
- newName: rename3.newName
16534
+ oldName: rename4.oldName,
16535
+ newName: rename4.newName
16290
16536
  });
16291
16537
  }
16292
16538
  }
@@ -16687,6 +16933,7 @@ function useCredentialsControls(handlers) {
16687
16933
  }
16688
16934
 
16689
16935
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16936
+ init_version();
16690
16937
  function cliUserAgent() {
16691
16938
  return buildUserAgent(readPackageVersion());
16692
16939
  }
@@ -17186,53 +17433,34 @@ function ExtractionScreen({
17186
17433
  );
17187
17434
  }
17188
17435
 
17189
- // packages/experience-design-system-types/dist/src/config/index.js
17190
- import { randomBytes as randomBytes3 } from "node:crypto";
17191
- import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
17192
- import { homedir as homedir3 } from "node:os";
17193
- import { dirname as dirname13, join as join17 } from "node:path";
17194
- function configRoot2() {
17195
- return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
17196
- }
17197
- var configFilePath2 = () => join17(configRoot2(), "config.json");
17198
- var debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
17199
- async function readSettings2() {
17200
- try {
17201
- return JSON.parse(await readFile18(configFilePath2(), "utf8"));
17202
- } catch {
17203
- return {};
17204
- }
17205
- }
17206
- async function writeSettings2(settings) {
17207
- const path5 = configFilePath2();
17208
- await mkdir6(dirname13(path5), { recursive: true });
17209
- const tmp = `${path5}.${process.pid}.${randomBytes3(4).toString("hex")}.tmp`;
17210
- await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
17211
- `, { mode: 384 });
17212
- await rename2(tmp, path5);
17213
- }
17214
- async function updateSettings2(patch) {
17215
- await writeSettings2({ ...await readSettings2(), ...patch });
17216
- }
17436
+ // packages/experience-design-system-cli/app.tsx
17437
+ init_config();
17217
17438
 
17218
17439
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17219
17440
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
17220
17441
 
17221
17442
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run.ts
17222
- import { mkdir as mkdir7 } from "node:fs/promises";
17223
- import { join as join19, resolve as resolve22 } from "node:path";
17443
+ import { mkdir as mkdir8 } from "node:fs/promises";
17444
+ import { join as join20, resolve as resolve23 } from "node:path";
17445
+
17446
+ // packages/experience-design-system-cli/src/tui/import/debug-hooks.ts
17447
+ var realDebugHooks = {
17448
+ setOutDir: async (outDir) => (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).setDebugOutDir(outDir),
17449
+ start: (run) => void Promise.resolve().then(() => (init_debug_store(), debug_store_exports)).then((m) => m.startDebugRun(run)),
17450
+ finish: async (run) => (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).finishDebugRun(run)
17451
+ };
17224
17452
 
17225
17453
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/find-skill-path.ts
17226
- import { existsSync as existsSync8 } from "node:fs";
17227
- import { dirname as dirname14, join as join18, resolve as resolve20 } from "node:path";
17454
+ import { existsSync as existsSync9 } from "node:fs";
17455
+ import { dirname as dirname14, join as join19, resolve as resolve21 } from "node:path";
17228
17456
  import { fileURLToPath as fileURLToPath4 } from "node:url";
17229
17457
  function findSkillPath(fileName) {
17230
17458
  const thisDir = dirname14(fileURLToPath4(import.meta.url));
17231
17459
  let dir = thisDir;
17232
17460
  for (; ; ) {
17233
- const candidate = join18(dir, "skills", fileName);
17234
- if (existsSync8(candidate)) return candidate;
17235
- const parent = resolve20(dir, "..");
17461
+ const candidate = join19(dir, "skills", fileName);
17462
+ if (existsSync9(candidate)) return candidate;
17463
+ const parent = resolve21(dir, "..");
17236
17464
  if (parent === dir) {
17237
17465
  throw new Error(`skill file not found (looked for skills/${fileName} from ${thisDir})`);
17238
17466
  }
@@ -17241,11 +17469,11 @@ function findSkillPath(fileName) {
17241
17469
  }
17242
17470
 
17243
17471
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/selection.ts
17244
- import { resolve as resolve21 } from "node:path";
17472
+ import { resolve as resolve22 } from "node:path";
17245
17473
  var SELECT_SKILL_PATH = findSkillPath("select-components.md");
17246
17474
  var DEFAULT_TIMEOUT_MS5 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
17247
17475
  async function hashSelectPrompt(options) {
17248
- const promptHash = options.promptText ? hashContent(options.promptText) : options.promptPath ? await hashFile(resolve21(options.promptPath)) : await hashFile(SELECT_SKILL_PATH);
17476
+ const promptHash = options.promptText ? hashContent(options.promptText) : options.promptPath ? await hashFile(resolve22(options.promptPath)) : await hashFile(SELECT_SKILL_PATH);
17249
17477
  return hashContent(`${promptHash}|${options.agent}|${options.model ?? ""}`);
17250
17478
  }
17251
17479
  async function runSelection(options) {
@@ -17335,12 +17563,32 @@ var realDeps = {
17335
17563
  fetchEntities,
17336
17564
  runExtractAndComposeSession,
17337
17565
  runGenerateTokensSession,
17338
- runSelection
17566
+ runSelection,
17567
+ debug: realDebugHooks
17339
17568
  };
17340
17569
  var fail = (step, message) => ({ ok: false, step, message });
17341
17570
  var errorMessage2 = (error) => error instanceof Error ? error.message : String(error);
17342
17571
  async function runExtraction(input, onProgress, deps = realDeps) {
17343
- const outDir = join19(resolve22(input.projectPath), ".contentful");
17572
+ const outDir = join20(resolve23(input.projectPath), ".contentful");
17573
+ await deps.debug?.setOutDir(outDir);
17574
+ deps.debug?.start({
17575
+ flow: "import",
17576
+ step: "06-extraction",
17577
+ menuOption: "Import",
17578
+ inputs: {
17579
+ projectPath: input.projectPath,
17580
+ agent: input.agent,
17581
+ files: input.filePaths.length,
17582
+ noCache: input.noCache
17583
+ }
17584
+ });
17585
+ const result = await extract(input, outDir, onProgress, deps);
17586
+ await deps.debug?.finish(
17587
+ result.ok ? { outputs: { sessionId: result.extraction.sessionId, outDir }, status: "success", exitMethod: "saved" } : { outputs: { step: result.step, message: result.message }, status: "error", exitMethod: "discarded" }
17588
+ );
17589
+ return result;
17590
+ }
17591
+ async function extract(input, outDir, onProgress, deps) {
17344
17592
  let progress = initialProgress({
17345
17593
  hasCredentials: input.credentials !== null,
17346
17594
  hasRawTokens: input.rawTokensPath !== "",
@@ -17435,7 +17683,7 @@ async function runExtraction(input, onProgress, deps = realDeps) {
17435
17683
  const extraction = {
17436
17684
  sessionId: extracted.sessionId,
17437
17685
  outDir,
17438
- tokensPath: tokens?.ok ? tokens.tokensPath : hasTokenSource ? join19(outDir, "tokens.json") : "",
17686
+ tokensPath: tokens?.ok ? tokens.tokensPath : hasTokenSource ? join20(outDir, "tokens.json") : "",
17439
17687
  tokenSessionId: tokens?.ok ? tokens.tokenSessionId : null,
17440
17688
  tokenCount: tokens?.ok ? tokens.tokenCount : 0,
17441
17689
  existingEntitiesPath,
@@ -17446,7 +17694,7 @@ async function runExtraction(input, onProgress, deps = realDeps) {
17446
17694
  }
17447
17695
  async function fetchEntities(credentials, outDir) {
17448
17696
  try {
17449
- await mkdir7(outDir, { recursive: true });
17697
+ await mkdir8(outDir, { recursive: true });
17450
17698
  const result = await fetchAndPersistExistingContentfulEntities({
17451
17699
  spaceId: credentials.spaceId,
17452
17700
  environmentId: credentials.environmentId,
@@ -17466,7 +17714,7 @@ async function resolveSelectionPrompt(overrides) {
17466
17714
  if (select?.kind === "text") return { promptText: select.value };
17467
17715
  if (select?.kind === "path") {
17468
17716
  await resolvePromptOverride(select);
17469
- return { promptPath: resolve22(select.value) };
17717
+ return { promptPath: resolve23(select.value) };
17470
17718
  }
17471
17719
  return {};
17472
17720
  }
@@ -20375,7 +20623,7 @@ function GenerationScreen({
20375
20623
  import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
20376
20624
 
20377
20625
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
20378
- import { resolve as resolve23 } from "node:path";
20626
+ import { resolve as resolve24 } from "node:path";
20379
20627
 
20380
20628
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
20381
20629
  async function prepareMapTokens(input, generatedSessionId) {
@@ -20510,7 +20758,7 @@ async function buildMapTokensOptions(input) {
20510
20758
  if (mapOverride?.kind === "text") prompt.skillContentOverride = mapOverride.value;
20511
20759
  if (mapOverride?.kind === "path") {
20512
20760
  await resolvePromptOverride(mapOverride);
20513
- prompt.skillPathOverride = resolve23(mapOverride.value);
20761
+ prompt.skillPathOverride = resolve24(mapOverride.value);
20514
20762
  }
20515
20763
  if (input.existingEntitiesPath) {
20516
20764
  const entities = await readExistingContentfulEntitiesFromSession({ path: input.existingEntitiesPath });
@@ -20558,7 +20806,7 @@ function useGeneration(input) {
20558
20806
  }
20559
20807
 
20560
20808
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
20561
- import { join as join20 } from "node:path";
20809
+ import { join as join21 } from "node:path";
20562
20810
  function buildFlowStart(input) {
20563
20811
  const { extraction, handoff, saved, generatePromptPath } = input;
20564
20812
  const credentials = extraction.credentials ?? {
@@ -20571,7 +20819,7 @@ function buildFlowStart(input) {
20571
20819
  handoff,
20572
20820
  agent: extraction.agent,
20573
20821
  projectPath: extraction.projectPath,
20574
- outDir: extraction.projectPath ? join20(extraction.projectPath, ".contentful") : "",
20822
+ outDir: extraction.projectPath ? join21(extraction.projectPath, ".contentful") : "",
20575
20823
  rawTokensPath: extraction.rawTokensPath,
20576
20824
  credentials: {
20577
20825
  spaceId: credentials.spaceId,
@@ -20584,6 +20832,7 @@ function buildFlowStart(input) {
20584
20832
  }
20585
20833
 
20586
20834
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/screen.tsx
20835
+ import { useEffect as useEffect20, useRef as useRef12 } from "react";
20587
20836
  import { Box as Box41 } from "ink";
20588
20837
 
20589
20838
  // packages/experience-design-system-types/dist/src/cdf/validate.js
@@ -26313,11 +26562,11 @@ function DoneStep({
26313
26562
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/PathPrompt.tsx
26314
26563
  import { useState as useState24 } from "react";
26315
26564
  import { Box as Box37, Text as Text40 } from "ink";
26316
- import { readdirSync as readdirSync3 } from "node:fs";
26317
- import { dirname as dirname15, basename as basename6, join as join21 } from "node:path";
26565
+ import { readdirSync as readdirSync4 } from "node:fs";
26566
+ import { dirname as dirname15, basename as basename6, join as join22 } from "node:path";
26318
26567
 
26319
26568
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts
26320
- import { resolve as resolve24 } from "node:path";
26569
+ import { resolve as resolve25 } from "node:path";
26321
26570
  import { homedir as homedir4 } from "node:os";
26322
26571
  function expandTilde(input) {
26323
26572
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -26331,7 +26580,7 @@ function normalizePath(input) {
26331
26580
  p = p.slice(1, -1);
26332
26581
  }
26333
26582
  p = expandTilde(p);
26334
- return resolve24(p);
26583
+ return resolve25(p);
26335
26584
  }
26336
26585
 
26337
26586
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
@@ -26354,19 +26603,19 @@ function autocomplete(partial) {
26354
26603
  const base = basename6(normalized);
26355
26604
  let entries;
26356
26605
  try {
26357
- entries = readdirSync3(dir);
26606
+ entries = readdirSync4(dir);
26358
26607
  } catch {
26359
26608
  return null;
26360
26609
  }
26361
26610
  const matches = entries.filter((e) => e.startsWith(base));
26362
26611
  if (matches.length === 0) return null;
26363
- if (matches.length === 1) return join21(dir, matches[0]);
26612
+ if (matches.length === 1) return join22(dir, matches[0]);
26364
26613
  let prefix = matches[0];
26365
26614
  for (const m of matches) {
26366
26615
  while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
26367
26616
  if (!prefix) break;
26368
26617
  }
26369
- return prefix.length > base.length ? join21(dir, prefix) : null;
26618
+ return prefix.length > base.length ? join22(dir, prefix) : null;
26370
26619
  }
26371
26620
  function PathPrompt({
26372
26621
  defaultPath,
@@ -26984,10 +27233,18 @@ function FlowScreen({
26984
27233
  controller,
26985
27234
  livePreview = true,
26986
27235
  generatePromptPath,
26987
- onExit
27236
+ onExit,
27237
+ onStepChange
26988
27238
  }) {
26989
27239
  const totalSteps = totalStepsFor(state);
26990
27240
  const quit = () => onExit(0);
27241
+ const previousStep = useRef12(state.step);
27242
+ useEffect20(() => {
27243
+ if (previousStep.current !== state.step) {
27244
+ onStepChange?.();
27245
+ previousStep.current = state.step;
27246
+ }
27247
+ }, [state.step, onStepChange]);
26991
27248
  const content = (() => {
26992
27249
  switch (state.step) {
26993
27250
  case "final-review":
@@ -27113,13 +27370,13 @@ function FlowScreen({
27113
27370
  }
27114
27371
 
27115
27372
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
27116
- import { useEffect as useEffect20, useRef as useRef12, useSyncExternalStore } from "react";
27373
+ import { useEffect as useEffect21, useRef as useRef13, useSyncExternalStore } from "react";
27117
27374
 
27118
27375
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27119
27376
  import { appendFileSync, writeFileSync } from "node:fs";
27120
- import { mkdir as mkdir8 } from "node:fs/promises";
27377
+ import { mkdir as mkdir9 } from "node:fs/promises";
27121
27378
  import { tmpdir } from "node:os";
27122
- import { join as join23 } from "node:path";
27379
+ import { join as join24 } from "node:path";
27123
27380
 
27124
27381
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27125
27382
  function shouldBypassPreview(state) {
@@ -27463,8 +27720,8 @@ function pushFailure(e, deps) {
27463
27720
  }
27464
27721
 
27465
27722
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/save.ts
27466
- import { writeFile as writeFile7 } from "node:fs/promises";
27467
- import { join as join22 } from "node:path";
27723
+ import { writeFile as writeFile8 } from "node:fs/promises";
27724
+ import { join as join23 } from "node:path";
27468
27725
 
27469
27726
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/run-print-files-helpers.ts
27470
27727
  function nextStateAfterPrint(opts) {
@@ -27487,15 +27744,15 @@ function buildSavedCDF(components, tokens, opts = {}) {
27487
27744
  var realSaveDeps = () => ({
27488
27745
  openDb: openPipelineDb,
27489
27746
  readTokens: (path5) => readTokensFromPath2({ flag: "tokens", path: path5 }),
27490
- writeFile: (path5, contents) => writeFile7(path5, contents),
27747
+ writeFile: (path5, contents) => writeFile8(path5, contents),
27491
27748
  appendRun,
27492
27749
  buildSourceFingerprint,
27493
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27750
+ sleep: (ms) => new Promise((resolve26) => setTimeout(resolve26, ms)),
27494
27751
  warn: (message) => process.stderr.write(message)
27495
27752
  });
27496
27753
  async function runPrintFiles(input, deps, onPatch) {
27497
27754
  onPatch({ step: "printing" });
27498
- const componentsPath = join22(input.outDir, "components.json");
27755
+ const componentsPath = join23(input.outDir, "components.json");
27499
27756
  try {
27500
27757
  const db = deps.openDb();
27501
27758
  let components = [];
@@ -27576,7 +27833,7 @@ var EMPTY_PUSH_RESULT = {
27576
27833
  };
27577
27834
 
27578
27835
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27579
- var WIZARD_LOG = join23(tmpdir(), "experiences-import-wizard.log");
27836
+ var WIZARD_LOG = join24(tmpdir(), "experiences-import-wizard.log");
27580
27837
  function appendWizardLog(entry) {
27581
27838
  appendFileSync(WIZARD_LOG, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n");
27582
27839
  }
@@ -27599,13 +27856,14 @@ function realFlowDeps() {
27599
27856
  }
27600
27857
  },
27601
27858
  mkdir: async (path5) => {
27602
- await mkdir8(path5, { recursive: true });
27859
+ await mkdir9(path5, { recursive: true });
27603
27860
  },
27604
27861
  detectSaveConflict,
27605
27862
  buildTimestampedSubdir,
27606
27863
  rejectComponentsByName,
27607
27864
  log,
27608
- stderr: (text) => process.stderr.write(text)
27865
+ stderr: (text) => process.stderr.write(text),
27866
+ debug: realDebugHooks
27609
27867
  };
27610
27868
  }
27611
27869
  function initialFlowState(start) {
@@ -27703,12 +27961,6 @@ function createFlowController(start, deps) {
27703
27961
  deps.log({ update: sanitizeForLog(patch) });
27704
27962
  } catch {
27705
27963
  }
27706
- if (patch.step !== void 0 && patch.step !== state.step) {
27707
- try {
27708
- deps.beforeStepChange?.();
27709
- } catch {
27710
- }
27711
- }
27712
27964
  state = { ...state, ...patch };
27713
27965
  for (const listener of listeners) listener();
27714
27966
  };
@@ -27755,6 +28007,13 @@ function createFlowController(start, deps) {
27755
28007
  };
27756
28008
  const proceedToWrite = async (path5) => {
27757
28009
  update({ outDir: path5 });
28010
+ await deps.debug?.setOutDir(path5);
28011
+ deps.debug?.start({
28012
+ flow: "import",
28013
+ step: "10-flow",
28014
+ menuOption: "Save",
28015
+ inputs: { outDir: path5, extractSessionId: state.extractSessionId, andPush: !!pendingSave.andPush }
28016
+ });
27758
28017
  const { skipGate, andPush } = pendingSave;
27759
28018
  const written = await runPrintFiles(
27760
28019
  {
@@ -27769,6 +28028,9 @@ function createFlowController(start, deps) {
27769
28028
  update
27770
28029
  );
27771
28030
  update(written.patch);
28031
+ await deps.debug?.finish(
28032
+ written.ok ? { outputs: { componentsPath: join24(path5, "components.json") }, status: "success", exitMethod: "saved" } : { outputs: { error: written.patch.errorMessage ?? "unknown" }, status: "error", exitMethod: "discarded" }
28033
+ );
27772
28034
  if (!written.ok) return;
27773
28035
  const runId = await recordRun({ state, savePath: path5 }, deps.save);
27774
28036
  if (runId) update({ lastRunId: runId });
@@ -27846,198 +28108,44 @@ function createFlowController(start, deps) {
27846
28108
  }
27847
28109
 
27848
28110
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/use-flow.ts
27849
- function useFlow(start, options = {}) {
27850
- const controller = useRef12();
28111
+ function useFlow(start, deps = realFlowDeps) {
28112
+ const controller = useRef13();
27851
28113
  if (start && !controller.current) {
27852
28114
  try {
27853
28115
  startWizardLog();
27854
28116
  } catch {
27855
28117
  }
27856
- const flowDeps = (options.deps ?? realFlowDeps)();
27857
- controller.current = createFlowController(start, {
27858
- ...flowDeps,
27859
- ...options.beforeStepChange ? { beforeStepChange: options.beforeStepChange } : {}
27860
- });
28118
+ controller.current = createFlowController(start, deps());
27861
28119
  }
27862
28120
  const current = controller.current;
27863
28121
  const state = useSyncExternalStore(
27864
28122
  (listener) => current?.subscribe(listener) ?? (() => void 0),
27865
28123
  () => current?.getState()
27866
28124
  );
27867
- useEffect20(() => {
28125
+ useEffect21(() => {
27868
28126
  if (!start) controller.current = void 0;
27869
28127
  }, [start]);
27870
28128
  return current && state ? { controller: current, state } : void 0;
27871
28129
  }
27872
28130
 
27873
28131
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
27874
- import { useEffect as useEffect21, useState as useState27 } from "react";
28132
+ import { useEffect as useEffect22, useState as useState27 } from "react";
27875
28133
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
27876
-
27877
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27878
- import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
27879
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
27880
- import { join as join24 } from "node:path";
27881
-
27882
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
27883
- var DEFAULT_DEBUG_MODE_SETTING = {
27884
- enabled: true
27885
- };
27886
- async function readDebugModeSetting() {
27887
- const { debugMode } = await readSettings2();
27888
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
27889
- }
27890
- async function writeDebugModeSetting(setting) {
27891
- await updateSettings2({ debugMode: setting });
27892
- }
27893
-
27894
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27895
- var pendingRun;
27896
- function generateRunId() {
27897
- const now = /* @__PURE__ */ new Date();
27898
- const pad = (n) => String(n).padStart(2, "0");
27899
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
27900
- }
27901
- function datePrefix(now = /* @__PURE__ */ new Date()) {
27902
- const pad = (n) => String(n).padStart(2, "0");
27903
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
27904
- }
27905
- function slugify(value) {
27906
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
27907
- }
27908
- function generateSessionId3() {
27909
- const today = datePrefix();
27910
- const root = debugSessionsDir2();
27911
- const existing = existsSync9(root) ? readdirSync4(root) : [];
27912
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
27913
- const maxSeq = existing.reduce((max, entry) => {
27914
- const match2 = seqPattern.exec(entry);
27915
- return match2 ? Math.max(max, Number(match2[1])) : max;
27916
- }, 0);
27917
- return `${today}-session-${maxSeq + 1}`;
27918
- }
27919
- var SESSION_ID = generateSessionId3();
27920
- function sessionDebugDir() {
27921
- return join24(debugSessionsDir2(), SESSION_ID);
27922
- }
27923
- function currentDebugSessionDir() {
27924
- return sessionDebugDir();
27925
- }
27926
- void isDebugModeEnabled().then((enabled) => {
27927
- if (!enabled) return void 0;
27928
- return mkdir9(sessionDebugDir(), { recursive: true });
27929
- });
27930
- async function isDebugModeEnabled() {
27931
- try {
27932
- return (await readDebugModeSetting()).enabled;
27933
- } catch {
27934
- return true;
27935
- }
27936
- }
27937
- function redact(value) {
27938
- const clone = { ...value };
27939
- if ("cma_token" in clone) {
27940
- const raw = clone.cma_token;
27941
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
27942
- }
27943
- return clone;
27944
- }
27945
- function startDebugRun({
27946
- flow,
27947
- step,
27948
- menuOption,
27949
- inputs
27950
- }) {
27951
- const runId = generateRunId();
27952
- const startedAt = Date.now();
27953
- const redactedInputs = redact(inputs);
27954
- isDebugModeEnabled().then((enabled) => {
27955
- if (!enabled) return;
27956
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
27957
- });
27958
- }
27959
- async function finishDebugRun({
27960
- outputs,
27961
- status,
27962
- exitMethod
27963
- }) {
27964
- const run = pendingRun;
27965
- if (!run) return;
27966
- pendingRun = void 0;
27967
- const durationMs = Date.now() - run.startedAt;
27968
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
27969
- const flowSegments = run.flow.split("/");
27970
- const dir = join24(sessionDebugDir(), ...flowSegments);
27971
- await mkdir9(dir, { recursive: true });
27972
- const filename = nextAttemptFilename(dir, run.menuOption);
27973
- await writeFile8(join24(dir, filename), content, { mode: 384 });
27974
- }
27975
- function nextAttemptFilename(dir, menuOption) {
27976
- const today = datePrefix();
27977
- const optionSlug = slugify(menuOption);
27978
- const existing = existsSync9(dir) ? readdirSync4(dir) : [];
27979
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
27980
- const maxAttempt = existing.reduce((max, entry) => {
27981
- const match2 = attemptPattern.exec(entry);
27982
- return match2 ? Math.max(max, Number(match2[1])) : max;
27983
- }, 0);
27984
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
27985
- }
27986
- function renderMarkdown(run, finish) {
27987
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
27988
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
27989
- const flowSlug = run.flow.split("/").join("-");
27990
- return `# Debug Log
27991
-
27992
- - Run ID: ${run.runId}
27993
- - Flow: ${flowSlug}
27994
- - Step: ${stepLabel2}
27995
- - Menu option: ${run.menuOption}
27996
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
27997
- - CLI version: ${readPackageVersion()}
27998
- - Platform: ${process.platform} / Node ${process.version}
27999
- - Duration on screen: ${finish.durationMs}ms
28000
- - Status: ${finish.status}
28001
- - Exit method: ${finish.exitMethod}
28002
-
28003
- ## Inputs
28004
- \`\`\`json
28005
- ${JSON.stringify(run.inputs, null, 2)}
28006
- \`\`\`
28007
-
28008
- ## Outputs
28009
- \`\`\`json
28010
- ${JSON.stringify(finish.outputs, null, 2)}
28011
- \`\`\`
28012
- `;
28013
- }
28014
- function handleCrash() {
28015
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28016
- }
28017
- process.once("uncaughtException", (err) => {
28018
- void handleCrash().finally(() => {
28019
- throw err;
28020
- });
28021
- });
28022
- process.once("unhandledRejection", (reason) => {
28023
- void handleCrash().finally(() => {
28024
- throw reason;
28025
- });
28026
- });
28027
- process.once("SIGINT", () => {
28028
- void handleCrash().finally(() => {
28029
- process.exit(130);
28030
- });
28031
- });
28134
+ init_debug_store();
28032
28135
 
28033
28136
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28137
+ init_config();
28138
+ init_debug_store();
28139
+ init_debug_mode_store();
28140
+ init_version();
28034
28141
  async function readHelpInfo() {
28035
28142
  const debugMode = await readDebugModeSetting();
28036
28143
  return {
28037
28144
  storage: [
28038
28145
  { label: "Config folder", value: configRoot2() },
28039
28146
  { label: "Settings file", value: configFilePath2() },
28040
- { label: "Debug logs", value: debugSessionsDir2() }
28147
+ { label: "Debug logs", value: "<project>/.contentful/debug/sessions, next to components.json" },
28148
+ { label: "No project", value: `${debugSessionsDir2()} (sessions that never pick a project)` }
28041
28149
  ],
28042
28150
  troubleshooting: [
28043
28151
  { label: "CLI version", value: readPackageVersion() },
@@ -28065,7 +28173,7 @@ function Section({ title, rows }) {
28065
28173
  }
28066
28174
  function HelpScreen({ onDone }) {
28067
28175
  const [info, setInfo] = useState27();
28068
- useEffect21(() => {
28176
+ useEffect22(() => {
28069
28177
  startDebugRun({ flow: "help", step: "01-help", menuOption: "Help", inputs: {} });
28070
28178
  void readHelpInfo().then(setInfo);
28071
28179
  }, []);
@@ -28158,11 +28266,12 @@ function SettingsScreen({
28158
28266
  }
28159
28267
 
28160
28268
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28161
- import { useEffect as useEffect22, useState as useState29 } from "react";
28269
+ import { useEffect as useEffect23, useState as useState29 } from "react";
28162
28270
  import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28163
28271
  import TextInput4 from "ink-text-input";
28164
28272
 
28165
28273
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28274
+ init_config();
28166
28275
  var readV1Store = readSettings2;
28167
28276
  var writeV1Store = writeSettings2;
28168
28277
 
@@ -28191,6 +28300,7 @@ async function writeCredentials(config) {
28191
28300
  }
28192
28301
 
28193
28302
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28303
+ init_debug_store();
28194
28304
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28195
28305
  var FIELD_ORDER = [
28196
28306
  "spaceId",
@@ -28226,7 +28336,7 @@ function ConfigurationScreen({ onDone }) {
28226
28336
  const [lastSaved, setLastSaved] = useState29(null);
28227
28337
  const [editing, setEditing] = useState29(false);
28228
28338
  const [valueBeforeEdit, setValueBeforeEdit] = useState29("");
28229
- useEffect22(() => {
28339
+ useEffect23(() => {
28230
28340
  readCredentials().then((cfg) => {
28231
28341
  setConfig(cfg);
28232
28342
  setStage("form");
@@ -28363,7 +28473,7 @@ function ConfigurationScreen({ onDone }) {
28363
28473
  }
28364
28474
 
28365
28475
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28366
- import { useEffect as useEffect23, useState as useState30 } from "react";
28476
+ import { useEffect as useEffect24, useState as useState30 } from "react";
28367
28477
  import { Box as Box45, Text as Text47, useInput as useInput12 } from "ink";
28368
28478
 
28369
28479
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
@@ -28382,11 +28492,12 @@ async function writeAnalyticsSetting(setting) {
28382
28492
  }
28383
28493
 
28384
28494
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28495
+ init_debug_store();
28385
28496
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28386
28497
  function OptInAnalyticsScreen({ onDone }) {
28387
28498
  const [loading, setLoading] = useState30(true);
28388
28499
  const [enabled, setEnabled] = useState30(true);
28389
- useEffect23(() => {
28500
+ useEffect24(() => {
28390
28501
  readAnalyticsSetting().then((setting) => {
28391
28502
  setEnabled(setting.enabled);
28392
28503
  setLoading(false);
@@ -28440,13 +28551,15 @@ function OptInAnalyticsScreen({ onDone }) {
28440
28551
  }
28441
28552
 
28442
28553
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28443
- import { useEffect as useEffect24, useState as useState31 } from "react";
28554
+ import { useEffect as useEffect25, useState as useState31 } from "react";
28444
28555
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28556
+ init_version();
28557
+ init_debug_store();
28445
28558
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28446
28559
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28447
28560
  function UpgradeScreen({ onDone }) {
28448
28561
  const [upgradeCheck, setUpgradeCheck] = useState31();
28449
- useEffect24(() => {
28562
+ useEffect25(() => {
28450
28563
  startDebugRun({
28451
28564
  flow: "upgrade",
28452
28565
  step: "01-upgrade",
@@ -28511,13 +28624,15 @@ function renderBody(upgradeCheck) {
28511
28624
  }
28512
28625
 
28513
28626
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28514
- import { useEffect as useEffect25, useState as useState32 } from "react";
28627
+ import { useEffect as useEffect26, useState as useState32 } from "react";
28515
28628
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28629
+ init_debug_mode_store();
28630
+ init_debug_store();
28516
28631
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28517
28632
  function DebugModeScreen({ onDone }) {
28518
28633
  const [loading, setLoading] = useState32(true);
28519
28634
  const [enabled, setEnabled] = useState32(true);
28520
- useEffect25(() => {
28635
+ useEffect26(() => {
28521
28636
  readDebugModeSetting().then((setting) => {
28522
28637
  setEnabled(setting.enabled);
28523
28638
  setLoading(false);
@@ -28595,9 +28710,9 @@ function App({ importOptions, inkClear }) {
28595
28710
  const [generationInput, setGenerationInput] = useState33();
28596
28711
  const generation = useGeneration(generationInput);
28597
28712
  const [flowStart, setFlowStart] = useState33();
28598
- const flow = useFlow(flowStart, { beforeStepChange: inkClear });
28713
+ const flow = useFlow(flowStart);
28599
28714
  const [importDefaults, setImportDefaults] = useState33();
28600
- useEffect26(() => {
28715
+ useEffect27(() => {
28601
28716
  if (screen !== "import") {
28602
28717
  setImportDefaults(void 0);
28603
28718
  return;
@@ -28655,12 +28770,12 @@ function App({ importOptions, inkClear }) {
28655
28770
  }
28656
28771
  });
28657
28772
  };
28658
- useEffect26(() => {
28773
+ useEffect27(() => {
28659
28774
  if (!extractionRun || extraction?.status !== "done" || !extraction.result.ok) return;
28660
28775
  setExtractionRun(void 0);
28661
28776
  setScopeRun({ ...extractionRun, extraction: extraction.result.extraction });
28662
28777
  }, [extraction, extractionRun]);
28663
- useEffect26(() => {
28778
+ useEffect27(() => {
28664
28779
  if (!scopeRun || scopeFlow?.status !== "confirmed" || generationInput) return;
28665
28780
  const { extraction: produced, input, generatePromptPath } = scopeRun;
28666
28781
  setGenerationInput({
@@ -28678,7 +28793,7 @@ function App({ importOptions, inkClear }) {
28678
28793
  ...generatePromptPath ? { generatePromptPath } : {}
28679
28794
  });
28680
28795
  }, [scopeFlow, scopeRun, generationInput]);
28681
- useEffect26(() => {
28796
+ useEffect27(() => {
28682
28797
  if (!scopeRun || generation?.status !== "done" || !generation.result.ok) return;
28683
28798
  const { credentialsSkipped, tokenStrategy, extraction: produced, input, generatePromptPath } = scopeRun;
28684
28799
  inkClear();
@@ -28729,7 +28844,8 @@ function App({ importOptions, inkClear }) {
28729
28844
  state: flow.state,
28730
28845
  controller: flow.controller,
28731
28846
  generatePromptPath: flowStart.generatePromptPath,
28732
- onExit: setImportExitCode
28847
+ onExit: setImportExitCode,
28848
+ onStepChange: inkClear
28733
28849
  }
28734
28850
  );
28735
28851
  }