@contentful/experience-design-system-cli 2.37.1-dev-build-ced30421.0 → 2.37.1-dev-build-a2454a09.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,6 +2081,233 @@ 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;
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
+ finishDebugRun: () => finishDebugRun,
2142
+ startDebugRun: () => startDebugRun,
2143
+ startDebugSessionIn: () => startDebugSessionIn
2144
+ });
2145
+ import { mkdir as mkdir8, writeFile as writeFile7 } from "node:fs/promises";
2146
+ import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
2147
+ import { join as join20, resolve as resolve23 } from "node:path";
2148
+ function generateRunId() {
2149
+ const now = /* @__PURE__ */ new Date();
2150
+ const pad = (n) => String(n).padStart(2, "0");
2151
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
2152
+ }
2153
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
2154
+ const pad = (n) => String(n).padStart(2, "0");
2155
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
2156
+ }
2157
+ function slugify(value) {
2158
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2159
+ }
2160
+ async function readBaseDir() {
2161
+ try {
2162
+ const dir = (await readSettings2())["contentfulBaseDir"];
2163
+ return typeof dir === "string" && dir !== "" ? resolve23(dir) : void 0;
2164
+ } catch {
2165
+ return void 0;
2166
+ }
2167
+ }
2168
+ function nextSessionId(contentfulDir) {
2169
+ const today = datePrefix();
2170
+ const existing = existsSync9(contentfulDir) ? readdirSync3(contentfulDir) : [];
2171
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2172
+ const maxSeq = existing.reduce((max, entry) => {
2173
+ const match2 = seqPattern.exec(entry);
2174
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2175
+ }, 0);
2176
+ return `${today}-session-${maxSeq + 1}`;
2177
+ }
2178
+ function startSession(base, { replace }) {
2179
+ const contentfulDir = join20(base, ".contentful");
2180
+ if (replace || !sessionDir) sessionDir = join20(contentfulDir, nextSessionId(contentfulDir));
2181
+ return sessionDir;
2182
+ }
2183
+ function currentDebugSessionDir() {
2184
+ return sessionDir && join20(sessionDir, "debug");
2185
+ }
2186
+ async function startDebugSessionIn(base, { replace = false } = {}) {
2187
+ try {
2188
+ if (!await isDebugModeEnabled()) return;
2189
+ await mkdir8(join20(startSession(resolve23(base), { replace }), "debug"), { recursive: true });
2190
+ } catch {
2191
+ }
2192
+ }
2193
+ async function isDebugModeEnabled() {
2194
+ try {
2195
+ return (await readDebugModeSetting()).enabled;
2196
+ } catch {
2197
+ return true;
2198
+ }
2199
+ }
2200
+ function redact(value) {
2201
+ const clone = { ...value };
2202
+ if ("cma_token" in clone) {
2203
+ const raw = clone.cma_token;
2204
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2205
+ }
2206
+ return clone;
2207
+ }
2208
+ function startDebugRun({
2209
+ flow,
2210
+ step,
2211
+ menuOption,
2212
+ inputs
2213
+ }) {
2214
+ const runId = generateRunId();
2215
+ const startedAt = Date.now();
2216
+ const redactedInputs = redact(inputs);
2217
+ isDebugModeEnabled().then((enabled) => {
2218
+ if (!enabled) return;
2219
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2220
+ });
2221
+ }
2222
+ async function finishDebugRun({
2223
+ outputs,
2224
+ status,
2225
+ exitMethod
2226
+ }) {
2227
+ const run = pendingRun;
2228
+ if (!run) return;
2229
+ pendingRun = void 0;
2230
+ const durationMs = Date.now() - run.startedAt;
2231
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2232
+ const root = currentDebugSessionDir();
2233
+ if (!root) return;
2234
+ const flowSegments = run.flow.split("/");
2235
+ const dir = join20(root, ...flowSegments);
2236
+ await mkdir8(dir, { recursive: true });
2237
+ const filename = nextAttemptFilename(dir, run.menuOption);
2238
+ await writeFile7(join20(dir, filename), content, { mode: 384 });
2239
+ }
2240
+ function nextAttemptFilename(dir, menuOption) {
2241
+ const today = datePrefix();
2242
+ const optionSlug = slugify(menuOption);
2243
+ const existing = existsSync9(dir) ? readdirSync3(dir) : [];
2244
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2245
+ const maxAttempt = existing.reduce((max, entry) => {
2246
+ const match2 = attemptPattern.exec(entry);
2247
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2248
+ }, 0);
2249
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2250
+ }
2251
+ function renderMarkdown(run, finish) {
2252
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2253
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2254
+ const flowSlug = run.flow.split("/").join("-");
2255
+ return `# Debug Log
2256
+
2257
+ - Run ID: ${run.runId}
2258
+ - Flow: ${flowSlug}
2259
+ - Step: ${stepLabel2}
2260
+ - Menu option: ${run.menuOption}
2261
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2262
+ - CLI version: ${readPackageVersion()}
2263
+ - Platform: ${process.platform} / Node ${process.version}
2264
+ - Duration on screen: ${finish.durationMs}ms
2265
+ - Status: ${finish.status}
2266
+ - Exit method: ${finish.exitMethod}
2267
+
2268
+ ## Inputs
2269
+ \`\`\`json
2270
+ ${JSON.stringify(run.inputs, null, 2)}
2271
+ \`\`\`
2272
+
2273
+ ## Outputs
2274
+ \`\`\`json
2275
+ ${JSON.stringify(finish.outputs, null, 2)}
2276
+ \`\`\`
2277
+ `;
2278
+ }
2279
+ function handleCrash() {
2280
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2281
+ }
2282
+ var pendingRun, sessionDir;
2283
+ var init_debug_store = __esm({
2284
+ "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2285
+ "use strict";
2286
+ init_config();
2287
+ init_version();
2288
+ init_debug_mode_store();
2289
+ void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
2290
+ if (!enabled || !base) return void 0;
2291
+ return mkdir8(join20(startSession(base, { replace: false }), "debug"), { recursive: true });
2292
+ });
2293
+ process.once("uncaughtException", (err) => {
2294
+ void handleCrash().finally(() => {
2295
+ throw err;
2296
+ });
2297
+ });
2298
+ process.once("unhandledRejection", (reason) => {
2299
+ void handleCrash().finally(() => {
2300
+ throw reason;
2301
+ });
2302
+ });
2303
+ process.once("SIGINT", () => {
2304
+ void handleCrash().finally(() => {
2305
+ process.exit(130);
2306
+ });
2307
+ });
2308
+ }
2309
+ });
2310
+
2019
2311
  // packages/experience-design-system-cli/app.tsx
