@contentful/experience-design-system-cli 2.37.1-dev-build-ced30421.0 → 2.37.1-dev-build-4ce44f69.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,237 @@ 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
+ currentSessionDir: () => currentSessionDir,
2142
+ finishDebugRun: () => finishDebugRun,
2143
+ startDebugRun: () => startDebugRun,
2144
+ startDebugSessionIn: () => startDebugSessionIn
2145
+ });
2146
+ import { mkdir as mkdir8, writeFile as writeFile7 } from "node:fs/promises";
2147
+ import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
2148
+ import { join as join20, resolve as resolve23 } 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
+ async function readBaseDir() {
2162
+ try {
2163
+ const dir = (await readSettings2())["contentfulBaseDir"];
2164
+ return typeof dir === "string" && dir !== "" ? resolve23(dir) : void 0;
2165
+ } catch {
2166
+ return void 0;
2167
+ }
2168
+ }
2169
+ function nextSessionId(contentfulDir) {
2170
+ const today = datePrefix();
2171
+ const existing = existsSync9(contentfulDir) ? readdirSync3(contentfulDir) : [];
2172
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2173
+ const maxSeq = existing.reduce((max, entry) => {
2174
+ const match2 = seqPattern.exec(entry);
2175
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2176
+ }, 0);
2177
+ return `${today}-session-${maxSeq + 1}`;
2178
+ }
2179
+ function startSession(base, { replace }) {
2180
+ const contentfulDir = join20(base, ".contentful");
2181
+ if (replace || !sessionDir) sessionDir = join20(contentfulDir, nextSessionId(contentfulDir));
2182
+ return sessionDir;
2183
+ }
2184
+ function currentDebugSessionDir() {
2185
+ return sessionDir && join20(sessionDir, "debug");
2186
+ }
2187
+ function currentSessionDir() {
2188
+ return sessionDir;
2189
+ }
2190
+ async function startDebugSessionIn(base, { replace = false } = {}) {
2191
+ try {
2192
+ if (!await isDebugModeEnabled()) return;
2193
+ await mkdir8(join20(startSession(resolve23(base), { replace }), "debug"), { recursive: true });
2194
+ } catch {
2195
+ }
2196
+ }
2197
+ async function isDebugModeEnabled() {
2198
+ try {
2199
+ return (await readDebugModeSetting()).enabled;
2200
+ } catch {
2201
+ return true;
2202
+ }
2203
+ }
2204
+ function redact(value) {
2205
+ const clone = { ...value };
2206
+ if ("cma_token" in clone) {
2207
+ const raw = clone.cma_token;
2208
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2209
+ }
2210
+ return clone;
2211
+ }
2212
+ function startDebugRun({
2213
+ flow,
2214
+ step,
2215
+ menuOption,
2216
+ inputs
2217
+ }) {
2218
+ const runId = generateRunId();
2219
+ const startedAt = Date.now();
2220
+ const redactedInputs = redact(inputs);
2221
+ isDebugModeEnabled().then((enabled) => {
2222
+ if (!enabled) return;
2223
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2224
+ });
2225
+ }
2226
+ async function finishDebugRun({
2227
+ outputs,
2228
+ status,
2229
+ exitMethod
2230
+ }) {
2231
+ const run = pendingRun;
2232
+ if (!run) return;
2233
+ pendingRun = void 0;
2234
+ const durationMs = Date.now() - run.startedAt;
2235
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2236
+ const root = currentDebugSessionDir();
2237
+ if (!root) return;
2238
+ const flowSegments = run.flow.split("/");
2239
+ const dir = join20(root, ...flowSegments);
2240
+ await mkdir8(dir, { recursive: true });
2241
+ const filename = nextAttemptFilename(dir, run.menuOption);
2242
+ await writeFile7(join20(dir, filename), content, { mode: 384 });
2243
+ }
2244
+ function nextAttemptFilename(dir, menuOption) {
2245
+ const today = datePrefix();
2246
+ const optionSlug = slugify(menuOption);
2247
+ const existing = existsSync9(dir) ? readdirSync3(dir) : [];
2248
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2249
+ const maxAttempt = existing.reduce((max, entry) => {
2250
+ const match2 = attemptPattern.exec(entry);
2251
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2252
+ }, 0);
2253
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2254
+ }
2255
+ function renderMarkdown(run, finish) {
2256
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2257
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2258
+ const flowSlug = run.flow.split("/").join("-");
2259
+ return `# Debug Log
2260
+
2261
+ - Run ID: ${run.runId}
2262
+ - Flow: ${flowSlug}
2263
+ - Step: ${stepLabel2}
2264
+ - Menu option: ${run.menuOption}
2265
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2266
+ - CLI version: ${readPackageVersion()}
2267
+ - Platform: ${process.platform} / Node ${process.version}
2268
+ - Duration on screen: ${finish.durationMs}ms
2269
+ - Status: ${finish.status}
2270
+ - Exit method: ${finish.exitMethod}
2271
+
2272
+ ## Inputs
2273
+ \`\`\`json
2274
+ ${JSON.stringify(run.inputs, null, 2)}
2275
+ \`\`\`
2276
+
2277
+ ## Outputs
2278
+ \`\`\`json
2279
+ ${JSON.stringify(finish.outputs, null, 2)}
2280
+ \`\`\`
2281
+ `;
2282
+ }
2283
+ function handleCrash() {
2284
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2285
+ }
2286
+ var pendingRun, sessionDir;
2287
+ var init_debug_store = __esm({
2288
+ "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2289
+ "use strict";
2290
+ init_config();
2291
+ init_version();
2292
+ init_debug_mode_store();
2293
+ void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
2294
+ if (!enabled || !base) return void 0;
2295
+ return mkdir8(join20(startSession(base, { replace: false }), "debug"), { recursive: true });
2296
+ });
2297
+ process.once("uncaughtException", (err) => {
2298
+ void handleCrash().finally(() => {
2299
+ throw err;
2300
+ });
2301
+ });
2302
+ process.once("unhandledRejection", (reason) => {
2303
+ void handleCrash().finally(() => {
2304
+ throw reason;
2305
+ });
2306
+ });
2307
+ process.once("SIGINT", () => {
2308
+ void handleCrash().finally(() => {
2309
+ process.exit(130);
2310
+ });
2311
+ });
2312
+ }
2313
+ });
2314
+
2019
2315
  // packages/experience-design-system-cli/app.tsx
