@contentful/experience-design-system-cli 2.37.1-dev-build-bdf99669.0 → 2.37.1-dev-build-6bfb243f.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((resolve27) => {
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
+ resolve27(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((resolve27) => {
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
+ resolve27("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
+ resolve27("unauthenticated");
867
932
  return;
868
933
  }
869
934
  try {
870
935
  const status = JSON.parse(stdout);
871
- resolve25(status.loggedIn ? "ok" : "unauthenticated");
936
+ resolve27(status.loggedIn ? "ok" : "unauthenticated");
872
937
  } catch {
873
- resolve25("unauthenticated");
938
+ resolve27("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((resolve27) => {
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) => resolve27(code === 0));
886
951
  });
887
952
  }
888
953
  var init_check_agent_auth = __esm({
@@ -2016,6 +2081,253 @@ 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
+ startImportRun: () => startImportRun
2146
+ });
2147
+ import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
2148
+ import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
2149
+ import { join as join24, resolve as resolve26 } from "node:path";
2150
+ function generateRunId() {
2151
+ const now = /* @__PURE__ */ new Date();
2152
+ const pad = (n) => String(n).padStart(2, "0");
2153
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
2154
+ }
2155
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
2156
+ const pad = (n) => String(n).padStart(2, "0");
2157
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
2158
+ }
2159
+ function slugify(value) {
2160
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2161
+ }
2162
+ async function readBaseDir() {
2163
+ try {
2164
+ const dir = (await readSettings2())["contentfulBaseDir"];
2165
+ return typeof dir === "string" && dir !== "" ? resolve26(dir) : void 0;
2166
+ } catch {
2167
+ return void 0;
2168
+ }
2169
+ }
2170
+ function nextSessionId(contentfulDir) {
2171
+ const today = datePrefix();
2172
+ const existing = existsSync9(contentfulDir) ? readdirSync4(contentfulDir) : [];
2173
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2174
+ const maxSeq = existing.reduce((max, entry) => {
2175
+ const match2 = seqPattern.exec(entry);
2176
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2177
+ }, 0);
2178
+ return `${today}-session-${maxSeq + 1}`;
2179
+ }
2180
+ function startSession(base, { replace }) {
2181
+ const contentfulDir = join24(base, ".contentful");
2182
+ if (replace || !sessionDir) sessionDir = join24(contentfulDir, nextSessionId(contentfulDir));
2183
+ return sessionDir;
2184
+ }
2185
+ function currentDebugSessionDir() {
2186
+ return sessionDir && join24(sessionDir, "debug");
2187
+ }
2188
+ function currentSessionDir() {
2189
+ return sessionDir;
2190
+ }
2191
+ async function startDebugSessionIn(base, { replace = false } = {}) {
2192
+ try {
2193
+ if (!await isDebugModeEnabled()) return;
2194
+ await mkdir9(join24(startSession(resolve26(base), { replace }), "debug"), { recursive: true });
2195
+ } catch {
2196
+ }
2197
+ }
2198
+ function nextImportRunDir(session) {
2199
+ const existing = existsSync9(session) ? readdirSync4(session) : [];
2200
+ const maxRun = existing.reduce((max, entry) => {
2201
+ const match2 = /^dsi-import-(\d+)$/.exec(entry);
2202
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2203
+ }, 0);
2204
+ return join24(session, `dsi-import-${maxRun + 1}`);
2205
+ }
2206
+ async function startImportRun(projectPath) {
2207
+ await startDebugSessionIn(projectPath);
2208
+ if (!sessionDir) return join24(resolve26(projectPath), ".contentful");
2209
+ const dir = nextImportRunDir(sessionDir);
2210
+ await mkdir9(dir, { recursive: true });
2211
+ return dir;
2212
+ }
2213
+ async function isDebugModeEnabled() {
2214
+ try {
2215
+ return (await readDebugModeSetting()).enabled;
2216
+ } catch {
2217
+ return true;
2218
+ }
2219
+ }
2220
+ function redact(value) {
2221
+ const clone = { ...value };
2222
+ if ("cma_token" in clone) {
2223
+ const raw = clone.cma_token;
2224
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2225
+ }
2226
+ return clone;
2227
+ }
2228
+ function startDebugRun({
2229
+ flow,
2230
+ step,
2231
+ menuOption,
2232
+ inputs
2233
+ }) {
2234
+ const runId = generateRunId();
2235
+ const startedAt = Date.now();
2236
+ const redactedInputs = redact(inputs);
2237
+ isDebugModeEnabled().then((enabled) => {
2238
+ if (!enabled) return;
2239
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2240
+ });
2241
+ }
2242
+ async function finishDebugRun({
2243
+ outputs,
2244
+ status,
2245
+ exitMethod
2246
+ }) {
2247
+ const run = pendingRun;
2248
+ if (!run) return;
2249
+ pendingRun = void 0;
2250
+ const durationMs = Date.now() - run.startedAt;
2251
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2252
+ const root = currentDebugSessionDir();
2253
+ if (!root) return;
2254
+ const flowSegments = run.flow.split("/");
2255
+ const dir = join24(root, ...flowSegments);
2256
+ await mkdir9(dir, { recursive: true });
2257
+ const filename = nextAttemptFilename(dir, run.menuOption);
2258
+ await writeFile8(join24(dir, filename), content, { mode: 384 });
2259
+ }
2260
+ function nextAttemptFilename(dir, menuOption) {
2261
+ const today = datePrefix();
2262
+ const optionSlug = slugify(menuOption);
2263
+ const existing = existsSync9(dir) ? readdirSync4(dir) : [];
2264
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2265
+ const maxAttempt = existing.reduce((max, entry) => {
2266
+ const match2 = attemptPattern.exec(entry);
2267
+ return match2 ? Math.max(max, Number(match2[1])) : max;
2268
+ }, 0);
2269
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2270
+ }
2271
+ function renderMarkdown(run, finish) {
2272
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2273
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2274
+ const flowSlug = run.flow.split("/").join("-");
2275
+ return `# Debug Log
2276
+
2277
+ - Run ID: ${run.runId}
2278
+ - Flow: ${flowSlug}
2279
+ - Step: ${stepLabel2}
2280
+ - Menu option: ${run.menuOption}
2281
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2282
+ - CLI version: ${readPackageVersion()}
2283
+ - Platform: ${process.platform} / Node ${process.version}
2284
+ - Duration on screen: ${finish.durationMs}ms
2285
+ - Status: ${finish.status}
2286
+ - Exit method: ${finish.exitMethod}
2287
+
2288
+ ## Inputs
2289
+ \`\`\`json
2290
+ ${JSON.stringify(run.inputs, null, 2)}
2291
+ \`\`\`
2292
+
2293
+ ## Outputs
2294
+ \`\`\`json
2295
+ ${JSON.stringify(finish.outputs, null, 2)}
2296
+ \`\`\`
2297
+ `;
2298
+ }
2299
+ function handleCrash() {
2300
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2301
+ }
2302
+ var pendingRun, sessionDir;
2303
+ var init_debug_store = __esm({
2304
+ "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2305
+ "use strict";
2306
+ init_config();
2307
+ init_version();
2308
+ init_debug_mode_store();
2309
+ void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
2310
+ if (!enabled || !base) return void 0;
2311
+ return mkdir9(join24(startSession(base, { replace: false }), "debug"), { recursive: true });
2312
+ });
2313
+ process.once("uncaughtException", (err) => {
2314
+ void handleCrash().finally(() => {
2315
+ throw err;
2316
+ });
2317
+ });
2318
+ process.once("unhandledRejection", (reason) => {
2319
+ void handleCrash().finally(() => {
2320
+ throw reason;
2321
+ });
2322
+ });
2323
+ process.once("SIGINT", () => {
2324
+ void handleCrash().finally(() => {
2325
+ process.exit(130);
2326
+ });
2327
+ });
2328
+ }
2329
+ });
2330
+
2019
2331
  // packages/experience-design-system-cli/app.tsx