2020
2312
  import { join as join25 } from "node:path";
2021
2313
  import { useEffect as useEffect27, useState as useState33 } from "react";
@@ -2055,60 +2347,8 @@ function brandBar(width, ramp = BRAND_RAMP) {
2055
2347
  }
2056
2348
  var FOCUS_MARKER = "\u276F";
2057
2349
 
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
- }
2350
+ // packages/experience-design-system-cli/src/tui/home/home.tsx
2351
+ init_version();
2112
2352
 
2113
2353
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2114
2354
  import { useEffect, useState } from "react";
@@ -4365,30 +4605,8 @@ function applyScopeDecisions(db, sessionId, decisions) {
4365
4605
  const placeholders = accepted.map(() => "?").join(",");
4366
4606
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
4367
4607
  }
4368
- removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
4369
4608
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
4370
4609
  }
4371
- function removeSlotAllowedComponents(db, sessionId, edges, rejectedNames) {
4372
- if (edges.length === 0 && rejectedNames.length === 0)
4373
- return;
4374
- const componentId = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
4375
- const removeEdge = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND allowed_component = ?");
4376
- const removeEverywhere = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND allowed_component = ?");
4377
- db.exec("BEGIN");
4378
- try {
4379
- for (const edge of edges) {
4380
- const row = componentId.get(sessionId, edge.parent);
4381
- if (row)
4382
- removeEdge.run(sessionId, row.component_id, edge.child);
4383
- }
4384
- for (const name of rejectedNames)
4385
- removeEverywhere.run(sessionId, name);
4386
- db.exec("COMMIT");
4387
- } catch (e) {
4388
- db.exec("ROLLBACK");
4389
- throw e;
4390
- }
4391
- }
4392
4610
  function findLatestSessionForCommand(db, command) {
4393
4611
  return getLatestCompletedSessionForCommand(db, command);
4394
4612
  }
@@ -12329,11 +12547,11 @@ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node
12329
12547
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
12330
12548
  import { resolve as resolve15 } from "node:path";
12331
12549
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
12332
- const sessionDir = resolve15(artifactsRoot, sessionId);
12550
+ const sessionDir2 = resolve15(artifactsRoot, sessionId);
12333
12551
  return {
12334
- sessionDir,
12335
- eventsPath: resolve15(sessionDir, "events.jsonl"),
12336
- statePath: resolve15(sessionDir, "current-review-state.json")
12552
+ sessionDir: sessionDir2,
12553
+ eventsPath: resolve15(sessionDir2, "events.jsonl"),
12554
+ statePath: resolve15(sessionDir2, "current-review-state.json")
12337
12555
  };
12338
12556
  }
12339
12557
 
@@ -13532,7 +13750,7 @@ function errorMessage(error) {
13532
13750
  return error instanceof Error && error.message ? error.message : String(error);
13533
13751
  }
13534
13752
  function defaultSleep(delayMs) {
13535
- return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13753
+ return new Promise((resolve26) => setTimeout(resolve26, delayMs));
13536
13754
  }
13537
13755
 
13538
13756
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -13773,7 +13991,7 @@ var ApiClient = class {
13773
13991
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13774
13992
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13775
13993
  const jitter = Math.random() * baseDelay * 0.15;
13776
- await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
13994
+ await new Promise((resolve26) => setTimeout(resolve26, baseDelay + jitter));
13777
13995
  }
13778
13996
  }
13779
13997
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -15886,7 +16104,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
15886
16104
  const message = error instanceof Error ? error.message : String(error);
15887
16105
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
15888
16106
  throw error;
15889
- await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16107
+ await new Promise((resolve26) => setTimeout(resolve26, Math.min(250 * attempt, 2e3)));
15890
16108
  }
15891
16109
  }
15892
16110
  }
@@ -16713,6 +16931,7 @@ function useCredentialsControls(handlers) {
16713
16931
  }
16714
16932
 
16715
16933
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16934
+ init_version();
16716
16935
  function cliUserAgent() {
16717
16936
  return buildUserAgent(readPackageVersion());
16718
16937
  }
