@contentful/experience-design-system-cli 2.37.1-dev-build-eed963c1.0 → 2.37.1-dev-build-a6ad74de.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 !== "",
@@ -27143,7 +27401,7 @@ import { useEffect as useEffect20, useRef as useRef12, useSyncExternalStore } fr
27143
27401
  import { appendFileSync, writeFileSync } from "node:fs";
27144
27402
  import { mkdir as mkdir8 } from "node:fs/promises";
27145
27403
  import { tmpdir } from "node:os";
27146
- import { join as join23 } from "node:path";
27404
+ import { join as join23, resolve as resolve25 } from "node:path";
27147
27405
 
27148
27406
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27149
27407
  function shouldBypassPreview(state) {
@@ -27514,7 +27772,7 @@ var realSaveDeps = () => ({
27514
27772
  writeFile: (path5, contents) => writeFile7(path5, contents),
27515
27773
  appendRun,
27516
27774
  buildSourceFingerprint,
27517
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27775
+ sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
27518
27776
  warn: (message) => process.stderr.write(message)
27519
27777
  });
27520
27778
  async function runPrintFiles(input, deps, onPatch) {
@@ -27848,7 +28106,7 @@ function createFlowController(start, deps) {
27848
28106
  },
27849
28107
  async submitPath(submitted) {
27850
28108
  await deps.mkdir(submitted);
27851
- if (await deps.detectSaveConflict(submitted)) {
28109
+ if (resolve25(submitted) !== resolve25(state.outDir) && await deps.detectSaveConflict(submitted)) {
27852
28110
  const subdir = deps.buildTimestampedSubdir(submitted);
27853
28111
  await deps.mkdir(subdir);
27854
28112
  await proceedToWrite(subdir);
@@ -27897,171 +28155,19 @@ function useFlow(start, options = {}) {
27897
28155
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
27898
28156
  import { useEffect as useEffect21, useState as useState27 } from "react";
27899
28157
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
27900
-
27901
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27902
- import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
27903
- import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
27904
- import { join as join24 } from "node:path";
27905
-
27906
- // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
27907
- var DEFAULT_DEBUG_MODE_SETTING = {
27908
- enabled: true
27909
- };
27910
- async function readDebugModeSetting() {
27911
- const { debugMode } = await readSettings2();
27912
- return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
27913
- }
27914
- async function writeDebugModeSetting(setting) {
27915
- await updateSettings2({ debugMode: setting });
27916
- }
27917
-
27918
- // packages/experience-design-system-cli/src/tui/debug-store.ts
27919
- var pendingRun;
27920
- function generateRunId() {
27921
- const now = /* @__PURE__ */ new Date();
27922
- const pad = (n) => String(n).padStart(2, "0");
27923
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
27924
- }
27925
- function datePrefix(now = /* @__PURE__ */ new Date()) {
27926
- const pad = (n) => String(n).padStart(2, "0");
27927
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
27928
- }
27929
- function slugify(value) {
27930
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
27931
- }
27932
- function generateSessionId3() {
27933
- const today = datePrefix();
27934
- const root = debugSessionsDir2();
27935
- const existing = existsSync9(root) ? readdirSync4(root) : [];
27936
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
27937
- const maxSeq = existing.reduce((max, entry) => {
27938
- const match2 = seqPattern.exec(entry);
27939
- return match2 ? Math.max(max, Number(match2[1])) : max;
27940
- }, 0);
27941
- return `${today}-session-${maxSeq + 1}`;
27942
- }
27943
- var SESSION_ID = generateSessionId3();
27944
- function sessionDebugDir() {
27945
- return join24(debugSessionsDir2(), SESSION_ID);
27946
- }
27947
- function currentDebugSessionDir() {
27948
- return sessionDebugDir();
27949
- }
27950
- void isDebugModeEnabled().then((enabled) => {
27951
- if (!enabled) return void 0;
27952
- return mkdir9(sessionDebugDir(), { recursive: true });
27953
- });
27954
- async function isDebugModeEnabled() {
27955
- try {
27956
- return (await readDebugModeSetting()).enabled;
27957
- } catch {
27958
- return true;
27959
- }
27960
- }
27961
- function redact(value) {
27962
- const clone = { ...value };
27963
- if ("cma_token" in clone) {
27964
- const raw = clone.cma_token;
27965
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
27966
- }
27967
- return clone;
27968
- }
27969
- function startDebugRun({
27970
- flow,
27971
- step,
27972
- menuOption,
27973
- inputs
27974
- }) {
27975
- const runId = generateRunId();
27976
- const startedAt = Date.now();
27977
- const redactedInputs = redact(inputs);
27978
- isDebugModeEnabled().then((enabled) => {
27979
- if (!enabled) return;
27980
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
27981
- });
27982
- }
27983
- async function finishDebugRun({
27984
- outputs,
27985
- status,
27986
- exitMethod
27987
- }) {
27988
- const run = pendingRun;
27989
- if (!run) return;
27990
- pendingRun = void 0;
27991
- const durationMs = Date.now() - run.startedAt;
27992
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
27993
- const flowSegments = run.flow.split("/");
27994
- const dir = join24(sessionDebugDir(), ...flowSegments);
27995
- await mkdir9(dir, { recursive: true });
27996
- const filename = nextAttemptFilename(dir, run.menuOption);
27997
- await writeFile8(join24(dir, filename), content, { mode: 384 });
27998
- }
27999
- function nextAttemptFilename(dir, menuOption) {
28000
- const today = datePrefix();
28001
- const optionSlug = slugify(menuOption);
28002
- const existing = existsSync9(dir) ? readdirSync4(dir) : [];
28003
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
28004
- const maxAttempt = existing.reduce((max, entry) => {
28005
- const match2 = attemptPattern.exec(entry);
28006
- return match2 ? Math.max(max, Number(match2[1])) : max;
28007
- }, 0);
28008
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
28009
- }
28010
- function renderMarkdown(run, finish) {
28011
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
28012
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
28013
- const flowSlug = run.flow.split("/").join("-");
28014
- return `# Debug Log
28015
-
28016
- - Run ID: ${run.runId}
28017
- - Flow: ${flowSlug}
28018
- - Step: ${stepLabel2}
28019
- - Menu option: ${run.menuOption}
28020
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
28021
- - CLI version: ${readPackageVersion()}
28022
- - Platform: ${process.platform} / Node ${process.version}
28023
- - Duration on screen: ${finish.durationMs}ms
28024
- - Status: ${finish.status}
28025
- - Exit method: ${finish.exitMethod}
28026
-
28027
- ## Inputs
28028
- \`\`\`json
28029
- ${JSON.stringify(run.inputs, null, 2)}
28030
- \`\`\`
28031
-
28032
- ## Outputs
28033
- \`\`\`json
28034
- ${JSON.stringify(finish.outputs, null, 2)}
28035
- \`\`\`
28036
- `;
28037
- }
28038
- function handleCrash() {
28039
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28040
- }
28041
- process.once("uncaughtException", (err) => {
28042
- void handleCrash().finally(() => {
28043
- throw err;
28044
- });
28045
- });
28046
- process.once("unhandledRejection", (reason) => {
28047
- void handleCrash().finally(() => {
28048
- throw reason;
28049
- });
28050
- });
28051
- process.once("SIGINT", () => {
28052
- void handleCrash().finally(() => {
28053
- process.exit(130);
28054
- });
28055
- });
28158
+ init_debug_store();
28056
28159
 
28057
28160
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28161
+ init_config();
28162
+ init_debug_store();
28163
+ init_debug_mode_store();
28164
+ init_version();
28058
28165
  async function readHelpInfo() {
28059
28166
  const debugMode = await readDebugModeSetting();
28060
28167
  return {
28061
28168
  storage: [
28062
28169
  { label: "Config folder", value: configRoot2() },
28063
- { label: "Settings file", value: configFilePath2() },
28064
- { label: "Debug logs", value: debugSessionsDir2() }
28170
+ { label: "Settings file", value: configFilePath2() }
28065
28171
  ],
28066
28172
  troubleshooting: [
28067
28173
  { label: "CLI version", value: readPackageVersion() },
@@ -28070,7 +28176,7 @@ async function readHelpInfo() {
28070
28176
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28071
28177
  {
28072
28178
  label: "This session",
28073
- value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28179
+ 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"
28074
28180
  }
28075
28181
  ]
28076
28182
  };
@@ -28187,6 +28293,7 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28187
28293
  import TextInput4 from "ink-text-input";
28188
28294
 
28189
28295
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28296
+ init_config();
28190
28297
  var readV1Store = readSettings2;
28191
28298
  var writeV1Store = writeSettings2;
28192
28299
 
@@ -28199,7 +28306,8 @@ async function readCredentials() {
28199
28306
  cmaToken: store.cmaToken || "",
28200
28307
  host: store.host || "",
28201
28308
  defaultComponentDir: store.defaultComponentDir || "",
28202
- defaultTokenFile: store.defaultTokenFile || ""
28309
+ defaultTokenFile: store.defaultTokenFile || "",
28310
+ contentfulBaseDir: store.contentfulBaseDir || ""
28203
28311
  };
28204
28312
  }
28205
28313
  async function writeCredentials(config) {
@@ -28215,6 +28323,7 @@ async function writeCredentials(config) {
28215
28323
  }
28216
28324
 
28217
28325
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28326
+ init_debug_store();
28218
28327
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28219
28328
  var FIELD_ORDER = [
28220
28329
  "spaceId",
@@ -28222,7 +28331,8 @@ var FIELD_ORDER = [
28222
28331
  "cmaToken",
28223
28332
  "host",
28224
28333
  "defaultComponentDir",
28225
- "defaultTokenFile"
28334
+ "defaultTokenFile",
28335
+ "contentfulBaseDir"
28226
28336
  ];
28227
28337
  function debugFields(config) {
28228
28338
  return {
@@ -28231,17 +28341,23 @@ function debugFields(config) {
28231
28341
  cma_token: config?.cmaToken ?? "",
28232
28342
  host: config?.host ?? "",
28233
28343
  default_component_dir: config?.defaultComponentDir ?? "",
28234
- default_token_file: config?.defaultTokenFile ?? ""
28344
+ default_token_file: config?.defaultTokenFile ?? "",
28345
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
28235
28346
  };
28236
28347
  }
28237
28348
  var FIELD_LABELS = {
28238
28349
  spaceId: "Space ID",
28239
28350
  environmentId: "Environment ID",
28240
28351
  cmaToken: "CMA Token",
28241
- host: "API Host (optional)",
28242
- defaultComponentDir: "Default component directory (optional)",
28243
- defaultTokenFile: "Default token file (optional)"
28352
+ host: "API Host",
28353
+ defaultComponentDir: "Default component directory",
28354
+ defaultTokenFile: "Default token file",
28355
+ contentfulBaseDir: "Root Project Directory"
28356
+ };
28357
+ var FIELD_HINTS = {
28358
+ contentfulBaseDir: "(where .contentful goes)"
28244
28359
  };
28360
+ var LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
28245
28361
  function ConfigurationScreen({ onDone }) {
28246
28362
  const [stage, setStage] = useState29("loading");
28247
28363
  const [config, setConfig] = useState29(null);
@@ -28277,6 +28393,7 @@ function ConfigurationScreen({ onDone }) {
28277
28393
  setNotice(null);
28278
28394
  writeCredentials(config).then(() => {
28279
28395
  setLastSaved(config);
28396
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
28280
28397
  setNotice({ kind: "success", text: "Configuration saved" });
28281
28398
  setStage("form");
28282
28399
  }).catch((err) => {
@@ -28342,10 +28459,7 @@ function ConfigurationScreen({ onDone }) {
28342
28459
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
28343
28460
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
28344
28461
  /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
28345
- /* @__PURE__ */ jsxs45(Text46, { bold: isActive, children: [
28346
- FIELD_LABELS[field],
28347
- ":"
28348
- ] }),
28462
+ /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
28349
28463
  isActive && editing ? /* @__PURE__ */ jsx55(
28350
28464
  TextInput4,
28351
28465
  {
@@ -28354,7 +28468,8 @@ function ConfigurationScreen({ onDone }) {
28354
28468
  onSubmit: () => setEditing(false),
28355
28469
  mask: field === "cmaToken" ? "\u2022" : void 0
28356
28470
  }
28357
- ) : /* @__PURE__ */ jsx55(Text46, { children: display || /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" }) })
28471
+ ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
28472
+ FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
28358
28473
  ] }, field);
28359
28474
  }) }),
28360
28475
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
@@ -28406,6 +28521,7 @@ async function writeAnalyticsSetting(setting) {
28406
28521
  }
28407
28522
 
28408
28523
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28524
+ init_debug_store();
28409
28525
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28410
28526
  function OptInAnalyticsScreen({ onDone }) {
28411
28527
  const [loading, setLoading] = useState30(true);
@@ -28466,6 +28582,8 @@ function OptInAnalyticsScreen({ onDone }) {
28466
28582
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28467
28583
  import { useEffect as useEffect24, useState as useState31 } from "react";
28468
28584
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28585
+ init_version();
28586
+ init_debug_store();
28469
28587
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28470
28588
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28471
28589
  function UpgradeScreen({ onDone }) {
@@ -28537,6 +28655,8 @@ function renderBody(upgradeCheck) {
28537
28655
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28538
28656
  import { useEffect as useEffect25, useState as useState32 } from "react";
28539
28657
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28658
+ init_debug_mode_store();
28659
+ init_debug_store();
28540
28660
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28541
28661
  function DebugModeScreen({ onDone }) {
28542
28662
  const [loading, setLoading] = useState32(true);
@@ -28639,7 +28759,7 @@ function App({ importOptions, inkClear }) {
28639
28759
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
28640
28760
  const state = await inspectTokens({
28641
28761
  rawTokensPath: tokens,
28642
- outDir: join25(resolveUserPath(projectPath2), ".contentful"),
28762
+ contentfulDir: join25(resolveUserPath(projectPath2), ".contentful"),
28643
28763
  cache: importOptions.cache
28644
28764
  });
28645
28765
  if (state.kind === "cached") {
@@ -28660,6 +28780,7 @@ function App({ importOptions, inkClear }) {
28660
28780
  const settings = await readSettings2();
28661
28781
  const { agent, agentModel } = resolveAgentChoice(launch.agent, settings);
28662
28782
  const generatePromptPath = typeof settings.generatePromptPath === "string" ? settings.generatePromptPath : void 0;
28783
+ const outDir = await (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).startImportRun(resolveUserPath(launch.projectPath ?? ""));
28663
28784
  setExtractionRun({
28664
28785
  ...generatePromptPath ? { generatePromptPath } : {},
28665
28786
  // the later steps get the same agent, so they use what the stage used
@@ -28668,6 +28789,7 @@ function App({ importOptions, inkClear }) {
28668
28789
  tokenStrategy,
28669
28790
  input: {
28670
28791
  projectPath: resolveUserPath(launch.projectPath ?? ""),
28792
+ outDir,
28671
28793
  filePaths: launch.filePaths ?? [],
28672
28794
  rawTokensPath: launch.tokens ?? "",
28673
28795
  tokenStrategy,