2020
2332
  import { join as join25 } from "node:path";
2021
2333
  import { useEffect as useEffect26, useState as useState33 } from "react";
@@ -2055,60 +2367,8 @@ function brandBar(width, ramp = BRAND_RAMP) {
2055
2367
  }
2056
2368
  var FOCUS_MARKER = "\u276F";
2057
2369
 
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
- }
2370
+ // packages/experience-design-system-cli/src/tui/home/home.tsx
2371
+ init_version();
2112
2372
 
2113
2373
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2114
2374
  import { useEffect, useState } from "react";
@@ -12307,11 +12567,11 @@ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node
12307
12567
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
12308
12568
  import { resolve as resolve15 } from "node:path";
12309
12569
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
12310
- const sessionDir = resolve15(artifactsRoot, sessionId);
12570
+ const sessionDir2 = resolve15(artifactsRoot, sessionId);
12311
12571
  return {
12312
- sessionDir,
12313
- eventsPath: resolve15(sessionDir, "events.jsonl"),
12314
- statePath: resolve15(sessionDir, "current-review-state.json")
12572
+ sessionDir: sessionDir2,
12573
+ eventsPath: resolve15(sessionDir2, "events.jsonl"),
12574
+ statePath: resolve15(sessionDir2, "current-review-state.json")
12315
12575
  };