2020
2316
  import { join as join25 } from "node:path";
2021
2317
  import { useEffect as useEffect27, useState as useState33 } from "react";
@@ -2055,60 +2351,8 @@ function brandBar(width, ramp = BRAND_RAMP) {
2055
2351
  }
2056
2352
  var FOCUS_MARKER = "\u276F";
2057
2353
 
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
- }
2354
+ // packages/experience-design-system-cli/src/tui/home/home.tsx
2355
+ init_version();
2112
2356
 
2113
2357
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2114
2358
  import { useEffect, useState } from "react";
@@ -4365,30 +4609,8 @@ function applyScopeDecisions(db, sessionId, decisions) {
4365
4609
  const placeholders = accepted.map(() => "?").join(",");
4366
4610
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
4367
4611
  }
4368
- removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
4369
4612
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
4370
4613
  }
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
4614
  function findLatestSessionForCommand(db, command) {
4393
4615
  return getLatestCompletedSessionForCommand(db, command);
4394
4616
  }
@@ -12329,11 +12551,11 @@ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node
12329
12551
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
12330
12552
  import { resolve as resolve15 } from "node:path";
12331
12553
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
12332
- const sessionDir = resolve15(artifactsRoot, sessionId);
12554
+ const sessionDir2 = resolve15(artifactsRoot, sessionId);
12333
12555
  return {
12334
- sessionDir,
12335
- eventsPath: resolve15(sessionDir, "events.jsonl"),
12336
- statePath: resolve15(sessionDir, "current-review-state.json")
12556
+ sessionDir: sessionDir2,
12557
+ eventsPath: resolve15(sessionDir2, "events.jsonl"),
12558
+ statePath: resolve15(sessionDir2, "current-review-state.json")
12337
12559
  };
12338
12560
  }
12339
12561
 
@@ -13532,7 +13754,7 @@ function errorMessage(error) {
13532
13754
  return error instanceof Error && error.message ? error.message : String(error);
13533
13755
  }