@@ -17212,34 +17431,8 @@ function ExtractionScreen({
17212
17431
  );
17213
17432
  }
17214
17433
 
17215
- // packages/experience-design-system-types/dist/src/config/index.js
17216
- import { randomBytes as randomBytes3 } from "node:crypto";
17217
- import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
17218
- import { homedir as homedir3 } from "node:os";
17219
- import { dirname as dirname13, join as join17 } from "node:path";
17220
- function configRoot2() {
17221
- return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
17222
- }
17223
- var configFilePath2 = () => join17(configRoot2(), "config.json");
17224
- var debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
17225
- async function readSettings2() {
17226
- try {
17227
- return JSON.parse(await readFile18(configFilePath2(), "utf8"));
17228
- } catch {
17229
- return {};
17230
- }
17231
- }
17232
- async function writeSettings2(settings) {
17233
- const path5 = configFilePath2();
17234
- await mkdir6(dirname13(path5), { recursive: true });
17235
- const tmp = `${path5}.${process.pid}.${randomBytes3(4).toString("hex")}.tmp`;
17236
- await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
17237
- `, { mode: 384 });
17238
- await rename2(tmp, path5);
17239
- }
17240
- async function updateSettings2(patch) {
17241
- await writeSettings2({ ...await readSettings2(), ...patch });
17242
- }
17434
+ // packages/experience-design-system-cli/app.tsx
17435
+ init_config();
17243
17436
 
17244
17437
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17245
17438
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
@@ -17515,6 +17708,7 @@ function useExtraction(input) {
17515
17708
  reuseTokens: input.tokenStrategy === "reuse"
17516
17709
  })
17517
17710
  });
17711
+ void Promise.resolve().then(() => (init_debug_store(), debug_store_exports)).then((store) => store.startDebugSessionIn(input.projectPath));
17518
17712
  void runExtraction(input, (progress) => {
17519
17713
  if (current.current === input) setState({ status: "running", progress });
17520
17714
  }).then((result) => {
@@ -18396,7 +18590,7 @@ function buildVisibleRows(props) {
18396
18590
  if (visited.has(target)) continue;
18397
18591
  visited.add(target);
18398
18592
  const isCycleMember = cycleParticipants.has(target);
18399
- out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
18593
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
18400
18594
  queue.push({ name: target, depth: cur.depth + 1 });
18401
18595
  }
18402
18596
  }
@@ -18443,8 +18637,7 @@ function buildVisibleRows(props) {
18443
18637
  sharedSuffix,
18444
18638
  cycleChild: child.isCycleMember || void 0,
18445
18639
  itemIdx: childRec?.idx ?? -1,
18446
- rootName: key,
18447
- parentName: child.parent
18640
+ rootName: key
18448
18641
  });
18449
18642
  });
18450
18643
  }
@@ -18527,19 +18720,13 @@ function buildVisibleRows(props) {
18527
18720
  injectedChildren.push({
18528
18721
  name: target,
18529
18722
  depth: parentDepth + 1,
18530
- isCycleChild: true,
18531
- parent: parentName
18723
+ isCycleChild: true
18532
18724
  });
18533
18725
  }
18534
18726
  };
18535
18727
  emitCycleChildrenOf(root, 0);
18536
18728
  for (const c2 of closureChildren) {
18537
- injectedChildren.push({
18538
- name: c2.name,
18539
- depth: c2.depth,
18540
- isCycleChild: false,
18541
- parent: c2.path[c2.path.length - 2] ?? root
18542
- });
18729
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
18543
18730
  emitCycleChildrenOf(c2.name, c2.depth);
18544
18731
  }
18545
18732
  const isLastAtDepth = (idx) => {
@@ -18573,8 +18760,7 @@ function buildVisibleRows(props) {
18573
18760
  sharedSuffix,
18574
18761
  cycleChild: child.isCycleChild || void 0,
18575
18762
  itemIdx: childRec?.idx ?? -1,
18576
- rootName: root,
18577
- parentName: child.parent
18763
+ rootName: root
18578
18764
  });
18579
18765
  });
18580
18766
  }
@@ -18727,7 +18913,7 @@ function GroupedSidebar(props) {
18727
18913
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
18728
18914
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
18729
18915
  const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
18730
- const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "empty" || row.kind === "cycle");
18916
+ const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "cycle");
18731
18917
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
18732
18918
  const isCycleRow = row.kind === "cycle";
18733
18919
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -18757,7 +18943,7 @@ function GroupedSidebar(props) {
18757
18943
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
18758
18944
  bold: isSelected || labelStyle.bold,
18759
18945
  inverse: false,
18760
- underline: isSelected && focused,
18946
+ underline: isSelected && !focused,
18761
18947
  wrap: wrapLabels ? "wrap" : "truncate",
18762
18948
  children: [
18763
18949
  " ",
@@ -19416,7 +19602,6 @@ function resolveKey(mode, key, ctx) {
19416
19602
  function resolveMain(key, ctx) {
19417
19603
  const { input } = key;
19418
19604
  const inMain = ctx.focusedColumn === "main";
19419
- if (key.ctrl && input === "z") return { type: "undo" };
19420
19605
  if (input === "q" || key.escape) {
19421
19606
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
19422
19607
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -19675,42 +19860,21 @@ function rejectNeedsConfirmation(graph, name, state) {
19675
19860
  const ancestors = toReject.filter((n) => n !== name);
19676
19861
  return ancestors.length + toDeselect.length >= 2;
19677
19862
  }
19678
- function removeSlotChild(components, edge) {
19679
- return components.map(
19680
- (component) => component.name === edge.parent ? {
19681
- ...component,
19682
- slots: component.slots?.map((slot) => ({
19683
- ...slot,
19684
- allowedComponents: slot.allowedComponents.filter((name) => name !== edge.child)
19685
- }))
19686
- } : component
19687
- );
19688
- }
19689
- function withoutSlotChildren(components, removedEdges) {
19690
- return removedEdges.reduce(removeSlotChild, components);
19691
- }
19692
- function partitionDecisions(components, state, removedEdges) {
19863
+ function partitionDecisions(components, state) {
19693
19864
  const accepted = [];
19694
19865
  const rejected = [];
19695
19866
  for (const c2 of components) {
19696
19867
  if (state.get(c2.name) === "accepted") accepted.push(c2.name);
19697
19868
  else rejected.push(c2.name);
19698
19869
  }
19699
- const rejectedNames = new Set(rejected);
19700
- const excludedSlotEdges = removedEdges.filter((e) => !rejectedNames.has(e.parent) && !rejectedNames.has(e.child));
19701
- return { accepted, rejected, excludedSlotEdges };
19870
+ return { accepted, rejected };
19702
19871
  }
19703
19872
 
19704
19873
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
19705
- function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19874
+ function useScopeGate({ components, onConfirm, onQuit }) {
19706
19875
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
19707
19876
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
19708
19877
  const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
19709
- const [removedEdges, setRemovedEdges] = useState12([]);
19710
- const components = useMemo2(
19711
- () => withoutSlotChildren(loadedComponents, removedEdges),
19712
- [loadedComponents, removedEdges]
19713
- );
19714
19878
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
19715
19879
  const [focusedColumn, setFocusedColumn] = useState12("main");
19716
19880
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -19882,14 +20046,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19882
20046
  return void 0;
19883
20047
  }
19884
20048
  };
19885
- const focusedNestedEdge = () => {
19886
- const row = visibleRows[safeCursor];
19887
- if (row?.kind !== "group-child" || !row.parentName || row.itemIdx < 0) return void 0;
19888
- const child = groupedItems[row.itemIdx]?.key;
19889
- return child ? { parent: row.parentName, child } : void 0;
19890
- };
19891
- const removeFromParentSlot = (edge) => setRemovedEdges((edges) => [...edges, edge]);
19892
- const undoSlotRemoval = () => setRemovedEdges((edges) => edges.slice(0, -1));
19893
20049
  const jumpCursorTo = (name) => {
19894
20050
  let idx = -1;
19895
20051
  for (let i = 0; i < visibleRows.length; i++) {
@@ -19989,7 +20145,7 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19989
20145
  onQuit();
19990
20146
  return;
19991
20147
  case "confirm":
19992
- onConfirm(partitionDecisions(components, decisions, removedEdges));
20148
+ onConfirm(partitionDecisions(components, decisions));
19993
20149
  return;
19994
20150
  case "close-help":
19995
20151
  setShowHelp(false);
@@ -20042,11 +20198,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20042
20198
  return;
20043
20199
  }
20044
20200
  case "reject": {
20045
- const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
20046
- if (edge) {
20047
- removeFromParentSlot(edge);
20048
- return;
20049
- }
20050
20201
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
20051
20202
  if (key) requestReject(key);
20052
20203
  return;
@@ -20054,9 +20205,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20054
20205
  case "toggle-all":
20055
20206
  decide({ type: "toggle-all" });
20056
20207
  return;
20057
- case "undo":
20058
- undoSlotRemoval();
20059
- return;
20060
20208
  case "accept-unflagged":
20061
20209
  decide({ type: "accept-unflagged" });
20062
20210
  return;
@@ -20447,7 +20595,7 @@ function GenerationScreen({
20447
20595
  import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
20448
20596
 
20449
20597
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
20450
- import { resolve as resolve23 } from "node:path";
20598
+ import { resolve as resolve24 } from "node:path";
20451
20599
 
20452
20600
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
20453
20601
  async function prepareMapTokens(input, generatedSessionId) {
@@ -20582,7 +20730,7 @@ async function buildMapTokensOptions(input) {
20582
20730
  if (mapOverride?.kind === "text") prompt.skillContentOverride = mapOverride.value;
20583
20731
  if (mapOverride?.kind === "path") {
20584
20732
  await resolvePromptOverride(mapOverride);
20585
- prompt.skillPathOverride = resolve23(mapOverride.value);
20733
+ prompt.skillPathOverride = resolve24(mapOverride.value);
20586
20734
  }
20587
20735
  if (input.existingEntitiesPath) {
20588
20736
  const entities = await readExistingContentfulEntitiesFromSession({ path: input.existingEntitiesPath });
@@ -20630,7 +20778,7 @@ function useGeneration(input) {
20630
20778
  }
20631
20779
 
20632
20780
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
20633
- import { join as join20 } from "node:path";
20781
+ import { join as join21 } from "node:path";
20634
20782
  function buildFlowStart(input) {
20635
20783
  const { extraction, handoff, saved, generatePromptPath } = input;
20636
20784
  const credentials = extraction.credentials ?? {
@@ -20643,7 +20791,7 @@ function buildFlowStart(input) {
20643
20791
  handoff,
20644
20792
  agent: extraction.agent,
20645
20793
  projectPath: extraction.projectPath,
20646
- outDir: extraction.projectPath ? join20(extraction.projectPath, ".contentful") : "",
20794
+ outDir: extraction.projectPath ? join21(extraction.projectPath, ".contentful") : "",
20647
20795
  rawTokensPath: extraction.rawTokensPath,
20648
20796
  credentials: {
20649
20797
  spaceId: credentials.spaceId,
@@ -22699,8 +22847,8 @@ function FieldEditor({
22699
22847
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE3.warning, children: [
22700
22848
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE3.warning, children: "FIELD EDITOR \u2014 no fields" }),
22701
22849
  /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify." }),
22702
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "There is nothing to edit here." }),
22703
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: active ? "[Esc] go back to the list" : "In the list: [r] reject this component \xB7 [a] accept it" })
22850
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "You can add fields manually below or reject this component." }),
22851
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "Enter to save \xB7 Esc to discard" })
22704
22852
  ] });
22705
22853
  }
22706
22854
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -22915,7 +23063,7 @@ function FieldEditor({
22915
23063
  children: [
22916
23064
  hasEmptyProperties && /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify. Reject this component or add fields manually." }),
22917
23065
  header,
22918
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
23066
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
22919
23067
  PropRow,
22920
23068
  {
22921
23069
  prop: currentProp,
@@ -23824,7 +23972,6 @@ function finalizeReviewSession(extractSessionId, components) {
23824
23972
  db.exec("ROLLBACK");
23825
23973
  throw error;
23826
23974
  }
23827
- removeSlotAllowedComponents(db, extractSessionId, [], toReject);
23828
23975
  } finally {
23829
23976
  db.close();
23830
23977
  }
@@ -25556,50 +25703,33 @@ function GenerateReviewStepView({
25556
25703
  const cycle = cycleRows[cyclesCursor];
25557
25704
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
25558
25705
  }, [cycleRows, cyclesCursor, components]);
25559
- const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
25706
+ const handleBreakEdge = (edge) => {
25707
+ const target = components.find((component) => component.key === edge.fromComponent);
25708
+ const slot = target?.entry.$slots?.[edge.slotName];
25709
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
25710
+ const nextEntry = {
25711
+ ...target.entry,
25712
+ $slots: {
25713
+ ...target.entry.$slots,
25714
+ [edge.slotName]: {
25715
+ ...slot,
25716
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
25717
+ }
25718
+ }
25719
+ };
25560
25720
  const next = components.map(
25561
- (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
25721
+ (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
25562
25722
  );
25563
25723
  setComponents(next);
25564
25724
  const db = openPipelineDb();
25565
25725
  try {
25566
- storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
25726
+ storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
25567
25727
  } finally {
25568
25728
  db.close();
25569
25729
  }
25570
25730
  recomputeCycles(next);
25571
25731
  livePreviewHook.trigger();
25572
- pushHistorySnapshot(next, historyLabel);
25573
- };
25574
- const handleBreakEdge = (edge) => {
25575
- const target = components.find((component) => component.key === edge.fromComponent);
25576
- const slot = target?.entry.$slots?.[edge.slotName];
25577
- if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
25578
- saveSlotChange(
25579
- target.key,
25580
- {
25581
- ...target.entry,
25582
- $slots: {
25583
- ...target.entry.$slots,
25584
- [edge.slotName]: {
25585
- ...slot,
25586
- $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
25587
- }
25588
- }
25589
- },
25590
- "break-cycle-edge"
25591
- );
25592
- };
25593
- const handleRemoveSlotChild = (parentKey, childKey) => {
25594
- const parent = components.find((component) => component.key === parentKey);
25595
- if (!parent?.entry.$slots) return;
25596
- const slots = Object.fromEntries(
25597
- Object.entries(parent.entry.$slots).map(([slotName, slot]) => [
25598
- slotName,
25599
- Array.isArray(slot.$allowedComponents) ? { ...slot, $allowedComponents: slot.$allowedComponents.filter((value) => value !== childKey) } : slot
25600
- ])
25601
- );
25602
- saveSlotChange(parentKey, { ...parent.entry, $slots: slots }, "remove-slot-child");
25732
+ pushHistorySnapshot(next, "break-cycle-edge");
25603
25733
  };
25604
25734
  const handleRejectComponent = (key) => {
25605
25735
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -25929,11 +26059,6 @@ function GenerateReviewStepView({
25929
26059
  if (input === "r") {
25930
26060
  const current = components[selectedIdx];
25931
26061
  if (!current) return;
25932
- const row = visibleRowsMemo[cursorRowIdx];
25933
- if (row?.kind === "group-child" && row.parentName) {
25934
- handleRemoveSlotChild(row.parentName, current.key);
25935
- return;
25936
- }
25937
26062
  handleRejectComponent(current.key);
25938
26063
  return;
25939
26064
  }
@@ -26409,11 +26534,11 @@ function DoneStep({
26409
26534
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/PathPrompt.tsx
26410
26535
  import { useState as useState24 } from "react";
26411
26536
  import { Box as Box37, Text as Text40 } from "ink";
26412
- import { readdirSync as readdirSync3 } from "node:fs";
26413
- import { dirname as dirname15, basename as basename6, join as join21 } from "node:path";
26537
+ import { readdirSync as readdirSync4 } from "node:fs";
26538
+ import { dirname as dirname15, basename as basename6, join as join22 } from "node:path";
26414
26539
 
26415
26540
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts
26416
- import { resolve as resolve24 } from "node:path";
26541
+ import { resolve as resolve25 } from "node:path";
26417
26542
  import { homedir as homedir4 } from "node:os";
26418
26543
  function expandTilde(input) {
26419
26544
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -26427,7 +26552,7 @@ function normalizePath(input) {
26427
26552
  p = p.slice(1, -1);
26428
26553
  }
26429
26554
  p = expandTilde(p);
26430
- return resolve24(p);
26555
+ return resolve25(p);
26431
26556
  }
26432
26557
 
26433
26558
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
@@ -26450,19 +26575,19 @@ function autocomplete(partial) {
26450
26575
  const base = basename6(normalized);
26451
26576
  let entries;
26452
26577
  try {
26453
- entries = readdirSync3(dir);
26578
+ entries = readdirSync4(dir);
26454
26579
  } catch {
26455
26580
  return null;
26456
26581
  }
26457
26582
  const matches = entries.filter((e) => e.startsWith(base));
26458
26583
  if (matches.length === 0) return null;
26459
- if (matches.length === 1) return join21(dir, matches[0]);
26584
+ if (matches.length === 1) return join22(dir, matches[0]);
26460
26585
  let prefix = matches[0];
26461
26586
  for (const m of matches) {
26462
26587
  while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
26463
26588
  if (!prefix) break;
26464
26589
  }
26465
- return prefix.length > base.length ? join21(dir, prefix) : null;
26590
+ return prefix.length > base.length ? join22(dir, prefix) : null;
26466
26591
  }
26467
26592
  function PathPrompt({
26468
26593
  defaultPath,
@@ -27221,9 +27346,9 @@ import { useEffect as useEffect21, useRef as useRef13, useSyncExternalStore } fr
27221
27346
 
27222
27347
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27223
27348
  import { appendFileSync, writeFileSync } from "node:fs";
27224
- import { mkdir as mkdir8 } from "node:fs/promises";
27349
+ import { mkdir as mkdir9 } from "node:fs/promises";
27225
27350
  import { tmpdir } from "node:os";
27226
- import { join as join23 } from "node:path";
27351
+ import { join as join24 } from "node:path";
27227
27352
 
27228
27353
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27229
27354
  function shouldBypassPreview(state) {
@@ -27567,8 +27692,8 @@ function pushFailure(e, deps) {
27567
27692
  }
27568
27693
 
27569
27694
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/save.ts
27570
- import { writeFile as writeFile7 } from "node:fs/promises";
27571
- import { join as join22 } from "node:path";
27695
+ import { writeFile as writeFile8 } from "node:fs/promises";
27696
+ import { join as join23 } from "node:path";
27572
27697
 
27573
27698
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/run-print-files-helpers.ts
27574
27699
  function nextStateAfterPrint(opts) {
@@ -27591,15 +27716,15 @@ function buildSavedCDF(components, tokens, opts = {}) {
27591
27716
  var realSaveDeps = () => ({
27592
27717
  openDb: openPipelineDb,
27593
27718
  readTokens: (path5) => readTokensFromPath2({ flag: "tokens", path: path5 }),
27594
- writeFile: (path5, contents) => writeFile7(path5, contents),
27719
+ writeFile: (path5, contents) => writeFile8(path5, contents),
27595
27720
  appendRun,
27596
27721
  buildSourceFingerprint,
27597
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27722
+ sleep: (ms) => new Promise((resolve26) => setTimeout(resolve26, ms)),
27598
27723
  warn: (message) => process.stderr.write(message)
27599
27724
  });
27600
27725
  async function runPrintFiles(input, deps, onPatch) {
27601
27726
  onPatch({ step: "printing" });
27602
- const componentsPath = join22(input.outDir, "components.json");
27727
+ const componentsPath = join23(input.outDir, "components.json");
27603
27728
  try {
27604
27729
  const db = deps.openDb();
27605
27730
  let components = [];
@@ -27680,7 +27805,7 @@ var EMPTY_PUSH_RESULT = {
27680
27805
  };
27681
27806
 
27682
27807
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27683
- var WIZARD_LOG = join23(tmpdir(), "experiences-import-wizard.log");
27808
+ var WIZARD_LOG = join24(tmpdir(), "experiences-import-wizard.log");
27684
27809
  function appendWizardLog(entry) {
27685
27810
  appendFileSync(WIZARD_LOG, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n");
27686
27811
  }
@@ -27703,7 +27828,7 @@ function realFlowDeps() {
27703
27828
  }
27704
27829
  },
27705
27830
  mkdir: async (path5) => {
27706
- await mkdir8(path5, { recursive: true });
27831
+ await mkdir9(path5, { recursive: true });
27707
27832
  },
27708
27833
  detectSaveConflict,
27709
27834
  buildTimestampedSubdir,
@@ -27967,171 +28092,19 @@ function useFlow(start, deps = realFlowDeps) {
27967
28092
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
27968
28093
  import { useEffect as useEffect22, useState as useState27 } from "react";
27969
28094
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
27970
-
27971
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27972
- import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
27973
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
27974
- import { join as join24 } from "node:path";
27975
-
27976
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
27977
- var DEFAULT_DEBUG_MODE_SETTING = {
27978
- enabled: true
27979
- };
27980
- async function readDebugModeSetting() {
27981
- const { debugMode } = await readSettings2();
27982
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
27983
- }
27984
- async function writeDebugModeSetting(setting) {
27985
- await updateSettings2({ debugMode: setting });
27986
- }
27987
-
27988
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27989
- var pendingRun;
27990
- function generateRunId() {
27991
- const now = /* @__PURE__ */ new Date();
27992
- const pad = (n) => String(n).padStart(2, "0");
27993
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
27994
- }
27995
- function datePrefix(now = /* @__PURE__ */ new Date()) {
27996
- const pad = (n) => String(n).padStart(2, "0");
27997
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
27998
- }
27999
- function slugify(value) {
28000
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
28001
- }
28002
- function generateSessionId3() {
28003
- const today = datePrefix();
28004
- const root = debugSessionsDir2();
28005
- const existing = existsSync9(root) ? readdirSync4(root) : [];
28006
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
28007
- const maxSeq = existing.reduce((max, entry) => {
28008
- const match2 = seqPattern.exec(entry);
28009
- return match2 ? Math.max(max, Number(match2[1])) : max;
28010
- }, 0);
28011
- return `${today}-session-${maxSeq + 1}`;
28012
- }
28013
- var SESSION_ID = generateSessionId3();
28014
- function sessionDebugDir() {
28015
- return join24(debugSessionsDir2(), SESSION_ID);
28016
- }
28017
- function currentDebugSessionDir() {
28018
- return sessionDebugDir();
28019
- }
28020
- void isDebugModeEnabled().then((enabled) => {
28021
- if (!enabled) return void 0;
28022
- return mkdir9(sessionDebugDir(), { recursive: true });
28023
- });
28024
- async function isDebugModeEnabled() {
28025
- try {
28026
- return (await readDebugModeSetting()).enabled;
28027
- } catch {
28028
- return true;
28029
- }
28030
- }
28031
- function redact(value) {
28032
- const clone = { ...value };
28033
- if ("cma_token" in clone) {
28034
- const raw = clone.cma_token;
28035
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
28036
- }
28037
- return clone;
28038
- }
28039
- function startDebugRun({
28040
- flow,
28041
- step,
28042
- menuOption,
28043
- inputs
28044
- }) {
28045
- const runId = generateRunId();
28046
- const startedAt = Date.now();
28047
- const redactedInputs = redact(inputs);
28048
- isDebugModeEnabled().then((enabled) => {
28049
- if (!enabled) return;
28050
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
28051
- });
28052
- }
28053
- async function finishDebugRun({
28054
- outputs,
28055
- status,
28056
- exitMethod
28057
- }) {
28058
- const run = pendingRun;
28059
- if (!run) return;
28060
- pendingRun = void 0;
28061
- const durationMs = Date.now() - run.startedAt;
28062
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
28063
- const flowSegments = run.flow.split("/");
28064
- const dir = join24(sessionDebugDir(), ...flowSegments);
28065
- await mkdir9(dir, { recursive: true });
28066
- const filename = nextAttemptFilename(dir, run.menuOption);
28067
- await writeFile8(join24(dir, filename), content, { mode: 384 });
28068
- }
28069
- function nextAttemptFilename(dir, menuOption) {
28070
- const today = datePrefix();
28071
- const optionSlug = slugify(menuOption);
28072
- const existing = existsSync9(dir) ? readdirSync4(dir) : [];
28073
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
28074
- const maxAttempt = existing.reduce((max, entry) => {
28075
- const match2 = attemptPattern.exec(entry);
28076
- return match2 ? Math.max(max, Number(match2[1])) : max;
28077
- }, 0);
28078
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
28079
- }
28080
- function renderMarkdown(run, finish) {
28081
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
28082
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
28083
- const flowSlug = run.flow.split("/").join("-");
28084
- return `# Debug Log
28085
-
28086
- - Run ID: ${run.runId}
28087
- - Flow: ${flowSlug}
28088
- - Step: ${stepLabel2}
28089
- - Menu option: ${run.menuOption}
28090
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
28091
- - CLI version: ${readPackageVersion()}
28092
- - Platform: ${process.platform} / Node ${process.version}
28093
- - Duration on screen: ${finish.durationMs}ms
28094
- - Status: ${finish.status}
28095
- - Exit method: ${finish.exitMethod}
28096
-
28097
- ## Inputs
28098
- \`\`\`json
28099
- ${JSON.stringify(run.inputs, null, 2)}
28100
- \`\`\`
28101
-
28102
- ## Outputs
28103
- \`\`\`json
28104
- ${JSON.stringify(finish.outputs, null, 2)}
28105
- \`\`\`
28106
- `;
28107
- }
28108
- function handleCrash() {
28109
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28110
- }
28111
- process.once("uncaughtException", (err) => {
28112
- void handleCrash().finally(() => {
28113
- throw err;
28114
- });
28115
- });
28116
- process.once("unhandledRejection", (reason) => {
28117
- void handleCrash().finally(() => {
28118
- throw reason;
28119
- });
28120
- });
28121
- process.once("SIGINT", () => {
28122
- void handleCrash().finally(() => {
28123
- process.exit(130);
28124
- });
28125
- });
28095
+ init_debug_store();
28126
28096
 