12316
12576
  }
12317
12577
 
@@ -13510,7 +13770,7 @@ function errorMessage(error) {
13510
13770
  return error instanceof Error && error.message ? error.message : String(error);
13511
13771
  }
13512
13772
  function defaultSleep(delayMs) {
13513
- return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13773
+ return new Promise((resolve27) => setTimeout(resolve27, delayMs));
13514
13774
  }
13515
13775
 
13516
13776
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -13751,7 +14011,7 @@ var ApiClient = class {
13751
14011
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13752
14012
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13753
14013
  const jitter = Math.random() * baseDelay * 0.15;
13754
- await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
14014
+ await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
13755
14015
  }
13756
14016
  }
13757
14017
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -15864,7 +16124,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
15864
16124
  const message = error instanceof Error ? error.message : String(error);
15865
16125
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
15866
16126
  throw error;
15867
- await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16127
+ await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
15868
16128
  }
15869
16129
  }
15870
16130
  }
@@ -16691,6 +16951,7 @@ function useCredentialsControls(handlers) {
16691
16951
  }
16692
16952
 
16693
16953
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16954
+ init_version();
16694
16955
  function cliUserAgent() {
16695
16956
  return buildUserAgent(readPackageVersion());
16696
16957
  }
@@ -17035,11 +17296,34 @@ function RunningStep({
17035
17296
  }
17036
17297
 
17037
17298
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-reuse/logic.ts
17038
- import { access as access5, stat as stat4 } from "node:fs/promises";
17299
+ import { access as access5, readdir as readdir2, stat as stat4 } from "node:fs/promises";
17039
17300
  import { join as join16 } from "node:path";
17040
- async function inspectTokens({ rawTokensPath, outDir, cache }) {
17301
+ async function findLatestTokens(contentfulDir) {
17302
+ const candidates = [join16(contentfulDir, "tokens.json")];
17303
+ try {
17304
+ for (const session of await readdir2(contentfulDir, { withFileTypes: true })) {
17305
+ if (!session.isDirectory()) continue;
17306
+ for (const run of await readdir2(join16(contentfulDir, session.name), { withFileTypes: true }).catch(() => [])) {
17307
+ if (run.isDirectory() && /^dsi-import-\d+$/.test(run.name)) {
17308
+ candidates.push(join16(contentfulDir, session.name, run.name, "tokens.json"));
17309
+ }
17310
+ }
17311
+ }
17312
+ } catch {
17313
+ }
17314
+ const found = [];
17315
+ for (const path5 of candidates) {
17316
+ try {
17317
+ found.push({ path: path5, mtimeMs: (await stat4(path5)).mtimeMs });
17318
+ } catch {
17319
+ }
17320
+ }
17321
+ return found.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.path ?? null;
17322
+ }
17323
+ async function inspectTokens({ rawTokensPath, contentfulDir, cache }) {
17041
17324
  if (!cache) return { kind: "none" };
17042
- const tokensPath = join16(outDir, "tokens.json");
17325
+ const tokensPath = await findLatestTokens(contentfulDir);
17326
+ if (!tokensPath) return { kind: "none" };
17043
17327
  try {
17044
17328
  await access5(tokensPath);
17045
17329
  } catch {
@@ -17190,34 +17474,8 @@ function ExtractionScreen({
17190
17474
  );
17191
17475
  }
17192
17476
 
17193
- // packages/experience-design-system-types/dist/src/config/index.js
17194
- import { randomBytes as randomBytes3 } from "node:crypto";
17195
- import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
17196
- import { homedir as homedir3 } from "node:os";
17197
- import { dirname as dirname13, join as join17 } from "node:path";
17198
- function configRoot2() {
17199
- return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
17200
- }
17201
- var configFilePath2 = () => join17(configRoot2(), "config.json");
17202
- var debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
17203
- async function readSettings2() {
17204
- try {
17205
- return JSON.parse(await readFile18(configFilePath2(), "utf8"));
17206
- } catch {
17207
- return {};
17208
- }
17209
- }
17210
- async function writeSettings2(settings) {
17211
- const path5 = configFilePath2();
17212
- await mkdir6(dirname13(path5), { recursive: true });
17213
- const tmp = `${path5}.${process.pid}.${randomBytes3(4).toString("hex")}.tmp`;
17214
- await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
17215
- `, { mode: 384 });
17216
- await rename2(tmp, path5);
17217
- }
17218
- async function updateSettings2(patch) {
17219
- await writeSettings2({ ...await readSettings2(), ...patch });
17220
- }
17477
+ // packages/experience-design-system-cli/app.tsx
17478
+ init_config();
17221
17479
 
17222
17480
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17223
17481
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
@@ -17344,7 +17602,7 @@ var realDeps = {
17344
17602
  var fail = (step, message) => ({ ok: false, step, message });
17345
17603
  var errorMessage2 = (error) => error instanceof Error ? error.message : String(error);
17346
17604
  async function runExtraction(input, onProgress, deps = realDeps) {
17347
- const outDir = join19(resolve22(input.projectPath), ".contentful");
17605
+ const outDir = input.outDir ?? join19(resolve22(input.projectPath), ".contentful");
17348
17606
  let progress = initialProgress({
17349
17607
  hasCredentials: input.credentials !== null,
17350
17608
  hasRawTokens: input.rawTokensPath !== "",
@@ -27123,7 +27381,7 @@ import { useEffect as useEffect20, useRef as useRef12, useSyncExternalStore } fr
27123
27381
  import { appendFileSync, writeFileSync } from "node:fs";
27124
27382
  import { mkdir as mkdir8 } from "node:fs/promises";
27125
27383
  import { tmpdir } from "node:os";
27126
- import { join as join23 } from "node:path";
27384
+ import { join as join23, resolve as resolve25 } from "node:path";
27127
27385
 
27128
27386
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27129
27387
  function shouldBypassPreview(state) {
@@ -27494,7 +27752,7 @@ var realSaveDeps = () => ({
27494
27752
  writeFile: (path5, contents) => writeFile7(path5, contents),
27495
27753
  appendRun,
27496
27754
  buildSourceFingerprint,
27497
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27755
+ sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
27498
27756
  warn: (message) => process.stderr.write(message)
27499
27757
  });
27500
27758
  async function runPrintFiles(input, deps, onPatch) {
@@ -27828,7 +28086,7 @@ function createFlowController(start, deps) {
27828
28086
  },
27829
28087
  async submitPath(submitted) {
27830
28088
  await deps.mkdir(submitted);
27831
- if (await deps.detectSaveConflict(submitted)) {
28089
+ if (resolve25(submitted) !== resolve25(state.outDir) && await deps.detectSaveConflict(submitted)) {
27832
28090
  const subdir = deps.buildTimestampedSubdir(submitted);
27833
28091
  await deps.mkdir(subdir);
27834
28092
  await proceedToWrite(subdir);
@@ -27877,171 +28135,19 @@ function useFlow(start, options = {}) {
27877
28135
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
27878
28136
  import { useEffect as useEffect21, useState as useState27 } from "react";
27879
28137
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
27880
-
27881
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27882
- import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
27883
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
27884
- import { join as join24 } from "node:path";
27885
-
27886
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
27887
- var DEFAULT_DEBUG_MODE_SETTING = {
27888
- enabled: true
27889
- };
27890
- async function readDebugModeSetting() {
27891
- const { debugMode } = await readSettings2();
27892
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
27893
- }
27894
- async function writeDebugModeSetting(setting) {
27895
- await updateSettings2({ debugMode: setting });
27896
- }
27897
-
27898
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27899
- var pendingRun;
27900
- function generateRunId() {
27901
- const now = /* @__PURE__ */ new Date();
27902
- const pad = (n) => String(n).padStart(2, "0");
27903
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
27904
- }
27905
- function datePrefix(now = /* @__PURE__ */ new Date()) {
27906
- const pad = (n) => String(n).padStart(2, "0");
27907
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
27908
- }
27909
- function slugify(value) {
27910
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
27911
- }
27912
- function generateSessionId3() {
27913
- const today = datePrefix();
27914
- const root = debugSessionsDir2();
27915
- const existing = existsSync9(root) ? readdirSync4(root) : [];
27916
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
27917
- const maxSeq = existing.reduce((max, entry) => {
27918
- const match2 = seqPattern.exec(entry);
27919
- return match2 ? Math.max(max, Number(match2[1])) : max;
27920
- }, 0);
27921
- return `${today}-session-${maxSeq + 1}`;
27922
- }
27923
- var SESSION_ID = generateSessionId3();
27924
- function sessionDebugDir() {
27925
- return join24(debugSessionsDir2(), SESSION_ID);
27926
- }
27927
- function currentDebugSessionDir() {
27928
- return sessionDebugDir();
27929
- }
27930
- void isDebugModeEnabled().then((enabled) => {
27931
- if (!enabled) return void 0;
27932
- return mkdir9(sessionDebugDir(), { recursive: true });
27933
- });
27934
- async function isDebugModeEnabled() {
27935
- try {
27936
- return (await readDebugModeSetting()).enabled;
27937
- } catch {
27938
- return true;
27939
- }
27940
- }
27941
- function redact(value) {
27942
- const clone = { ...value };
27943
- if ("cma_token" in clone) {
27944
- const raw = clone.cma_token;
27945
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
27946
- }
27947
- return clone;
27948
- }
27949
- function startDebugRun({
27950
- flow,
27951
- step,
27952
- menuOption,
27953
- inputs
27954
- }) {
27955
- const runId = generateRunId();
27956
- const startedAt = Date.now();
27957
- const redactedInputs = redact(inputs);
27958
- isDebugModeEnabled().then((enabled) => {
27959
- if (!enabled) return;
27960
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
27961
- });
27962
- }
27963
- async function finishDebugRun({
27964
- outputs,
27965
- status,
27966
- exitMethod
27967
- }) {
27968
- const run = pendingRun;
27969
- if (!run) return;
27970
- pendingRun = void 0;
27971
- const durationMs = Date.now() - run.startedAt;
27972
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
27973
- const flowSegments = run.flow.split("/");
27974
- const dir = join24(sessionDebugDir(), ...flowSegments);
27975
- await mkdir9(dir, { recursive: true });
27976
- const filename = nextAttemptFilename(dir, run.menuOption);
27977
- await writeFile8(join24(dir, filename), content, { mode: 384 });
27978
- }
27979
- function nextAttemptFilename(dir, menuOption) {
27980
- const today = datePrefix();
27981
- const optionSlug = slugify(menuOption);
27982
- const existing = existsSync9(dir) ? readdirSync4(dir) : [];
27983
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
27984
- const maxAttempt = existing.reduce((max, entry) => {
27985
- const match2 = attemptPattern.exec(entry);
27986
- return match2 ? Math.max(max, Number(match2[1])) : max;
27987
- }, 0);
27988
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
27989
- }
27990
- function renderMarkdown(run, finish) {
27991
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
27992
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
27993
- const flowSlug = run.flow.split("/").join("-");
27994
- return `# Debug Log
27995
-
27996
- - Run ID: ${run.runId}
27997
- - Flow: ${flowSlug}
27998
- - Step: ${stepLabel2}
27999
- - Menu option: ${run.menuOption}
28000
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
28001
- - CLI version: ${readPackageVersion()}
28002
- - Platform: ${process.platform} / Node ${process.version}
28003
- - Duration on screen: ${finish.durationMs}ms
28004
- - Status: ${finish.status}
28005
- - Exit method: ${finish.exitMethod}
28006
-
28007
- ## Inputs
28008
- \`\`\`json
28009
- ${JSON.stringify(run.inputs, null, 2)}
28010
- \`\`\`
28011
-
28012
- ## Outputs
28013
- \`\`\`json
28014
- ${JSON.stringify(finish.outputs, null, 2)}
28015
- \`\`\`
28016
- `;
28017
- }
28018
- function handleCrash() {
28019
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28020
- }
28021
- process.once("uncaughtException", (err) => {
28022
- void handleCrash().finally(() => {
28023
- throw err;
28024
- });
28025
- });
28026
- process.once("unhandledRejection", (reason) => {
28027
- void handleCrash().finally(() => {
28028
- throw reason;
28029
- });
28030
- });
28031
- process.once("SIGINT", () => {
28032
- void handleCrash().finally(() => {
28033
- process.exit(130);
28034
- });
28035
- });
28138
+ init_debug_store();
28036
28139
 
28037
28140
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28141
+ init_config();
28142
+ init_debug_store();
28143
+ init_debug_mode_store();
28144
+ init_version();
28038
28145
  async function readHelpInfo() {
28039
28146
  const debugMode = await readDebugModeSetting();
28040
28147
  return {
28041
28148
  storage: [
28042
28149
  { label: "Config folder", value: configRoot2() },
28043
- { label: "Settings file", value: configFilePath2() },
28044
- { label: "Debug logs", value: debugSessionsDir2() }
28150
+ { label: "Settings file", value: configFilePath2() }
28045
28151
  ],
28046
28152
  troubleshooting: [
28047
28153
  { label: "CLI version", value: readPackageVersion() },
@@ -28050,7 +28156,7 @@ async function readHelpInfo() {
28050
28156
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28051
28157
  {
28052
28158
  label: "This session",
28053
- value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28159
+ value: !debugMode.enabled ? "no logs written while Debug Mode is off" : currentDebugSessionDir() ?? "not started: set the Root Project Directory in Settings, or start an import"
28054
28160
  }
28055
28161
  ]
28056
28162
  };
@@ -28167,6 +28273,7 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28167
28273
  import TextInput4 from "ink-text-input";
28168
28274
 
28169
28275
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28276
+ init_config();
28170
28277
  var readV1Store = readSettings2;
28171
28278
  var writeV1Store = writeSettings2;
28172
28279
 
@@ -28179,7 +28286,8 @@ async function readCredentials() {
28179
28286
  cmaToken: store.cmaToken || "",
28180
28287
  host: store.host || "",
28181
28288
  defaultComponentDir: store.defaultComponentDir || "",
28182
- defaultTokenFile: store.defaultTokenFile || ""
28289
+ defaultTokenFile: store.defaultTokenFile || "",
28290
+ contentfulBaseDir: store.contentfulBaseDir || ""
28183
28291
  };
28184
28292
  }
28185
28293
  async function writeCredentials(config) {
@@ -28195,6 +28303,7 @@ async function writeCredentials(config) {
28195
28303
  }
28196
28304
 
28197
28305
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28306
+ init_debug_store();
28198
28307
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28199
28308
  var FIELD_ORDER = [
28200
28309
  "spaceId",
@@ -28202,7 +28311,8 @@ var FIELD_ORDER = [
28202
28311
  "cmaToken",
28203
28312
  "host",
28204
28313
  "defaultComponentDir",
28205
- "defaultTokenFile"
28314
+ "defaultTokenFile",
28315
+ "contentfulBaseDir"
28206
28316
  ];
28207
28317
  function debugFields(config) {
28208
28318
  return {
@@ -28211,17 +28321,23 @@ function debugFields(config) {
28211
28321
  cma_token: config?.cmaToken ?? "",
28212
28322
  host: config?.host ?? "",
28213
28323
  default_component_dir: config?.defaultComponentDir ?? "",
28214
- default_token_file: config?.defaultTokenFile ?? ""
28324
+ default_token_file: config?.defaultTokenFile ?? "",
28325
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
28215
28326
  };
28216
28327
  }
28217
28328
  var FIELD_LABELS = {
28218
28329
  spaceId: "Space ID",
28219
28330
  environmentId: "Environment ID",
28220
28331
  cmaToken: "CMA Token",
28221
- host: "API Host (optional)",
28222
- defaultComponentDir: "Default component directory (optional)",
28223
- defaultTokenFile: "Default token file (optional)"
28332
+ host: "API Host",
28333
+ defaultComponentDir: "Default component directory",
28334
+ defaultTokenFile: "Default token file",
28335
+ contentfulBaseDir: "Root Project Directory"
28336
+ };
28337
+ var FIELD_HINTS = {
28338
+ contentfulBaseDir: "(where .contentful goes)"
28224
28339
  };
28340
+ var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28225
28341
  function ConfigurationScreen({ onDone }) {
28226
28342
  const [stage, setStage] = useState29("loading");
28227
28343
  const [config, setConfig] = useState29(null);
@@ -28257,6 +28373,7 @@ function ConfigurationScreen({ onDone }) {
28257
28373
  setNotice(null);
28258
28374
  writeCredentials(config).then(() => {
28259
28375
  setLastSaved(config);
28376
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28260
28377
  setNotice({ kind: "success", text: "Configuration saved" });
28261
28378
  setStage("form");
28262
28379
  }).catch((err) => {
@@ -28322,10 +28439,7 @@ function ConfigurationScreen({ onDone }) {
28322
28439
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28323
28440
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28324
28441
  /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28325
- /* @__PURE__ */ jsxs45(Text46, { bold: isActive, children: [
28326
- FIELD_LABELS[field],
28327
- ":"
28328
- ] }),
28442
+ /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28329
28443
  isActive && editing ? /* @__PURE__ */ jsx55(
28330
28444
  TextInput4,
28331
28445
  {
@@ -28334,7 +28448,8 @@ function ConfigurationScreen({ onDone }) {
28334
28448
  onSubmit: () => setEditing(false),
28335
28449
  mask: field === "cmaToken" ? "\u2022" : void 0
28336
28450
  }
28337
- ) : /* @__PURE__ */ jsx55(Text46, { children: display || /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" }) })
28451
+ ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28452
+ FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28338
28453
  ] }, field);
28339
28454
  }) }),
28340
28455
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
@@ -28386,6 +28501,7 @@ async function writeAnalyticsSetting(setting) {
28386
28501
  }
28387
28502
 
28388
28503
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28504
+ init_debug_store();
28389
28505
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28390
28506
  function OptInAnalyticsScreen({ onDone }) {
28391
28507
  const [loading, setLoading] = useState30(true);
@@ -28446,6 +28562,8 @@ function OptInAnalyticsScreen({ onDone }) {
28446
28562
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28447
28563
  import { useEffect as useEffect24, useState as useState31 } from "react";
28448
28564
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28565
+ init_version();
28566
+ init_debug_store();
28449
28567
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28450
28568
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28451
28569
  function UpgradeScreen({ onDone }) {
@@ -28517,6 +28635,8 @@ function renderBody(upgradeCheck) {
28517
28635
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28518
28636
  import { useEffect as useEffect25, useState as useState32 } from "react";
28519
28637
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28638
+ init_debug_mode_store();
28639
+ init_debug_store();
28520
28640
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28521
28641
  function DebugModeScreen({ onDone }) {
28522
28642
  const [loading, setLoading] = useState32(true);
@@ -28619,7 +28739,7 @@ function App({ importOptions, inkClear }) {
28619
28739
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
28620
28740
  const state = await inspectTokens({
28621
28741
  rawTokensPath: tokens,
28622
- outDir: join25(resolveUserPath(projectPath2), ".contentful"),
28742
+ contentfulDir: join25(resolveUserPath(projectPath2), ".contentful"),
28623
28743
  cache: importOptions.cache
28624
28744
  });
28625
28745
  if (state.kind === "cached") {
@@ -28640,6 +28760,7 @@ function App({ importOptions, inkClear }) {
28640
28760
  const settings = await readSettings2();
28641
28761
  const { agent, agentModel } = resolveAgentChoice(launch.agent, settings);
28642
28762
  const generatePromptPath = typeof settings.generatePromptPath === "string" ? settings.generatePromptPath : void 0;
28763
+ const outDir = await (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).startImportRun(resolveUserPath(launch.projectPath ?? ""));
28643
28764
  setExtractionRun({
28644
28765
  ...generatePromptPath ? { generatePromptPath } : {},
28645
28766
  // the later steps get the same agent, so they use what the stage used
@@ -28648,6 +28769,7 @@ function App({ importOptions, inkClear }) {
28648
28769
  tokenStrategy,
28649
28770
  input: {
28650
28771
  projectPath: resolveUserPath(launch.projectPath ?? ""),
28772
+ outDir,
28651
28773
  filePaths: launch.filePaths ?? [],
28652
28774
  rawTokensPath: launch.tokens ?? "",
28653
28775
  tokenStrategy,