13534
13756
  function defaultSleep(delayMs) {
13535
- return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13757
+ return new Promise((resolve26) => setTimeout(resolve26, delayMs));
13536
13758
  }
13537
13759
 
13538
13760
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -13773,7 +13995,7 @@ var ApiClient = class {
13773
13995
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13774
13996
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13775
13997
  const jitter = Math.random() * baseDelay * 0.15;
13776
- await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
13998
+ await new Promise((resolve26) => setTimeout(resolve26, baseDelay + jitter));
13777
13999
  }
13778
14000
  }
13779
14001
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -15886,7 +16108,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
15886
16108
  const message = error instanceof Error ? error.message : String(error);
15887
16109
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
15888
16110
  throw error;
15889
- await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16111
+ await new Promise((resolve26) => setTimeout(resolve26, Math.min(250 * attempt, 2e3)));
15890
16112
  }
15891
16113
  }
15892
16114
  }
@@ -16713,6 +16935,7 @@ function useCredentialsControls(handlers) {
16713
16935
  }
16714
16936
 
16715
16937
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16938
+ init_version();
16716
16939
  function cliUserAgent() {
16717
16940
  return buildUserAgent(readPackageVersion());
16718
16941
  }
@@ -17212,34 +17435,8 @@ function ExtractionScreen({
17212
17435
  );
17213
17436
  }
17214
17437
 
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
- }
17438
+ // packages/experience-design-system-cli/app.tsx
17439
+ init_config();
17243
17440
 
17244
17441
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17245
17442
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
@@ -17515,6 +17712,7 @@ function useExtraction(input) {
17515
17712
  reuseTokens: input.tokenStrategy === "reuse"
17516
17713
  })
17517
17714
  });
17715
+ void Promise.resolve().then(() => (init_debug_store(), debug_store_exports)).then((store) => store.startDebugSessionIn(input.projectPath));
17518
17716
  void runExtraction(input, (progress) => {
17519
17717
  if (current.current === input) setState({ status: "running", progress });
17520
17718
  }).then((result) => {
@@ -18396,7 +18594,7 @@ function buildVisibleRows(props) {
18396
18594
  if (visited.has(target)) continue;
18397
18595
  visited.add(target);
18398
18596
  const isCycleMember = cycleParticipants.has(target);
18399
- out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
18597
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
18400
18598
  queue.push({ name: target, depth: cur.depth + 1 });
18401
18599
  }
18402
18600
  }
@@ -18443,8 +18641,7 @@ function buildVisibleRows(props) {
18443
18641
  sharedSuffix,
18444
18642
  cycleChild: child.isCycleMember || void 0,
18445
18643
  itemIdx: childRec?.idx ?? -1,
18446
- rootName: key,
18447
- parentName: child.parent
18644
+ rootName: key
18448
18645
  });
18449
18646
  });
18450
18647
  }
@@ -18527,19 +18724,13 @@ function buildVisibleRows(props) {
18527
18724
  injectedChildren.push({
18528
18725
  name: target,
18529
18726
  depth: parentDepth + 1,
18530
- isCycleChild: true,
18531
- parent: parentName
18727
+ isCycleChild: true
18532
18728
  });
18533
18729
  }
18534
18730
  };
18535
18731
  emitCycleChildrenOf(root, 0);
18536
18732
  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
- });
18733
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
18543
18734
  emitCycleChildrenOf(c2.name, c2.depth);
18544
18735
  }
18545
18736
  const isLastAtDepth = (idx) => {
@@ -18573,8 +18764,7 @@ function buildVisibleRows(props) {
18573
18764
  sharedSuffix,
18574
18765
  cycleChild: child.isCycleChild || void 0,
18575
18766
  itemIdx: childRec?.idx ?? -1,
18576
- rootName: root,
18577
- parentName: child.parent
18767
+ rootName: root
18578
18768
  });
18579
18769
  });
18580
18770
  }
