@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/index.js CHANGED
@@ -2121,7 +2121,7 @@ async function runAgent(options) {
2121
2121
  promptLen: prompt.length,
2122
2122
  promptHead: prompt.slice(0, 500)
2123
2123
  });
2124
- return new Promise((resolve25) => {
2124
+ return new Promise((resolve27) => {
2125
2125
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
2126
2126
  const child = spawn3(binary, args, {
2127
2127
  stdio: ["pipe", "pipe", "pipe"],
@@ -2170,7 +2170,7 @@ async function runAgent(options) {
2170
2170
  stderrLen: stderr.length,
2171
2171
  stderrTail: stderr.slice(-1e3)
2172
2172
  });
2173
- resolve25(result);
2173
+ resolve27(result);
2174
2174
  });
2175
2175
  });
2176
2176
  }
@@ -2192,7 +2192,7 @@ async function checkAgentAuth(agent) {
2192
2192
  return "not-found";
2193
2193
  if (agent !== "claude")
2194
2194
  return "ok";
2195
- return new Promise((resolve25) => {
2195
+ return new Promise((resolve27) => {
2196
2196
  const child = spawn4(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
2197
2197
  let stdout = "";
2198
2198
  let done = false;
@@ -2201,7 +2201,7 @@ async function checkAgentAuth(agent) {
2201
2201
  return;
2202
2202
  done = true;
2203
2203
  child.kill("SIGTERM");
2204
- resolve25("unauthenticated");
2204
+ resolve27("unauthenticated");
2205
2205
  }, 5e3);
2206
2206
  child.stdout?.on("data", (chunk) => {
2207
2207
  stdout += chunk.toString();
@@ -2212,14 +2212,14 @@ async function checkAgentAuth(agent) {
2212
2212
  done = true;
2213
2213
  clearTimeout(timer);
2214
2214
  if (code !== 0) {
2215
- resolve25("unauthenticated");
2215
+ resolve27("unauthenticated");
2216
2216
  return;
2217
2217
  }
2218
2218
  try {
2219
2219
  const status = JSON.parse(stdout);
2220
- resolve25(status.loggedIn ? "ok" : "unauthenticated");
2220
+ resolve27(status.loggedIn ? "ok" : "unauthenticated");
2221
2221
  } catch {
2222
- resolve25("unauthenticated");
2222
+ resolve27("unauthenticated");
2223
2223
  }
2224
2224
  });
2225
2225
  });
@@ -2229,9 +2229,9 @@ async function binaryIsOnPath(binary) {
2229
2229
  const fs = await import("node:fs/promises");
2230
2230
  return fs.access(binary).then(() => true, () => false);
2231
2231
  }
2232
- return new Promise((resolve25) => {
2232
+ return new Promise((resolve27) => {
2233
2233
  const child = spawn4(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
2234
- child.on("close", (code) => resolve25(code === 0));
2234
+ child.on("close", (code) => resolve27(code === 0));
2235
2235
  });
2236
2236
  }
2237
2237
  var init_check_agent_auth = __esm({
@@ -13144,11 +13144,11 @@ var init_load_and_validate_for_review = __esm({
13144
13144
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
13145
13145
  import { resolve as resolve15 } from "node:path";
13146
13146
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
13147
- const sessionDir = resolve15(artifactsRoot, sessionId);
13147
+ const sessionDir2 = resolve15(artifactsRoot, sessionId);
13148
13148
  return {
13149
- sessionDir,
13150
- eventsPath: resolve15(sessionDir, "events.jsonl"),
13151
- statePath: resolve15(sessionDir, "current-review-state.json")
13149
+ sessionDir: sessionDir2,
13150
+ eventsPath: resolve15(sessionDir2, "events.jsonl"),
13151
+ statePath: resolve15(sessionDir2, "current-review-state.json")
13152
13152
  };
13153
13153
  }
13154
13154
  var init_review_session_paths = __esm({
@@ -14901,7 +14901,7 @@ function errorMessage(error) {
14901
14901
  return error instanceof Error && error.message ? error.message : String(error);
14902
14902
  }
14903
14903
  function defaultSleep(delayMs) {
14904
- return new Promise((resolve25) => setTimeout(resolve25, delayMs));
14904
+ return new Promise((resolve27) => setTimeout(resolve27, delayMs));
14905
14905
  }
14906
14906
  var MAX_RETRY_AFTER_MS;
14907
14907
  var init_http_utils = __esm({
@@ -15177,7 +15177,7 @@ var init_api_client = __esm({
15177
15177
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
15178
15178
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
15179
15179
  const jitter = Math.random() * baseDelay * 0.15;
15180
- await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
15180
+ await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
15181
15181
  }
15182
15182
  }
15183
15183
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -18734,7 +18734,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
18734
18734
  const message = error instanceof Error ? error.message : String(error);
18735
18735
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
18736
18736
  throw error;
18737
- await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
18737
+ await new Promise((resolve27) => setTimeout(resolve27, Math.min(250 * attempt, 2e3)));
18738
18738
  }
18739
18739
  }
18740
18740
  }
@@ -20301,11 +20301,34 @@ var init_shared2 = __esm({
20301
20301
  });
20302
20302
 
20303
20303
  // packages/experience-design-system-cli/src/tui/import/steps/05-token-reuse/logic.ts
20304
- import { access as access5, stat as stat4 } from "node:fs/promises";
20304
+ import { access as access5, readdir as readdir2, stat as stat4 } from "node:fs/promises";
20305
20305
  import { join as join18 } from "node:path";
20306
- async function inspectTokens({ rawTokensPath, outDir, cache }) {
20306
+ async function findLatestTokens(contentfulDir) {
20307
+ const candidates = [join18(contentfulDir, "tokens.json")];
20308
+ try {
20309
+ for (const session of await readdir2(contentfulDir, { withFileTypes: true })) {
20310
+ if (!session.isDirectory()) continue;
20311
+ for (const run of await readdir2(join18(contentfulDir, session.name), { withFileTypes: true }).catch(() => [])) {
20312
+ if (run.isDirectory() && /^dsi-import-\d+$/.test(run.name)) {
20313
+ candidates.push(join18(contentfulDir, session.name, run.name, "tokens.json"));
20314
+ }
20315
+ }
20316
+ }
20317
+ } catch {
20318
+ }
20319
+ const found = [];
20320
+ for (const path5 of candidates) {
20321
+ try {
20322
+ found.push({ path: path5, mtimeMs: (await stat4(path5)).mtimeMs });
20323
+ } catch {
20324
+ }
20325
+ }
20326
+ return found.sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.path ?? null;
20327
+ }
20328
+ async function inspectTokens({ rawTokensPath, contentfulDir, cache }) {
20307
20329
  if (!cache) return { kind: "none" };
20308
- const tokensPath = join18(outDir, "tokens.json");
20330
+ const tokensPath = await findLatestTokens(contentfulDir);
20331
+ if (!tokensPath) return { kind: "none" };
20309
20332
  try {
20310
20333
  await access5(tokensPath);
20311
20334
  } catch {
@@ -20520,13 +20543,12 @@ async function writeSettings2(settings) {
20520
20543
  async function updateSettings2(patch) {
20521
20544
  await writeSettings2({ ...await readSettings2(), ...patch });
20522
20545
  }
20523
- var configFilePath2, runsFilePath2, debugSessionsDir2, oldConfigDir2;
20546
+ var configFilePath2, runsFilePath2, oldConfigDir2;
20524
20547
  var init_config = __esm({
20525
20548
  "packages/experience-design-system-types/dist/src/config/index.js"() {
20526
20549
  "use strict";
20527
20550
  configFilePath2 = () => join19(configRoot2(), "config.json");
20528
20551
  runsFilePath2 = () => join19(configRoot2(), "state", "runs.json");
20529
- debugSessionsDir2 = () => join19(configRoot2(), "debug", "sessions");
20530
20552
  oldConfigDir2 = () => join19(homedir3(), ".config", "experiences");
20531
20553
  }
20532
20554
  });
@@ -20654,7 +20676,7 @@ var init_selection2 = __esm({
20654
20676
  import { mkdir as mkdir7 } from "node:fs/promises";
20655
20677
  import { join as join21, resolve as resolve22 } from "node:path";
20656
20678
  async function runExtraction(input, onProgress, deps = realDeps) {
20657
- const outDir = join21(resolve22(input.projectPath), ".contentful");
20679
+ const outDir = input.outDir ?? join21(resolve22(input.projectPath), ".contentful");
20658
20680
  let progress = initialProgress({
20659
20681
  hasCredentials: input.credentials !== null,
20660
20682
  hasRawTokens: input.rawTokensPath !== "",
@@ -31775,7 +31797,7 @@ var init_save = __esm({
31775
31797
  writeFile: (path5, contents) => writeFile7(path5, contents),
31776
31798
  appendRun,
31777
31799
  buildSourceFingerprint,
31778
- sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
31800
+ sleep: (ms) => new Promise((resolve27) => setTimeout(resolve27, ms)),
31779
31801
  warn: (message) => process.stderr.write(message)
31780
31802
  });
31781
31803
  }
@@ -31797,7 +31819,7 @@ var init_types9 = __esm({
31797
31819
  import { appendFileSync, writeFileSync } from "node:fs";
31798
31820
  import { mkdir as mkdir8 } from "node:fs/promises";
31799
31821
  import { tmpdir } from "node:os";
31800
- import { join as join25 } from "node:path";
31822
+ import { join as join25, resolve as resolve25 } from "node:path";
31801
31823
  function appendWizardLog(entry) {
31802
31824
  appendFileSync(WIZARD_LOG, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n");
31803
31825
  }
@@ -32045,7 +32067,7 @@ function createFlowController(start, deps) {
32045
32067
  },
32046
32068
  async submitPath(submitted) {
32047
32069
  await deps.mkdir(submitted);
32048
- if (await deps.detectSaveConflict(submitted)) {
32070
+ if (resolve25(submitted) !== resolve25(state.outDir) && await deps.detectSaveConflict(submitted)) {
32049
32071
  const subdir = deps.buildTimestampedSubdir(submitted);
32050
32072
  await deps.mkdir(subdir);
32051
32073
  await proceedToWrite(subdir);
@@ -32133,9 +32155,18 @@ var init_debug_mode_store = __esm({
32133
32155
  });
32134
32156
 
32135
32157
  // packages/experience-design-system-cli/src/tui/debug-store.ts
32158
+ var debug_store_exports = {};
32159
+ __export(debug_store_exports, {
32160
+ currentDebugSessionDir: () => currentDebugSessionDir,
32161
+ currentSessionDir: () => currentSessionDir,
32162
+ finishDebugRun: () => finishDebugRun,
32163
+ startDebugRun: () => startDebugRun,
32164
+ startDebugSessionIn: () => startDebugSessionIn,
32165
+ startImportRun: () => startImportRun
32166
+ });
32136
32167
  import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
32137
32168
  import { existsSync as existsSync11, readdirSync as readdirSync4 } from "node:fs";
32138
- import { join as join26 } from "node:path";
32169
+ import { join as join26, resolve as resolve26 } from "node:path";
32139
32170
  function generateRunId() {
32140
32171
  const now = /* @__PURE__ */ new Date();
32141
32172
  const pad = (n) => String(n).padStart(2, "0");
@@ -32148,10 +32179,17 @@ function datePrefix(now = /* @__PURE__ */ new Date()) {
32148
32179
  function slugify(value) {
32149
32180
  return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
32150
32181
  }
32151
- function generateSessionId3() {
32182
+ async function readBaseDir() {
32183
+ try {
32184
+ const dir = (await readSettings2())["contentfulBaseDir"];
32185
+ return typeof dir === "string" && dir !== "" ? resolve26(dir) : void 0;
32186
+ } catch {
32187
+ return void 0;
32188
+ }
32189
+ }
32190
+ function nextSessionId(contentfulDir) {
32152
32191
  const today = datePrefix();
32153
- const root = debugSessionsDir2();
32154
- const existing = existsSync11(root) ? readdirSync4(root) : [];
32192
+ const existing = existsSync11(contentfulDir) ? readdirSync4(contentfulDir) : [];
32155
32193
  const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
32156
32194
  const maxSeq = existing.reduce((max, entry) => {
32157
32195
  const match2 = seqPattern.exec(entry);
@@ -32159,11 +32197,38 @@ function generateSessionId3() {
32159
32197
  }, 0);
32160
32198
  return `${today}-session-${maxSeq + 1}`;
32161
32199
  }
32162
- function sessionDebugDir() {
32163
- return join26(debugSessionsDir2(), SESSION_ID);
32200
+ function startSession(base, { replace }) {
32201
+ const contentfulDir = join26(base, ".contentful");
32202
+ if (replace || !sessionDir) sessionDir = join26(contentfulDir, nextSessionId(contentfulDir));
32203
+ return sessionDir;
32164
32204
  }
32165
32205
  function currentDebugSessionDir() {
32166
- return sessionDebugDir();
32206
+ return sessionDir && join26(sessionDir, "debug");
32207
+ }
32208
+ function currentSessionDir() {
32209
+ return sessionDir;
32210
+ }
32211
+ async function startDebugSessionIn(base, { replace = false } = {}) {
32212
+ try {
32213
+ if (!await isDebugModeEnabled()) return;
32214
+ await mkdir9(join26(startSession(resolve26(base), { replace }), "debug"), { recursive: true });
32215
+ } catch {
32216
+ }
32217
+ }
32218
+ function nextImportRunDir(session) {
32219
+ const existing = existsSync11(session) ? readdirSync4(session) : [];
32220
+ const maxRun = existing.reduce((max, entry) => {
32221
+ const match2 = /^dsi-import-(\d+)$/.exec(entry);
32222
+ return match2 ? Math.max(max, Number(match2[1])) : max;
32223
+ }, 0);
32224
+ return join26(session, `dsi-import-${maxRun + 1}`);
32225
+ }
32226
+ async function startImportRun(projectPath) {
32227
+ await startDebugSessionIn(projectPath);
32228
+ if (!sessionDir) return join26(resolve26(projectPath), ".contentful");
32229
+ const dir = nextImportRunDir(sessionDir);
32230
+ await mkdir9(dir, { recursive: true });
32231
+ return dir;
32167
32232
  }
32168
32233
  async function isDebugModeEnabled() {
32169
32234
  try {
@@ -32204,8 +32269,10 @@ async function finishDebugRun({
32204
32269
  pendingRun = void 0;
32205
32270
  const durationMs = Date.now() - run.startedAt;
32206
32271
  const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
32272
+ const root = currentDebugSessionDir();
32273
+ if (!root) return;
32207
32274
  const flowSegments = run.flow.split("/");
32208
- const dir = join26(sessionDebugDir(), ...flowSegments);
32275
+ const dir = join26(root, ...flowSegments);
32209
32276
  await mkdir9(dir, { recursive: true });
32210
32277
  const filename = nextAttemptFilename(dir, run.menuOption);
32211
32278
  await writeFile8(join26(dir, filename), content, { mode: 384 });
@@ -32252,17 +32319,16 @@ ${JSON.stringify(finish.outputs, null, 2)}
32252
32319
  function handleCrash() {
32253
32320
  return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
32254
32321
  }
32255
- var pendingRun, SESSION_ID;
32322
+ var pendingRun, sessionDir;
32256
32323
  var init_debug_store = __esm({
32257
32324
  "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
32258
32325
  "use strict";
32259
32326
  init_config();
32260
32327
  init_version();
32261
32328
  init_debug_mode_store();
32262
- SESSION_ID = generateSessionId3();
32263
- void isDebugModeEnabled().then((enabled) => {
32264
- if (!enabled) return void 0;
32265
- return mkdir9(sessionDebugDir(), { recursive: true });
32329
+ void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
32330
+ if (!enabled || !base) return void 0;
32331
+ return mkdir9(join26(startSession(base, { replace: false }), "debug"), { recursive: true });
32266
32332
  });
32267
32333
  process.once("uncaughtException", (err) => {
32268
32334
  void handleCrash().finally(() => {
@@ -32288,8 +32354,7 @@ async function readHelpInfo() {
32288
32354
  return {
32289
32355
  storage: [
32290
32356
  { label: "Config folder", value: configRoot2() },
32291
- { label: "Settings file", value: configFilePath2() },
32292
- { label: "Debug logs", value: debugSessionsDir2() }
32357
+ { label: "Settings file", value: configFilePath2() }
32293
32358
  ],
32294
32359
  troubleshooting: [
32295
32360
  { label: "CLI version", value: readPackageVersion() },
@@ -32298,7 +32363,7 @@ async function readHelpInfo() {
32298
32363
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
32299
32364
  {
32300
32365
  label: "This session",
32301
- value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
32366
+ 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"
32302
32367
  }
32303
32368
  ]
32304
32369
  };
@@ -32455,7 +32520,8 @@ async function readCredentials() {
32455
32520
  cmaToken: store.cmaToken || "",
32456
32521
  host: store.host || "",
32457
32522
  defaultComponentDir: store.defaultComponentDir || "",
32458
- defaultTokenFile: store.defaultTokenFile || ""
32523
+ defaultTokenFile: store.defaultTokenFile || "",
32524
+ contentfulBaseDir: store.contentfulBaseDir || ""
32459
32525
  };
32460
32526
  }
32461
32527
  async function writeCredentials(config) {
@@ -32488,7 +32554,8 @@ function debugFields(config) {
32488
32554
  cma_token: config?.cmaToken ?? "",
32489
32555
  host: config?.host ?? "",
32490
32556
  default_component_dir: config?.defaultComponentDir ?? "",
32491
- default_token_file: config?.defaultTokenFile ?? ""
32557
+ default_token_file: config?.defaultTokenFile ?? "",
32558
+ contentful_base_dir: config?.contentfulBaseDir ?? ""
32492
32559
  };
32493
32560
  }
32494
32561
  function ConfigurationScreen({ onDone }) {
@@ -32526,6 +32593,7 @@ function ConfigurationScreen({ onDone }) {
32526
32593
  setNotice(null);
32527
32594
  writeCredentials(config).then(() => {
32528
32595
  setLastSaved(config);
32596
+ if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir, { replace: true });
32529
32597
  setNotice({ kind: "success", text: "Configuration saved" });
32530
32598
  setStage("form");
32531
32599
  }).catch((err) => {
@@ -32591,10 +32659,7 @@ function ConfigurationScreen({ onDone }) {
32591
32659
  const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
32592
32660
  return /* @__PURE__ */ jsxs45(Box44, { gap: 1, children: [
32593
32661
  /* @__PURE__ */ jsx55(Text46, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
32594
- /* @__PURE__ */ jsxs45(Text46, { bold: isActive, children: [
32595
- FIELD_LABELS[field],
32596
- ":"
32597
- ] }),
32662
+ /* @__PURE__ */ jsx55(Box44, { width: LABEL_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx55(Text46, { bold: isActive, color: isActive ? PALETTE.accent : PALETTE.muted, children: FIELD_LABELS[field] }) }),
32598
32663
  isActive && editing ? /* @__PURE__ */ jsx55(
32599
32664
  TextInput4,
32600
32665
  {
@@ -32603,7 +32668,8 @@ function ConfigurationScreen({ onDone }) {
32603
32668
  onSubmit: () => setEditing(false),
32604
32669
  mask: field === "cmaToken" ? "\u2022" : void 0
32605
32670
  }
32606
- ) : /* @__PURE__ */ jsx55(Text46, { children: display || /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" }) })
32671
+ ) : /* @__PURE__ */ jsx55(Text46, { bold: !!display, children: display || (FIELD_HINTS[field] ? "" : /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: "(empty)" })) }),
32672
+ FIELD_HINTS[field] && /* @__PURE__ */ jsx55(Text46, { color: PALETTE.muted, children: FIELD_HINTS[field] })
32607
32673
  ] }, field);
32608
32674
  }) }),
32609
32675
  notice && /* @__PURE__ */ jsxs45(Fragment17, { children: [
@@ -32634,7 +32700,7 @@ function ConfigurationScreen({ onDone }) {
32634
32700
  )
32635
32701
  ] });
32636
32702
  }
32637
- var FIELD_ORDER, FIELD_LABELS;
32703
+ var FIELD_ORDER, FIELD_LABELS, FIELD_HINTS, LABEL_WIDTH;
32638
32704
  var init_ContentfulConfigScreen = __esm({
32639
32705
  "packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx"() {
32640
32706
  "use strict";
@@ -32648,16 +32714,22 @@ var init_ContentfulConfigScreen = __esm({
32648
32714
  "cmaToken",
32649
32715
  "host",
32650
32716
  "defaultComponentDir",
32651
- "defaultTokenFile"
32717
+ "defaultTokenFile",
32718
+ "contentfulBaseDir"
32652
32719
  ];
32653
32720
  FIELD_LABELS = {
32654
32721
  spaceId: "Space ID",
32655
32722
  environmentId: "Environment ID",
32656
32723
  cmaToken: "CMA Token",
32657
- host: "API Host (optional)",
32658
- defaultComponentDir: "Default component directory (optional)",
32659
- defaultTokenFile: "Default token file (optional)"
32724
+ host: "API Host",
32725
+ defaultComponentDir: "Default component directory",
32726
+ defaultTokenFile: "Default token file",
32727
+ contentfulBaseDir: "Root Project Directory"
32728
+ };
32729
+ FIELD_HINTS = {
32730
+ contentfulBaseDir: "(where .contentful goes)"
32660
32731
  };
32732
+ LABEL_WIDTH = Math.max(...Object.values(FIELD_LABELS).map((label) => label.length));
32661
32733
  }
32662
32734
  });
32663
32735
 
@@ -32951,7 +33023,7 @@ function App({ importOptions, inkClear }) {
32951
33023
  const launch = { projectPath: projectPath2, tokens, filePaths, ...importOptions };
32952
33024
  const state = await inspectTokens({
32953
33025
  rawTokensPath: tokens,
32954
- outDir: join27(resolveUserPath(projectPath2), ".contentful"),
33026
+ contentfulDir: join27(resolveUserPath(projectPath2), ".contentful"),
32955
33027
  cache: importOptions.cache
32956
33028
  });
32957
33029
  if (state.kind === "cached") {
@@ -32972,6 +33044,7 @@ function App({ importOptions, inkClear }) {
32972
33044
  const settings = await readSettings2();
32973
33045
  const { agent, agentModel } = resolveAgentChoice(launch.agent, settings);
32974
33046
  const generatePromptPath = typeof settings.generatePromptPath === "string" ? settings.generatePromptPath : void 0;
33047
+ const outDir = await (await Promise.resolve().then(() => (init_debug_store(), debug_store_exports))).startImportRun(resolveUserPath(launch.projectPath ?? ""));
32975
33048
  setExtractionRun({
32976
33049
  ...generatePromptPath ? { generatePromptPath } : {},
32977
33050
  // the later steps get the same agent, so they use what the stage used
@@ -32980,6 +33053,7 @@ function App({ importOptions, inkClear }) {
32980
33053
  tokenStrategy,
32981
33054
  input: {
32982
33055
  projectPath: resolveUserPath(launch.projectPath ?? ""),
33056
+ outDir,
32983
33057
  filePaths: launch.filePaths ?? [],
32984
33058
  rawTokensPath: launch.tokens ?? "",
32985
33059
  tokenStrategy,
@@ -33326,14 +33400,14 @@ function runDevWatch(args) {
33326
33400
  process.stderr.write("--watch only works from a checkout of the repo (scripts/dev.mjs is not in the package).\n");
33327
33401
  return Promise.resolve(1);
33328
33402
  }
33329
- return new Promise((resolve25) => {
33403
+ return new Promise((resolve27) => {
33330
33404
  const child = spawn2(process.execPath, [script, ...args], { stdio: "inherit" });
33331
33405
  process.on("SIGINT", () => void 0);
33332
- child.on("exit", (code) => resolve25(code ?? 0));
33406
+ child.on("exit", (code) => resolve27(code ?? 0));
33333
33407
  child.on("error", (err) => {
33334
33408
  process.stderr.write(`${err.message}
33335
33409
  `);
33336
- resolve25(1);
33410
+ resolve27(1);
33337
33411
  });
33338
33412
  });
33339
33413
  }
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-bdf99669.0",
3
+ "version": "2.37.1-dev-build-6bfb243f.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +1,23 @@
1
1
  type Status = 'success' | 'error';
2
2
  type ExitMethod = 'saved' | 'discarded' | 'crashed';
3
- export declare function currentDebugSessionDir(): string;
3
+ export declare function currentDebugSessionDir(): string | undefined;
4
+ /** This terminal session's folder, `<base>/.contentful/<session>/`, or undefined until it is known. */
5
+ export declare function currentSessionDir(): string | undefined;
6
+ /**
7
+ * Starts this terminal session's folder in `base`. The base directory setting being saved passes `replace` so the new
8
+ * location wins; the import passes nothing and only starts a session when none exists yet. Fail-open like the rest of
9
+ * the logger.
10
+ */
11
+ export declare function startDebugSessionIn(base: string, { replace }?: {
12
+ replace?: boolean | undefined;
13
+ }): Promise<void>;
14
+ /**
15
+ * Where this import run writes everything it produces (tokens.json, .existing-entities.json, components.json): a new
16
+ * `dsi-import-N` folder in this session's folder, next to the debug logs. The session is started here, and waited for,
17
+ * so the answer does not depend on how quickly the boot-time start finished. Without a session (Debug Mode off, or a
18
+ * folder that cannot be created) the files stay in `<project>/.contentful`, as before.
19
+ */
20
+ export declare function startImportRun(projectPath: string): Promise<string>;
4
21
  export declare function startDebugRun({ flow, step, menuOption, inputs, }: {
5
22
  flow: string;
6
23
  step: string;
@@ -8,10 +8,11 @@ export type TokensState = {
8
8
  };
9
9
  interface InspectInput {
10
10
  rawTokensPath: string;
11
- outDir: string;
11
+ /** The `.contentful` folder: the sessions' `dsi-import` folders sit inside it, and an older `tokens.json` may sit in it. */
12
+ contentfulDir: string;
12
13
  cache: boolean;
13
14
  }
14
- export declare function inspectTokens({ rawTokensPath, outDir, cache }: InspectInput): Promise<TokensState>;
15
+ export declare function inspectTokens({ rawTokensPath, contentfulDir, cache }: InspectInput): Promise<TokensState>;
15
16
  export declare function gateText({ tokensPath, sourceChanged }: {
16
17
  tokensPath: string;
17
18
  sourceChanged: boolean;
@@ -2,6 +2,8 @@ import type { ExtractionHandoff, ImportHandoff } from '@contentful/experience-de
2
2
  export type TokenStrategy = ImportHandoff['tokens']['strategy'];
3
3
  export interface ExtractionInput {
4
4
  projectPath: string;
5
+ /** Where the stage writes tokens.json and the other files. Defaults to `<projectPath>/.contentful`. */
6
+ outDir?: string;
5
7
  /** Absolute source files from the path-validation step (collectFiles output). */
6
8
  filePaths: string[];
7
9
  /** Raw tokens file the user pointed at (always set: v2 asks for one). */
@@ -5,6 +5,7 @@ export type V1Credentials = {
5
5
  host?: string;
6
6
  defaultComponentDir?: string;
7
7
  defaultTokenFile?: string;
8
+ contentfulBaseDir?: string;
8
9
  [key: string]: string | undefined;
9
10
  };
10
11
  export declare function readCredentials(): Promise<V1Credentials>;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-bdf99669.0",
3
+ "version": "2.37.1-dev-build-6bfb243f.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.37.1-dev-build-bdf99669.0",
3
+ "version": "2.37.1-dev-build-6bfb243f.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,8 +45,8 @@
45
45
  "ts-morph": "^27.0.2",
46
46
  "typescript": "^5.9.3",
47
47
  "zod": "^4.6.5",
48
- "@contentful/experience-design-system-backend-pipeline": "2.37.1-dev-build-bdf99669.0",
49
- "@contentful/experience-design-system-types": "2.37.1-dev-build-bdf99669.0"
48
+ "@contentful/experience-design-system-backend-pipeline": "2.37.1-dev-build-6bfb243f.0",
49
+ "@contentful/experience-design-system-types": "2.37.1-dev-build-6bfb243f.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@tsconfig/node24": "^24.0.4",