28127
28097
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28098
+ init_config();
28099
+ init_debug_store();
28100
+ init_debug_mode_store();
28101
+ init_version();
28128
28102
  async function readHelpInfo() {
28129
28103
  const debugMode = await readDebugModeSetting();
28130
28104
  return {
28131
28105
  storage: [
28132
28106
  { label: "Config folder", value: configRoot2() },
28133
- { label: "Settings file", value: configFilePath2() },
28134
- { label: "Debug logs", value: debugSessionsDir2() }
28107
+ { label: "Settings file", value: configFilePath2() }
28135
28108
  ],
28136
28109
  troubleshooting: [
28137
28110
  { label: "CLI version", value: readPackageVersion() },
@@ -28140,7 +28113,7 @@ async function readHelpInfo() {
28140
28113
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28141
28114
  {
28142
28115
  label: "This session",
28143
- value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28116
+ value: !debugMode.enabled ? "no logs written while Debug Mode is off" : currentDebugSessionDir() ?? "not started: set the default project directory in Settings, or start an import"
28144
28117
  }
28145
28118
  ]
28146
28119
  };
@@ -28257,6 +28230,7 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28257
28230
  import TextInput4 from "ink-text-input";
28258
28231
 
28259
28232
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28233
+ init_config();
28260
28234
  var readV1Store = readSettings2;
28261
28235
  var writeV1Store = writeSettings2;
28262
28236
 
@@ -28269,7 +28243,8 @@ async function readCredentials() {
28269
28243
  cmaToken: store.cmaToken || "",
28270
28244
  host: store.host || "",
28271
28245
  defaultComponentDir: store.defaultComponentDir || "",
28272
- defaultTokenFile: store.defaultTokenFile || ""
28246
+ defaultTokenFile: store.defaultTokenFile || "",
28247
+ contentfulBaseDir: store.contentfulBaseDir || ""
28273
28248
  };
28274
28249
  }
28275
28250
  async function writeCredentials(config) {
@@ -28285,6 +28260,7 @@ async function writeCredentials(config) {
28285
28260
  }
28286
28261
 
28287
28262
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28263
+ init_debug_store();
28288
28264
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28289
28265
  var FIELD_ORDER = [
28290
28266
  "spaceId",
@@ -28292,7 +28268,8 @@ var FIELD_ORDER = [
28292
28268
  "cmaToken",
28293
28269
  "host",
28294
28270
  "defaultComponentDir",
28295
- "defaultTokenFile"
28271
+ "defaultTokenFile",
28272
+ "contentfulBaseDir"
28296
28273
  ];
28297
28274
  function debugFields(config) {
28298
28275
  return {
@@ -28301,7 +28278,8 @@ function debugFields(config) {
28301
28278
  cma_token: config?.cmaToken ?? "",
28302
28279
  host: config?.host ?? "",
28303
28280
  default_component_dir: config?.defaultComponentDir ?? "",
28304
- default_token_file: config?.defaultTokenFile ?? ""
28281
+ default_token_file: config?.defaultTokenFile ?? "",
28282
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
28305
28283
  };
28306
28284
  }
28307
28285
  var FIELD_LABELS = {
@@ -28310,7 +28288,8 @@ var FIELD_LABELS = {
28310
28288
  cmaToken: "CMA Token",
28311
28289
  host: "API Host (optional)",
28312
28290
  defaultComponentDir: "Default component directory (optional)",
28313
- defaultTokenFile: "Default token file (optional)"
28291
+ defaultTokenFile: "Default token file (optional)",
28292
+ contentfulBaseDir: "Default project directory, where .contentful goes (optional)"
28314
28293
  };
28315
28294
  function ConfigurationScreen({ onDone }) {
28316
28295
  const [stage, setStage] = useState29("loading");
@@ -28347,6 +28326,7 @@ function ConfigurationScreen({ onDone }) {
28347
28326
  setNotice(null);
28348
28327
  writeCredentials(config).then(() => {
28349
28328
  setLastSaved(config);
28329
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28350
28330
  setNotice({ kind: "success", text: "Configuration saved" });
28351
28331
  setStage("form");
28352
28332
  }).catch((err) => {
@@ -28476,6 +28456,7 @@ async function writeAnalyticsSetting(setting) {
28476
28456
  }
28477
28457
 
28478
28458
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28459
+ init_debug_store();
28479
28460
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28480
28461
  function OptInAnalyticsScreen({ onDone }) {
28481
28462
  const [loading, setLoading] = useState30(true);
@@ -28536,6 +28517,8 @@ function OptInAnalyticsScreen({ onDone }) {
28536
28517
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28537
28518
  import { useEffect as useEffect25, useState as useState31 } from "react";
28538
28519
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28520
+ init_version();
28521
+ init_debug_store();
28539
28522
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28540
28523
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28541
28524
  function UpgradeScreen({ onDone }) {
@@ -28607,6 +28590,8 @@ function renderBody(upgradeCheck) {
28607
28590
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28608
28591
  import { useEffect as useEffect26, useState as useState32 } from "react";
28609
28592
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28593
+ init_debug_mode_store();
28594
+ init_debug_store();
28610
28595
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28611
28596
  function DebugModeScreen({ onDone }) {
28612
28597
  const [loading, setLoading] = useState32(true);