@@ -18727,7 +18917,7 @@ function GroupedSidebar(props) {
18727
18917
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
18728
18918
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
18729
18919
  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");
18920
+ 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
18921
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
18732
18922
  const isCycleRow = row.kind === "cycle";
18733
18923
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -18757,7 +18947,7 @@ function GroupedSidebar(props) {
18757
18947
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
18758
18948
  bold: isSelected || labelStyle.bold,
18759
18949
  inverse: false,
18760
- underline: isSelected && focused,
18950
+ underline: isSelected && !focused,
18761
18951
  wrap: wrapLabels ? "wrap" : "truncate",
18762
18952
  children: [
18763
18953
  " ",
@@ -19416,7 +19606,6 @@ function resolveKey(mode, key, ctx) {
19416
19606
  function resolveMain(key, ctx) {
19417
19607
  const { input } = key;
19418
19608
  const inMain = ctx.focusedColumn === "main";
19419
- if (key.ctrl && input === "z") return { type: "undo" };
19420
19609
  if (input === "q" || key.escape) {
19421
19610
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
19422
19611
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -19675,42 +19864,21 @@ function rejectNeedsConfirmation(graph, name, state) {
19675
19864
  const ancestors = toReject.filter((n) => n !== name);
19676
19865
  return ancestors.length + toDeselect.length >= 2;
19677
19866
  }
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) {
19867
+ function partitionDecisions(components, state) {
19693
19868
  const accepted = [];
19694
19869
  const rejected = [];
19695
19870
  for (const c2 of components) {
19696
19871
  if (state.get(c2.name) === "accepted") accepted.push(c2.name);
19697
19872
  else rejected.push(c2.name);
19698
19873
  }
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 };
19874
+ return { accepted, rejected };
19702
19875
  }
19703
19876
 
19704
19877
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
19705
- function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19878
+ function useScopeGate({ components, onConfirm, onQuit }) {
19706
19879
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
19707
19880
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
19708
19881
  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
19882
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
19715
19883
  const [focusedColumn, setFocusedColumn] = useState12("main");
19716
19884
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -19882,14 +20050,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19882
20050
  return void 0;
19883
20051
  }
19884
20052
  };
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
20053
  const jumpCursorTo = (name) => {
19894
20054
  let idx = -1;
19895
20055
  for (let i = 0; i < visibleRows.length; i++) {
@@ -19989,7 +20149,7 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19989
20149
  onQuit();
19990
20150
  return;
19991
20151
  case "confirm":
19992
- onConfirm(partitionDecisions(components, decisions, removedEdges));
20152
+ onConfirm(partitionDecisions(components, decisions));
19993
20153
  return;
19994
20154
  case "close-help":
19995
20155
  setShowHelp(false);
@@ -20042,11 +20202,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20042
20202
  return;
20043
20203
  }
20044
20204
  case "reject": {
20045
- const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
20046
- if (edge) {
20047
- removeFromParentSlot(edge);
20048
- return;
20049
- }
20050
20205
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
20051
20206
  if (key) requestReject(key);
20052
20207
  return;
@@ -20054,9 +20209,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
20054
20209
  case "toggle-all":
20055
20210
  decide({ type: "toggle-all" });
20056
20211
  return;
20057
- case "undo":
20058
- undoSlotRemoval();
20059
- return;
20060
20212
  case "accept-unflagged":
20061
20213
  decide({ type: "accept-unflagged" });
20062
20214
  return;
@@ -20447,7 +20599,7 @@ function GenerationScreen({
20447
20599
  import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
20448
20600
 
20449
20601
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
20450
- import { resolve as resolve23 } from "node:path";
20602
+ import { resolve as resolve24 } from "node:path";
20451
20603
 
20452
20604
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
20453
20605
  async function prepareMapTokens(input, generatedSessionId) {
@@ -20582,7 +20734,7 @@ async function buildMapTokensOptions(input) {
20582
20734
  if (mapOverride?.kind === "text") prompt.skillContentOverride = mapOverride.value;
20583
20735
  if (mapOverride?.kind === "path") {
20584
20736
  await resolvePromptOverride(mapOverride);
20585
- prompt.skillPathOverride = resolve23(mapOverride.value);
20737
+ prompt.skillPathOverride = resolve24(mapOverride.value);
20586
20738
  }
20587
20739
  if (input.existingEntitiesPath) {
20588
20740
  const entities = await readExistingContentfulEntitiesFromSession({ path: input.existingEntitiesPath });
@@ -20630,7 +20782,7 @@ function useGeneration(input) {
20630
20782
  }
20631
20783
 
20632
20784
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
20633
- import { join as join20 } from "node:path";
20785
+ import { join as join21 } from "node:path";
20634
20786
  function buildFlowStart(input) {
20635
20787
  const { extraction, handoff, saved, generatePromptPath } = input;
20636
20788
  const credentials = extraction.credentials ?? {
@@ -20643,7 +20795,7 @@ function buildFlowStart(input) {
20643
20795
  handoff,
20644
20796
  agent: extraction.agent,
20645
20797
  projectPath: extraction.projectPath,
20646
- outDir: extraction.projectPath ? join20(extraction.projectPath, ".contentful") : "",
20798
+ outDir: extraction.projectPath ? join21(extraction.projectPath, ".contentful") : "",
20647
20799
  rawTokensPath: extraction.rawTokensPath,
20648
20800
  credentials: {
20649
20801
  spaceId: credentials.spaceId,
@@ -22699,8 +22851,8 @@ function FieldEditor({
22699
22851
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE3.warning, children: [
22700
22852
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE3.warning, children: "FIELD EDITOR \u2014 no fields" }),
22701
22853
  /* @__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" })
22854
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "You can add fields manually below or reject this component." }),
22855
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "Enter to save \xB7 Esc to discard" })
22704
22856
  ] });
22705
22857
  }
22706
22858
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -22915,7 +23067,7 @@ function FieldEditor({
22915
23067
  children: [
22916
23068
  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
23069
  header,
22918
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
23070
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
22919
23071
  PropRow,
22920
23072
  {
22921
23073
  prop: currentProp,
@@ -23824,7 +23976,6 @@ function finalizeReviewSession(extractSessionId, components) {
23824
23976
  db.exec("ROLLBACK");
23825
23977
  throw error;
23826
23978
  }
23827
- removeSlotAllowedComponents(db, extractSessionId, [], toReject);
23828
23979
  } finally {
23829
23980
  db.close();
23830
23981
  }
@@ -25556,50 +25707,33 @@ function GenerateReviewStepView({
25556
25707
  const cycle = cycleRows[cyclesCursor];
25557
25708
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
25558
25709
  }, [cycleRows, cyclesCursor, components]);
25559
- const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
25710
+ const handleBreakEdge = (edge) => {
25711
+ const target = components.find((component) => component.key === edge.fromComponent);
25712
+ const slot = target?.entry.$slots?.[edge.slotName];
25713
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
25714
+ const nextEntry = {
25715
+ ...target.entry,
25716
+ $slots: {
25717
+ ...target.entry.$slots,
25718
+ [edge.slotName]: {
25719
+ ...slot,
25720
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
25721
+ }
25722
+ }
25723
+ };
25560
25724
  const next = components.map(
25561
- (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
25725
+ (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
25562
25726
  );
25563
25727
  setComponents(next);
25564
25728
  const db = openPipelineDb();
25565
25729
  try {
25566
- storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
25730
+ storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
25567
25731
  } finally {
25568
25732
  db.close();
25569
25733
  }
25570
25734
  recomputeCycles(next);
25571
25735
  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");
25736
+ pushHistorySnapshot(next, "break-cycle-edge");
25603
25737
  };
25604
25738
  const handleRejectComponent = (key) => {
25605
25739
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -25929,11 +26063,6 @@ function GenerateReviewStepView({
25929
26063
  if (input === "r") {
25930
26064
  const current = components[selectedIdx];
25931
26065
  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
26066
  handleRejectComponent(current.key);
25938
26067
  return;
25939
26068
  }
@@ -26409,11 +26538,11 @@ function DoneStep({
26409
26538
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/PathPrompt.tsx
26410
26539
  import { useState as useState24 } from "react";
26411
26540
  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";
26541
+ import { readdirSync as readdirSync4 } from "node:fs";
26542
+ import { dirname as dirname15, basename as basename6, join as join22 } from "node:path";
26414
26543
 
26415
26544
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts
26416
- import { resolve as resolve24 } from "node:path";
26545
+ import { resolve as resolve25 } from "node:path";
26417
26546
  import { homedir as homedir4 } from "node:os";
26418
26547
  function expandTilde(input) {
26419
26548
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -26427,7 +26556,7 @@ function normalizePath(input) {
26427
26556
  p = p.slice(1, -1);
26428
26557
  }
26429
26558
  p = expandTilde(p);
26430
- return resolve24(p);
26559
+ return resolve25(p);
26431
26560
  }
26432
26561
 
26433
26562
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
@@ -26450,19 +26579,19 @@ function autocomplete(partial) {
26450
26579
  const base = basename6(normalized);
26451
26580
  let entries;
26452
26581
  try {
26453
- entries = readdirSync3(dir);
26582
+ entries = readdirSync4(dir);
26454
26583
  } catch {
26455
26584
  return null;
26456
26585
  }
26457
26586
  const matches = entries.filter((e) => e.startsWith(base));
26458
26587
  if (matches.length === 0) return null;
26459
- if (matches.length === 1) return join21(dir, matches[0]);
26588
+ if (matches.length === 1) return join22(dir, matches[0]);
26460
26589
  let prefix = matches[0];
26461
26590
  for (const m of matches) {
26462
26591
  while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
26463
26592
  if (!prefix) break;
26464
26593
  }
26465
- return prefix.length > base.length ? join21(dir, prefix) : null;
26594
+ return prefix.length > base.length ? join22(dir, prefix) : null;
26466
26595
  }
26467
26596
  function PathPrompt({
26468
26597
  defaultPath,
@@ -27221,9 +27350,9 @@ import { useEffect as useEffect21, useRef as useRef13, useSyncExternalStore } fr
27221
27350
 
27222
27351
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27223
27352
  import { appendFileSync, writeFileSync } from "node:fs";
27224
- import { mkdir as mkdir8 } from "node:fs/promises";
27353
+ import { mkdir as mkdir9 } from "node:fs/promises";
27225
27354
  import { tmpdir } from "node:os";
27226
- import { join as join23 } from "node:path";
27355
+ import { join as join24 } from "node:path";
27227
27356
 
27228
27357
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27229
27358
  function shouldBypassPreview(state) {
@@ -27567,8 +27696,8 @@ function pushFailure(e, deps) {
27567
27696
  }
27568
27697
 
27569
27698
  // 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";
27699
+ import { writeFile as writeFile8 } from "node:fs/promises";
27700
+ import { join as join23 } from "node:path";
27572
27701
 
27573
27702
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/run-print-files-helpers.ts
27574
27703
  function nextStateAfterPrint(opts) {
@@ -27591,15 +27720,15 @@ function buildSavedCDF(components, tokens, opts = {}) {
27591
27720
  var realSaveDeps = () => ({
27592
27721
  openDb: openPipelineDb,
27593
27722
  readTokens: (path5) => readTokensFromPath2({ flag: "tokens", path: path5 }),
27594
- writeFile: (path5, contents) => writeFile7(path5, contents),
27723
+ writeFile: (path5, contents) => writeFile8(path5, contents),
27595
27724
  appendRun,
27596
27725
  buildSourceFingerprint,
27597
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27726
+ sleep: (ms) => new Promise((resolve26) => setTimeout(resolve26, ms)),
27598
27727
  warn: (message) => process.stderr.write(message)
27599
27728
  });
27600
27729
  async function runPrintFiles(input, deps, onPatch) {
27601
27730
  onPatch({ step: "printing" });
27602
- const componentsPath = join22(input.outDir, "components.json");
27731
+ const componentsPath = join23(input.outDir, "components.json");
27603
27732
  try {
27604
27733
  const db = deps.openDb();
27605
27734
  let components = [];
@@ -27680,7 +27809,7 @@ var EMPTY_PUSH_RESULT = {
27680
27809
  };
27681
27810
 
27682
27811
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27683
- var WIZARD_LOG = join23(tmpdir(), "experiences-import-wizard.log");
27812
+ var WIZARD_LOG = join24(tmpdir(), "experiences-import-wizard.log");
27684
27813
  function appendWizardLog(entry) {
27685
27814
  appendFileSync(WIZARD_LOG, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n");
27686
27815
  }
@@ -27688,6 +27817,9 @@ function startWizardLog() {
27688
27817
  writeFileSync(WIZARD_LOG, `--- experiences import session ${(/* @__PURE__ */ new Date()).toISOString()} ---
27689
27818
  `);
27690
27819
  }
27820
+ async function realSessionDir() {
27821
+ return (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).currentSessionDir();
27822
+ }
27691
27823
  function realFlowDeps() {
27692
27824
  const log = (entry) => appendWizardLog(entry);
27693
27825
  return {
@@ -27703,13 +27835,14 @@ function realFlowDeps() {
27703
27835
  }
27704
27836
  },
27705
27837
  mkdir: async (path5) => {
27706
- await mkdir8(path5, { recursive: true });
27838
+ await mkdir9(path5, { recursive: true });
27707
27839
  },
27708
27840
  detectSaveConflict,
27709
27841
  buildTimestampedSubdir,
27710
27842
  rejectComponentsByName,
27711
27843
  log,
27712
- stderr: (text) => process.stderr.write(text)
27844
+ stderr: (text) => process.stderr.write(text),
27845
+ sessionDir: realSessionDir
27713
27846
  };
27714
27847
  }
27715
27848
  function initialFlowState(start) {
@@ -27850,6 +27983,9 @@ function createFlowController(start, deps) {
27850
27983
  const startSave = (opts, patch = {}) => {
27851
27984
  pendingSave = opts;
27852
27985
  update({ ...patch, step: "path-prompt" });
27986
+ void deps.sessionDir?.().then((session) => {
27987
+ if (session && state.step === "path-prompt") update({ outDir: join24(session, "dsi-import") });
27988
+ });
27853
27989
  };
27854
27990
  const proceedToWrite = async (path5) => {
27855
27991
  update({ outDir: path5 });
@@ -27967,171 +28103,19 @@ function useFlow(start, deps = realFlowDeps) {
27967
28103
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
27968
28104
  import { useEffect as useEffect22, useState as useState27 } from "react";
27969
28105
  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
- });
28106
+ init_debug_store();
28126
28107
 
28127
28108
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28109
+ init_config();
28110
+ init_debug_store();
28111
+ init_debug_mode_store();
28112
+ init_version();
28128
28113
  async function readHelpInfo() {
28129
28114
  const debugMode = await readDebugModeSetting();
28130
28115
  return {
28131
28116
  storage: [
28132
28117
  { label: "Config folder", value: configRoot2() },
28133
- { label: "Settings file", value: configFilePath2() },
28134
- { label: "Debug logs", value: debugSessionsDir2() }
28118
+ { label: "Settings file", value: configFilePath2() }
28135
28119
  ],
28136
28120
  troubleshooting: [
28137
28121
  { label: "CLI version", value: readPackageVersion() },
@@ -28140,7 +28124,7 @@ async function readHelpInfo() {
28140
28124
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28141
28125
  {
28142
28126
  label: "This session",
28143
- value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28127
+ value: !debugMode.enabled ? "no logs written while Debug Mode is off" : currentDebugSessionDir() ?? "not started: set the Root Project Directory in Settings, or start an import"
28144
28128
  }
28145
28129
  ]
28146
28130
  };
@@ -28257,6 +28241,7 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28257
28241
  import TextInput4 from "ink-text-input";
28258
28242
 
28259
28243
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28244
+ init_config();
28260
28245
  var readV1Store = readSettings2;
28261
28246
  var writeV1Store = writeSettings2;
28262
28247
 
@@ -28269,7 +28254,8 @@ async function readCredentials() {
28269
28254
  cmaToken: store.cmaToken || "",
28270
28255
  host: store.host || "",
28271
28256
  defaultComponentDir: store.defaultComponentDir || "",
28272
- defaultTokenFile: store.defaultTokenFile || ""
28257
+ defaultTokenFile: store.defaultTokenFile || "",
28258
+ contentfulBaseDir: store.contentfulBaseDir || ""
28273
28259
  };
28274
28260
  }
28275
28261
  async function writeCredentials(config) {
@@ -28285,6 +28271,7 @@ async function writeCredentials(config) {
28285
28271
  }
28286
28272
 
28287
28273
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28274
+ init_debug_store();
28288
28275
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28289
28276
  var FIELD_ORDER = [
28290
28277
  "spaceId",
@@ -28292,7 +28279,8 @@ var FIELD_ORDER = [
28292
28279
  "cmaToken",
28293
28280
  "host",
28294
28281
  "defaultComponentDir",
28295
- "defaultTokenFile"
28282
+ "defaultTokenFile",
28283
+ "contentfulBaseDir"
28296
28284
  ];
28297
28285
  function debugFields(config) {
28298
28286
  return {
@@ -28301,17 +28289,23 @@ function debugFields(config) {
28301
28289
  cma_token: config?.cmaToken ?? "",
28302
28290
  host: config?.host ?? "",
28303
28291
  default_component_dir: config?.defaultComponentDir ?? "",
28304
- default_token_file: config?.defaultTokenFile ?? ""
28292
+ default_token_file: config?.defaultTokenFile ?? "",
28293
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
28305
28294
  };
28306
28295
  }
28307
28296
  var FIELD_LABELS = {
28308
28297
  spaceId: "Space ID",
28309
28298
  environmentId: "Environment ID",
28310
28299
  cmaToken: "CMA Token",
28311
- host: "API Host (optional)",
28312
- defaultComponentDir: "Default component directory (optional)",
28313
- defaultTokenFile: "Default token file (optional)"
28300
+ host: "API Host",
28301
+ defaultComponentDir: "Default component directory",
28302
+ defaultTokenFile: "Default token file",
28303
+ contentfulBaseDir: "Root Project Directory"
28304
+ };
28305
+ var FIELD_HINTS = {
28306
+ contentfulBaseDir: "(where .contentful goes)"
28314
28307
  };
28308
+ var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28315
28309
  function ConfigurationScreen({ onDone }) {
28316
28310
  const [stage, setStage] = useState29("loading");
28317
28311
  const [config, setConfig] = useState29(null);
@@ -28347,6 +28341,7 @@ function ConfigurationScreen({ onDone }) {
28347
28341
  setNotice(null);
28348
28342
  writeCredentials(config).then(() => {
28349
28343
  setLastSaved(config);
28344
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28350
28345
  setNotice({ kind: "success", text: "Configuration saved" });
28351
28346
  setStage("form");
28352
28347
  }).catch((err) => {
@@ -28412,10 +28407,7 @@ function ConfigurationScreen({ onDone }) {
28412
28407
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28413
28408
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28414
28409
  /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28415
- /* @__PURE__ */ jsxs45(Text46, { bold: isActive, children: [
28416
- FIELD_LABELS[field],
28417
- ":"
28418
- ] }),
28410
+ /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28419
28411
  isActive && editing ? /* @__PURE__ */ jsx55(
28420
28412
  TextInput4,
28421
28413
  {
@@ -28424,7 +28416,8 @@ function ConfigurationScreen({ onDone }) {
28424
28416
  onSubmit: () => setEditing(false),
28425
28417
  mask: field === "cmaToken" ? "\u2022" : void 0
28426
28418
  }
28427
- ) : /* @__PURE__ */ jsx55(Text46, { children: display || /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" }) })
28419
+ ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28420
+ FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28428
28421
  ] }, field);
28429
28422
  }) }),
28430
28423
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
@@ -28476,6 +28469,7 @@ async function writeAnalyticsSetting(setting) {
28476
28469
  }
28477
28470
 
28478
28471
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28472
+ init_debug_store();
28479
28473
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28480
28474
  function OptInAnalyticsScreen({ onDone }) {
28481
28475
  const [loading, setLoading] = useState30(true);
@@ -28536,6 +28530,8 @@ function OptInAnalyticsScreen({ onDone }) {
28536
28530
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28537
28531
  import { useEffect as useEffect25, useState as useState31 } from "react";
28538
28532
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28533
+ init_version();
28534
+ init_debug_store();
28539
28535
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28540
28536
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28541
28537
  function UpgradeScreen({ onDone }) {
@@ -28607,6 +28603,8 @@ function renderBody(upgradeCheck) {
28607
28603
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28608
28604
  import { useEffect as useEffect26, useState as useState32 } from "react";
28609
28605
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28606
+ init_debug_mode_store();
28607
+ init_debug_store();
28610
28608
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28611
28609
  function DebugModeScreen({ onDone }) {
28612
28610
  const [loading, setLoading] = useState32(true);