@contentful/experience-design-system-cli 2.37.1-dev-build-e051d273.0 → 2.37.1-dev-build-bdab4dbe.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
@@ -2135,14 +2135,14 @@ var init_debug_mode_store = __esm({
2135
2135
  "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
2136
2136
  "use strict";
2137
2137
  init_config();
2138
- RETENTION_CHOICES = [30, 60, 90];
2138
+ RETENTION_CHOICES = [3, 14, 30];
2139
2139
  DEFAULT_RETENTION_DAYS = 30;
2140
2140
  }
2141
2141
  });
2142
2142
 
2143
2143
  // packages/experience-design-system-cli/src/tui/debug-prune.ts
2144
- import { readdir as readdir3, rm, stat as stat5 } from "node:fs/promises";
2145
- import { join as join24 } from "node:path";
2144
+ import { readdir as readdir3, rm, rmdir, stat as stat5 } from "node:fs/promises";
2145
+ import { dirname as dirname16, join as join24 } from "node:path";
2146
2146
  async function logFilesIn(dir) {
2147
2147
  const entries = await readdir3(dir, { withFileTypes: true });
2148
2148
  const nested = await Promise.all(
@@ -2154,10 +2154,24 @@ async function logFilesIn(dir) {
2154
2154
  );
2155
2155
  return nested.flat();
2156
2156
  }
2157
+ async function removeEmptyFolders(from, stop) {
2158
+ let dir = from;
2159
+ let removed = 0;
2160
+ for (; ; ) {
2161
+ try {
2162
+ await rmdir(dir);
2163
+ } catch {
2164
+ return removed;
2165
+ }
2166
+ removed += 1;
2167
+ if (dir === stop) return removed;
2168
+ dir = dirname16(dir);
2169
+ }
2170
+ }
2157
2171
  async function pruneExpiredLogs(base, retentionDays, now = Date.now()) {
2158
2172
  const cutoff = now - retentionDays * DAY_MS;
2159
2173
  const contentfulDir = join24(base, ".contentful");
2160
- let deleted = 0;
2174
+ const result = { logs: 0, folders: 0 };
2161
2175
  try {
2162
2176
  const sessions = (await readdir3(contentfulDir)).filter((name) => SESSION_FOLDER.test(name));
2163
2177
  for (const session of sessions) {
@@ -2166,14 +2180,15 @@ async function pruneExpiredLogs(base, retentionDays, now = Date.now()) {
2166
2180
  try {
2167
2181
  if ((await stat5(file)).mtimeMs >= cutoff) continue;
2168
2182
  await rm(file);
2169
- deleted += 1;
2183
+ result.logs += 1;
2184
+ result.folders += await removeEmptyFolders(dirname16(file), join24(contentfulDir, session));
2170
2185
  } catch {
2171
2186
  }
2172
2187
  }
2173
2188
  }
2174
2189
  } catch {
2175
2190
  }
2176
- return deleted;
2191
+ return result;
2177
2192
  }
2178
2193
  var DAY_MS, SESSION_FOLDER;
2179
2194
  var init_debug_prune = __esm({
@@ -2359,8 +2374,24 @@ var init_debug_store = __esm({
2359
2374
  init_debug_prune();
2360
2375
  void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(async ([enabled, base]) => {
2361
2376
  if (!base) return;
2362
- await readDebugModeSetting().then(({ retentionDays }) => pruneExpiredLogs(base, retentionDays)).catch(() => void 0);
2363
- if (enabled) await mkdir9(join25(startSession(base, { replace: false }), "debug"), { recursive: true });
2377
+ const retention = await readDebugModeSetting().catch(() => void 0);
2378
+ const pruned = retention ? await pruneExpiredLogs(base, retention.retentionDays).catch(() => void 0) : void 0;
2379
+ if (!enabled) return;
2380
+ const debugDir = join25(startSession(base, { replace: false }), "debug");
2381
+ await mkdir9(debugDir, { recursive: true });
2382
+ if (retention && pruned && pruned.logs + pruned.folders > 0) {
2383
+ await writeFile8(
2384
+ join25(debugDir, `${datePrefix()}-cleanup-${generateRunId()}.md`),
2385
+ `# Debug Log Cleanup
2386
+
2387
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2388
+ - Retention: ${retention.retentionDays} days
2389
+ - Logs deleted: ${pruned.logs}
2390
+ - Empty folders removed: ${pruned.folders}
2391
+ `,
2392
+ { mode: 384 }
2393
+ );
2394
+ }
2364
2395
  });
2365
2396
  process.once("uncaughtException", (err) => {
2366
2397
  void handleCrash().finally(() => {
@@ -2610,13 +2641,25 @@ function useWelcomeControls(onQuit) {
2610
2641
 
2611
2642
  // packages/experience-design-system-cli/src/tui/import/steps/01-welcome/screen.tsx
2612
2643
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
2613
- var RULE = "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
2644
+ var OVERVIEW_BOX_MAX_WIDTH = 90;
2645
+ var AI_MARKER = "\u273B";
2614
2646
  var OVERVIEW = [
2615
- { label: "Step 1", description: "Extract components from your codebase" },
2616
- { label: "Step 2", description: "Review what was extracted" },
2617
- { label: "Step 3", description: "Generate CDF definitions with Claude" },
2618
- { label: "Step 4", description: "Review generated definitions" },
2619
- { label: "Step 5", description: "Push to Contentful" }
2647
+ {
2648
+ label: "Step 1",
2649
+ description: "Extract components from your codebase",
2650
+ ai: true
2651
+ },
2652
+ { label: "Step 2", description: "Review what was extracted", ai: false },
2653
+ {
2654
+ label: "Step 3",
2655
+ description: "Generate component definitions",
2656
+ ai: true
2657
+ },
2658
+ { label: "Step 4", description: "Review generated definitions", ai: false },
2659
+ { label: "Step 5", description: "Push to Contentful", ai: false }
2660
+ ];
2661
+ var AI_DISCLOSURE = [
2662
+ "Steps marked \u273B use your local AI agent, which may send relevant code to your AI provider under your agreement with them. Contentful does not receive that code, or the prompts and responses. AI suggestions can be wrong or incomplete, so review and edit them before importing."
2620
2663
  ];
2621
2664
  function WelcomeScreen({ onContinue, onQuit, initialPath = "" }) {
2622
2665
  const [projectPath, setProjectPath] = useState3(initialPath);
@@ -2626,18 +2669,37 @@ function WelcomeScreen({ onContinue, onQuit, initialPath = "" }) {
2626
2669
  if (path5) onContinue(path5);
2627
2670
  };
2628
2671
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
2629
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.success, children: "Let's import your design system into Contentful." }),
2630
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
2631
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: RULE }),
2632
- OVERVIEW.map((item) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
2633
- /* @__PURE__ */ jsx4(Text4, { bold: true, children: item.label }),
2634
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: item.description })
2635
- ] }, item.label)),
2636
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: RULE })
2637
- ] }),
2672
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.accent, children: "Let's import your design system into Contentful." }),
2673
+ /* @__PURE__ */ jsx4(Box3, { flexDirection: "row", children: /* @__PURE__ */ jsxs3(
2674
+ Box3,
2675
+ {
2676
+ flexDirection: "column",
2677
+ borderStyle: "round",
2678
+ borderColor: PALETTE.border,
2679
+ paddingX: 2,
2680
+ paddingY: 1,
2681
+ width: OVERVIEW_BOX_MAX_WIDTH,
2682
+ flexShrink: 1,
2683
+ children: [
2684
+ OVERVIEW.map((item) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
2685
+ /* @__PURE__ */ jsx4(Box3, { flexShrink: 0, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: item.label }) }),
2686
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, wrap: "truncate-end", children: item.description }),
2687
+ item.ai && /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.accent, children: AI_MARKER })
2688
+ ] }, item.label)),
2689
+ /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
2690
+ /* @__PURE__ */ jsxs3(Text4, { bold: true, children: [
2691
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.accent, children: AI_MARKER }),
2692
+ " AI disclosure"
2693
+ ] }),
2694
+ AI_DISCLOSURE.map((paragraph) => /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: paragraph }, paragraph))
2695
+ ] })
2696
+ ]
2697
+ }
2698
+ ) }),
2638
2699
  /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, children: [
2639
2700
  /* @__PURE__ */ jsx4(Text4, { children: "Where is your component library?" }),
2640
2701
  /* @__PURE__ */ jsxs3(Box3, { children: [
2702
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.accent, children: "? " }),
2641
2703
  /* @__PURE__ */ jsx4(Text4, { children: "Project path: " }),
2642
2704
  /* @__PURE__ */ jsx4(TextInput, { value: projectPath, onChange: setProjectPath, onSubmit: submit })
2643
2705
  ] })
@@ -17076,7 +17138,7 @@ function useElapsed() {
17076
17138
 
17077
17139
  // packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx
17078
17140
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
17079
- var RULE2 = "\u2500".repeat(40);
17141
+ var RULE = "\u2500".repeat(40);
17080
17142
  function Line({ line }) {
17081
17143
  if (line.progress) {
17082
17144
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
@@ -17106,9 +17168,9 @@ function RunningStep({
17106
17168
  const elapsed = useElapsed();
17107
17169
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
17108
17170
  /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
17109
- /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE2 }),
17171
+ /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE }),
17110
17172
  /* @__PURE__ */ jsx10(Text10, { bold: true, children: stepLabel(stepNumber, totalSteps, title) }),
17111
- /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE2 })
17173
+ /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE })
17112
17174
  ] }),
17113
17175
  /* @__PURE__ */ jsx10(Text10, { children: description }),
17114
17176
  /* @__PURE__ */ jsx10(Box9, { marginTop: 1, flexDirection: "column", gap: 1, children: lines.map((line, index) => /* @__PURE__ */ jsx10(Line, { line }, index)) }),
@@ -29233,19 +29295,29 @@ function OptInAnalyticsScreen({ onDone }) {
29233
29295
  }
29234
29296
 
29235
29297
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
29236
- import { useEffect as useEffect26, useState as useState35 } from "react";
29298
+ import { useEffect as useEffect26, useRef as useRef15, useState as useState35 } from "react";
29237
29299
  import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
29238
29300
  init_debug_mode_store();
29239
29301
  init_debug_store();
29240
29302
  import { Fragment as Fragment21, jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
29241
29303
  var ROWS = ["enabled", "retentionDays"];
29242
- var nextRetention = (current) => RETENTION_CHOICES[(RETENTION_CHOICES.indexOf(current) + 1) % RETENTION_CHOICES.length];
29304
+ var snapshotOf2 = (setting) => ({
29305
+ enabled: String(setting.enabled),
29306
+ retentionDays: String(setting.retentionDays)
29307
+ });
29243
29308
  function DebugModeScreen({ onDone }) {
29244
29309
  const [setting, setSetting] = useState35(null);
29245
29310
  const [focus, setFocus] = useState35("enabled");
29311
+ const [pending, setPending] = useState35(
29312
+ RETENTION_CHOICES[RETENTION_CHOICES.length - 1]
29313
+ );
29314
+ const [notice, setNotice] = useState35(null);
29315
+ const visit = useRef15({ trail: createTrail(), before: void 0, error: "" }).current;
29246
29316
  useEffect26(() => {
29247
29317
  readDebugModeSetting().then((loaded) => {
29248
29318
  setSetting(loaded);
29319
+ setPending(loaded.retentionDays);
29320
+ visit.before = snapshotOf2(loaded);
29249
29321
  startDebugRun({
29250
29322
  flow: "settings/debug-mode",
29251
29323
  step: "01-debug-mode",
@@ -29254,49 +29326,95 @@ function DebugModeScreen({ onDone }) {
29254
29326
  });
29255
29327
  });
29256
29328
  }, []);
29257
- const change = (patch) => {
29329
+ const save = (patch, saved) => {
29258
29330
  if (!setting) return;
29259
- setSetting({ ...setting, ...patch });
29260
- void writeDebugModeSetting(patch);
29331
+ const fields2 = Object.keys(patch).join(", ");
29332
+ writeDebugModeSetting(patch).then(() => {
29333
+ setSetting({ ...setting, ...patch });
29334
+ visit.trail.record(`saved ${fields2}`);
29335
+ setNotice({ kind: "success", text: `Saved: ${saved}` });
29336
+ }).catch((err) => {
29337
+ visit.error = scrubError(err, []);
29338
+ visit.trail.record(`saving ${fields2} failed`);
29339
+ setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` });
29340
+ });
29341
+ };
29342
+ const endVisit = (current) => {
29343
+ const change = diffSnapshots(visit.before ?? snapshotOf2(current), snapshotOf2(current));
29344
+ void finishDebugRun({
29345
+ outputs: {
29346
+ ...current,
29347
+ ...change,
29348
+ ...pending !== current.retentionDays ? { unsaved_retention_days: pending } : {},
29349
+ actions: visit.trail.entries(),
29350
+ ...visit.error ? { error: visit.error } : {}
29351
+ },
29352
+ status: visit.error ? "error" : "success",
29353
+ exitMethod: change.changed ? "saved" : "discarded"
29354
+ });
29261
29355
  };
29262
29356
  useInput16((input, key) => {
29263
29357
  if (!setting) return;
29264
29358
  if (key.upArrow || key.downArrow) {
29265
29359
  setFocus((current) => ROWS[(ROWS.indexOf(current) + (key.downArrow ? 1 : ROWS.length - 1)) % ROWS.length]);
29360
+ setNotice(null);
29266
29361
  return;
29267
29362
  }
29268
- if (key.return || input === " ") {
29269
- if (focus === "enabled") change({ enabled: !setting.enabled });
29270
- else change({ retentionDays: nextRetention(setting.retentionDays) });
29363
+ if ((key.leftArrow || key.rightArrow) && focus === "retentionDays") {
29364
+ const index = RETENTION_CHOICES.indexOf(pending) + (key.rightArrow ? 1 : -1);
29365
+ setPending(RETENTION_CHOICES[Math.min(Math.max(index, 0), RETENTION_CHOICES.length - 1)]);
29366
+ setNotice(null);
29367
+ return;
29368
+ }
29369
+ if (focus === "enabled" && (key.return || input === " ")) {
29370
+ const enabled = !setting.enabled;
29371
+ save({ enabled }, `debug logging is ${enabled ? "on" : "off"}`);
29372
+ return;
29373
+ }
29374
+ if (focus === "retentionDays" && key.return) {
29375
+ save({ retentionDays: pending }, `logs are deleted after ${pending} days`);
29271
29376
  return;
29272
29377
  }
29273
29378
  if (key.escape || input === "q") {
29274
- void finishDebugRun({ outputs: { ...setting }, status: "success", exitMethod: "saved" });
29379
+ endVisit(setting);
29275
29380
  onDone();
29276
29381
  }
29277
29382
  });
29278
- const marker = (row) => focus === row ? "\u276F" : " ";
29383
+ const marker = (row) => /* @__PURE__ */ jsx62(Text53, { color: focus === row ? PALETTE.accent : void 0, children: focus === row ? "\u276F" : " " });
29384
+ const label = (row, text) => /* @__PURE__ */ jsx62(Text53, { bold: focus === row, color: focus === row ? PALETTE.accent : PALETTE.muted, children: text });
29279
29385
  return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
29280
29386
  /* @__PURE__ */ jsx62(Text53, { bold: true, children: "Settings \u203A Debug Mode" }),
29281
29387
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
29282
29388
  setting ? /* @__PURE__ */ jsxs51(Fragment21, { children: [
29283
- /* @__PURE__ */ jsxs51(Text53, { children: [
29389
+ /* @__PURE__ */ jsxs51(Box50, { gap: 1, children: [
29284
29390
  marker("enabled"),
29285
- " Debug logging:",
29286
- " ",
29391
+ label("enabled", "Debug logging:"),
29287
29392
  /* @__PURE__ */ jsx62(Text53, { bold: true, color: setting.enabled ? PALETTE.success : PALETTE.muted, children: setting.enabled ? "On" : "Off" })
29288
29393
  ] }),
29289
- /* @__PURE__ */ jsxs51(Text53, { children: [
29394
+ /* @__PURE__ */ jsxs51(Box50, { gap: 1, children: [
29290
29395
  marker("retentionDays"),
29291
- " Delete logs after:",
29292
- " ",
29293
- /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.accent, children: [
29294
- setting.retentionDays,
29295
- " days"
29296
- ] })
29396
+ label("retentionDays", "Delete logs after:"),
29397
+ RETENTION_CHOICES.map((days) => {
29398
+ const highlighted = focus === "retentionDays" && days === pending;
29399
+ const saved = days === setting.retentionDays;
29400
+ return /* @__PURE__ */ jsx62(
29401
+ Text53,
29402
+ {
29403
+ bold: highlighted || saved,
29404
+ underline: highlighted,
29405
+ color: highlighted ? PALETTE.accent : saved ? PALETTE.success : PALETTE.muted,
29406
+ children: `${saved ? "\u2713 " : ""}${days} days`
29407
+ },
29408
+ days
29409
+ );
29410
+ })
29297
29411
  ] }),
29298
29412
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
29299
- /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Older logs are deleted the next time the CLI starts." })
29413
+ notice ? /* @__PURE__ */ jsxs51(Text53, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
29414
+ notice.kind === "success" ? "\u2713" : "\u2717",
29415
+ " ",
29416
+ notice.text
29417
+ ] }) : /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "\u2713 marks what is saved. Older logs are deleted the next time the CLI starts." })
29300
29418
  ] }) : /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Loading\u2026" }),
29301
29419
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
29302
29420
  /* @__PURE__ */ jsx62(
@@ -29304,7 +29422,10 @@ function DebugModeScreen({ onDone }) {
29304
29422
  {
29305
29423
  hints: [
29306
29424
  { keys: "\u2191/\u2193", label: "move" },
29307
- { keys: "\u23CE/Space", label: "change" },
29425
+ ...focus === "retentionDays" ? [
29426
+ { keys: "\u2190/\u2192", label: "choose" },
29427
+ { keys: "\u23CE", label: "save" }
29428
+ ] : [{ keys: "\u23CE/Space", label: "toggle" }],
29308
29429
  { keys: "Esc/q", label: "back" }
29309
29430
  ]
29310
29431
  }
package/dist/index.js CHANGED
@@ -18561,18 +18561,37 @@ function WelcomeScreen({ onContinue, onQuit, initialPath = "" }) {
18561
18561
  if (path5) onContinue(path5);
18562
18562
  };
18563
18563
  return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
18564
- /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.success, children: "Let's import your design system into Contentful." }),
18565
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
18566
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: RULE }),
18567
- OVERVIEW.map((item) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
18568
- /* @__PURE__ */ jsx4(Text4, { bold: true, children: item.label }),
18569
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: item.description })
18570
- ] }, item.label)),
18571
- /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: RULE })
18572
- ] }),
18564
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.accent, children: "Let's import your design system into Contentful." }),
18565
+ /* @__PURE__ */ jsx4(Box3, { flexDirection: "row", children: /* @__PURE__ */ jsxs3(
18566
+ Box3,
18567
+ {
18568
+ flexDirection: "column",
18569
+ borderStyle: "round",
18570
+ borderColor: PALETTE.border,
18571
+ paddingX: 2,
18572
+ paddingY: 1,
18573
+ width: OVERVIEW_BOX_MAX_WIDTH,
18574
+ flexShrink: 1,
18575
+ children: [
18576
+ OVERVIEW.map((item) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
18577
+ /* @__PURE__ */ jsx4(Box3, { flexShrink: 0, children: /* @__PURE__ */ jsx4(Text4, { bold: true, children: item.label }) }),
18578
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, wrap: "truncate-end", children: item.description }),
18579
+ item.ai && /* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.accent, children: AI_MARKER })
18580
+ ] }, item.label)),
18581
+ /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
18582
+ /* @__PURE__ */ jsxs3(Text4, { bold: true, children: [
18583
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.accent, children: AI_MARKER }),
18584
+ " AI disclosure"
18585
+ ] }),
18586
+ AI_DISCLOSURE.map((paragraph) => /* @__PURE__ */ jsx4(Text4, { color: PALETTE.muted, children: paragraph }, paragraph))
18587
+ ] })
18588
+ ]
18589
+ }
18590
+ ) }),
18573
18591
  /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, children: [
18574
18592
  /* @__PURE__ */ jsx4(Text4, { children: "Where is your component library?" }),
18575
18593
  /* @__PURE__ */ jsxs3(Box3, { children: [
18594
+ /* @__PURE__ */ jsx4(Text4, { color: PALETTE.accent, children: "? " }),
18576
18595
  /* @__PURE__ */ jsx4(Text4, { children: "Project path: " }),
18577
18596
  /* @__PURE__ */ jsx4(TextInput, { value: projectPath, onChange: setProjectPath, onSubmit: submit })
18578
18597
  ] })
@@ -18585,20 +18604,32 @@ function WelcomeScreen({ onContinue, onQuit, initialPath = "" }) {
18585
18604
  ] }, control.keys)) })
18586
18605
  ] });
18587
18606
  }
18588
- var RULE, OVERVIEW;
18607
+ var OVERVIEW_BOX_MAX_WIDTH, AI_MARKER, OVERVIEW, AI_DISCLOSURE;
18589
18608
  var init_screen = __esm({
18590
18609
  "packages/experience-design-system-cli/src/tui/import/steps/01-welcome/screen.tsx"() {
18591
18610
  "use strict";
18592
18611
  init_theme();
18593
18612
  init_controls();
18594
18613
  init_logic();
18595
- RULE = "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
18614
+ OVERVIEW_BOX_MAX_WIDTH = 90;
18615
+ AI_MARKER = "\u273B";
18596
18616
  OVERVIEW = [
18597
- { label: "Step 1", description: "Extract components from your codebase" },
18598
- { label: "Step 2", description: "Review what was extracted" },
18599
- { label: "Step 3", description: "Generate CDF definitions with Claude" },
18600
- { label: "Step 4", description: "Review generated definitions" },
18601
- { label: "Step 5", description: "Push to Contentful" }
18617
+ {
18618
+ label: "Step 1",
18619
+ description: "Extract components from your codebase",
18620
+ ai: true
18621
+ },
18622
+ { label: "Step 2", description: "Review what was extracted", ai: false },
18623
+ {
18624
+ label: "Step 3",
18625
+ description: "Generate component definitions",
18626
+ ai: true
18627
+ },
18628
+ { label: "Step 4", description: "Review generated definitions", ai: false },
18629
+ { label: "Step 5", description: "Push to Contentful", ai: false }
18630
+ ];
18631
+ AI_DISCLOSURE = [
18632
+ "Steps marked \u273B use your local AI agent, which may send relevant code to your AI provider under your agreement with them. Contentful does not receive that code, or the prompts and responses. AI suggestions can be wrong or incomplete, so review and edit them before importing."
18602
18633
  ];
18603
18634
  }
18604
18635
  });
@@ -19429,9 +19460,9 @@ function RunningStep({
19429
19460
  const elapsed = useElapsed();
19430
19461
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
19431
19462
  /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
19432
- /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE2 }),
19463
+ /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE }),
19433
19464
  /* @__PURE__ */ jsx10(Text10, { bold: true, children: stepLabel(stepNumber, totalSteps, title) }),
19434
- /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE2 })
19465
+ /* @__PURE__ */ jsx10(Text10, { color: PALETTE.muted, children: RULE })
19435
19466
  ] }),
19436
19467
  /* @__PURE__ */ jsx10(Text10, { children: description }),
19437
19468
  /* @__PURE__ */ jsx10(Box9, { marginTop: 1, flexDirection: "column", gap: 1, children: lines.map((line, index) => /* @__PURE__ */ jsx10(Line, { line }, index)) }),
@@ -19441,7 +19472,7 @@ function RunningStep({
19441
19472
  ] }) })
19442
19473
  ] });
19443
19474
  }
19444
- var RULE2;
19475
+ var RULE;
19445
19476
  var init_running_step = __esm({
19446
19477
  "packages/experience-design-system-cli/src/tui/import/shared/running-step/running-step.tsx"() {
19447
19478
  "use strict";
@@ -19449,7 +19480,7 @@ var init_running_step = __esm({
19449
19480
  init_logic7();
19450
19481
  init_theme2();
19451
19482
  init_use_elapsed();
19452
- RULE2 = "\u2500".repeat(40);
19483
+ RULE = "\u2500".repeat(40);
19453
19484
  }
19454
19485
  });
19455
19486
 
@@ -31271,14 +31302,14 @@ var init_debug_mode_store = __esm({
31271
31302
  "packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts"() {
31272
31303
  "use strict";
31273
31304
  init_config();
31274
- RETENTION_CHOICES = [30, 60, 90];
31305
+ RETENTION_CHOICES = [3, 14, 30];
31275
31306
  DEFAULT_RETENTION_DAYS = 30;
31276
31307
  }
31277
31308
  });
31278
31309
 
31279
31310
  // packages/experience-design-system-cli/src/tui/debug-prune.ts
31280
- import { readdir as readdir3, rm, stat as stat5 } from "node:fs/promises";
31281
- import { join as join25 } from "node:path";
31311
+ import { readdir as readdir3, rm, rmdir, stat as stat5 } from "node:fs/promises";
31312
+ import { dirname as dirname16, join as join25 } from "node:path";
31282
31313
  async function logFilesIn(dir) {
31283
31314
  const entries = await readdir3(dir, { withFileTypes: true });
31284
31315
  const nested = await Promise.all(
@@ -31290,10 +31321,24 @@ async function logFilesIn(dir) {
31290
31321
  );
31291
31322
  return nested.flat();
31292
31323
  }
31324
+ async function removeEmptyFolders(from, stop) {
31325
+ let dir = from;
31326
+ let removed = 0;
31327
+ for (; ; ) {
31328
+ try {
31329
+ await rmdir(dir);
31330
+ } catch {
31331
+ return removed;
31332
+ }
31333
+ removed += 1;
31334
+ if (dir === stop) return removed;
31335
+ dir = dirname16(dir);
31336
+ }
31337
+ }
31293
31338
  async function pruneExpiredLogs(base, retentionDays, now = Date.now()) {
31294
31339
  const cutoff = now - retentionDays * DAY_MS;
31295
31340
  const contentfulDir = join25(base, ".contentful");
31296
- let deleted = 0;
31341
+ const result = { logs: 0, folders: 0 };
31297
31342
  try {
31298
31343
  const sessions = (await readdir3(contentfulDir)).filter((name) => SESSION_FOLDER.test(name));
31299
31344
  for (const session of sessions) {
@@ -31302,14 +31347,15 @@ async function pruneExpiredLogs(base, retentionDays, now = Date.now()) {
31302
31347
  try {
31303
31348
  if ((await stat5(file)).mtimeMs >= cutoff) continue;
31304
31349
  await rm(file);
31305
- deleted += 1;
31350
+ result.logs += 1;
31351
+ result.folders += await removeEmptyFolders(dirname16(file), join25(contentfulDir, session));
31306
31352
  } catch {
31307
31353
  }
31308
31354
  }
31309
31355
  }
31310
31356
  } catch {
31311
31357
  }
31312
- return deleted;
31358
+ return result;
31313
31359
  }
31314
31360
  var DAY_MS, SESSION_FOLDER;
31315
31361
  var init_debug_prune = __esm({
@@ -31495,8 +31541,24 @@ var init_debug_store = __esm({
31495
31541
  init_debug_prune();
31496
31542
  void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(async ([enabled, base]) => {
31497
31543
  if (!base) return;
31498
- await readDebugModeSetting().then(({ retentionDays }) => pruneExpiredLogs(base, retentionDays)).catch(() => void 0);
31499
- if (enabled) await mkdir9(join26(startSession(base, { replace: false }), "debug"), { recursive: true });
31544
+ const retention = await readDebugModeSetting().catch(() => void 0);
31545
+ const pruned = retention ? await pruneExpiredLogs(base, retention.retentionDays).catch(() => void 0) : void 0;
31546
+ if (!enabled) return;
31547
+ const debugDir = join26(startSession(base, { replace: false }), "debug");
31548
+ await mkdir9(debugDir, { recursive: true });
31549
+ if (retention && pruned && pruned.logs + pruned.folders > 0) {
31550
+ await writeFile8(
31551
+ join26(debugDir, `${datePrefix()}-cleanup-${generateRunId()}.md`),
31552
+ `# Debug Log Cleanup
31553
+
31554
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
31555
+ - Retention: ${retention.retentionDays} days
31556
+ - Logs deleted: ${pruned.logs}
31557
+ - Empty folders removed: ${pruned.folders}
31558
+ `,
31559
+ { mode: 384 }
31560
+ );
31561
+ }
31500
31562
  });
31501
31563
  process.once("uncaughtException", (err) => {
31502
31564
  void handleCrash().finally(() => {
@@ -32813,15 +32875,22 @@ var init_screen11 = __esm({
32813
32875
  });
32814
32876
 
32815
32877
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
32816
- import { useEffect as useEffect26, useState as useState35 } from "react";
32878
+ import { useEffect as useEffect26, useRef as useRef15, useState as useState35 } from "react";
32817
32879
  import { Box as Box50, Text as Text53, useInput as useInput16 } from "ink";
32818
32880
  import { Fragment as Fragment21, jsx as jsx62, jsxs as jsxs51 } from "react/jsx-runtime";
32819
32881
  function DebugModeScreen({ onDone }) {
32820
32882
  const [setting, setSetting] = useState35(null);
32821
32883
  const [focus, setFocus] = useState35("enabled");
32884
+ const [pending, setPending] = useState35(
32885
+ RETENTION_CHOICES[RETENTION_CHOICES.length - 1]
32886
+ );
32887
+ const [notice, setNotice] = useState35(null);
32888
+ const visit = useRef15({ trail: createTrail(), before: void 0, error: "" }).current;
32822
32889
  useEffect26(() => {
32823
32890
  readDebugModeSetting().then((loaded) => {
32824
32891
  setSetting(loaded);
32892
+ setPending(loaded.retentionDays);
32893
+ visit.before = snapshotOf2(loaded);
32825
32894
  startDebugRun({
32826
32895
  flow: "settings/debug-mode",
32827
32896
  step: "01-debug-mode",
@@ -32830,49 +32899,95 @@ function DebugModeScreen({ onDone }) {
32830
32899
  });
32831
32900
  });
32832
32901
  }, []);
32833
- const change = (patch) => {
32902
+ const save = (patch, saved) => {
32834
32903
  if (!setting) return;
32835
- setSetting({ ...setting, ...patch });
32836
- void writeDebugModeSetting(patch);
32904
+ const fields2 = Object.keys(patch).join(", ");
32905
+ writeDebugModeSetting(patch).then(() => {
32906
+ setSetting({ ...setting, ...patch });
32907
+ visit.trail.record(`saved ${fields2}`);
32908
+ setNotice({ kind: "success", text: `Saved: ${saved}` });
32909
+ }).catch((err) => {
32910
+ visit.error = scrubError(err, []);
32911
+ visit.trail.record(`saving ${fields2} failed`);
32912
+ setNotice({ kind: "error", text: `Not saved: ${err instanceof Error ? err.message : String(err)}` });
32913
+ });
32914
+ };
32915
+ const endVisit = (current) => {
32916
+ const change = diffSnapshots(visit.before ?? snapshotOf2(current), snapshotOf2(current));
32917
+ void finishDebugRun({
32918
+ outputs: {
32919
+ ...current,
32920
+ ...change,
32921
+ ...pending !== current.retentionDays ? { unsaved_retention_days: pending } : {},
32922
+ actions: visit.trail.entries(),
32923
+ ...visit.error ? { error: visit.error } : {}
32924
+ },
32925
+ status: visit.error ? "error" : "success",
32926
+ exitMethod: change.changed ? "saved" : "discarded"
32927
+ });
32837
32928
  };
32838
32929
  useInput16((input, key) => {
32839
32930
  if (!setting) return;
32840
32931
  if (key.upArrow || key.downArrow) {
32841
32932
  setFocus((current) => ROWS[(ROWS.indexOf(current) + (key.downArrow ? 1 : ROWS.length - 1)) % ROWS.length]);
32933
+ setNotice(null);
32842
32934
  return;
32843
32935
  }
32844
- if (key.return || input === " ") {
32845
- if (focus === "enabled") change({ enabled: !setting.enabled });
32846
- else change({ retentionDays: nextRetention(setting.retentionDays) });
32936
+ if ((key.leftArrow || key.rightArrow) && focus === "retentionDays") {
32937
+ const index = RETENTION_CHOICES.indexOf(pending) + (key.rightArrow ? 1 : -1);
32938
+ setPending(RETENTION_CHOICES[Math.min(Math.max(index, 0), RETENTION_CHOICES.length - 1)]);
32939
+ setNotice(null);
32940
+ return;
32941
+ }
32942
+ if (focus === "enabled" && (key.return || input === " ")) {
32943
+ const enabled = !setting.enabled;
32944
+ save({ enabled }, `debug logging is ${enabled ? "on" : "off"}`);
32945
+ return;
32946
+ }
32947
+ if (focus === "retentionDays" && key.return) {
32948
+ save({ retentionDays: pending }, `logs are deleted after ${pending} days`);
32847
32949
  return;
32848
32950
  }
32849
32951
  if (key.escape || input === "q") {
32850
- void finishDebugRun({ outputs: { ...setting }, status: "success", exitMethod: "saved" });
32952
+ endVisit(setting);
32851
32953
  onDone();
32852
32954
  }
32853
32955
  });
32854
- const marker = (row) => focus === row ? "\u276F" : " ";
32956
+ const marker = (row) => /* @__PURE__ */ jsx62(Text53, { color: focus === row ? PALETTE.accent : void 0, children: focus === row ? "\u276F" : " " });
32957
+ const label = (row, text) => /* @__PURE__ */ jsx62(Text53, { bold: focus === row, color: focus === row ? PALETTE.accent : PALETTE.muted, children: text });
32855
32958
  return /* @__PURE__ */ jsxs51(Box50, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
32856
32959
  /* @__PURE__ */ jsx62(Text53, { bold: true, children: "Settings \u203A Debug Mode" }),
32857
32960
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
32858
32961
  setting ? /* @__PURE__ */ jsxs51(Fragment21, { children: [
32859
- /* @__PURE__ */ jsxs51(Text53, { children: [
32962
+ /* @__PURE__ */ jsxs51(Box50, { gap: 1, children: [
32860
32963
  marker("enabled"),
32861
- " Debug logging:",
32862
- " ",
32964
+ label("enabled", "Debug logging:"),
32863
32965
  /* @__PURE__ */ jsx62(Text53, { bold: true, color: setting.enabled ? PALETTE.success : PALETTE.muted, children: setting.enabled ? "On" : "Off" })
32864
32966
  ] }),
32865
- /* @__PURE__ */ jsxs51(Text53, { children: [
32967
+ /* @__PURE__ */ jsxs51(Box50, { gap: 1, children: [
32866
32968
  marker("retentionDays"),
32867
- " Delete logs after:",
32868
- " ",
32869
- /* @__PURE__ */ jsxs51(Text53, { bold: true, color: PALETTE.accent, children: [
32870
- setting.retentionDays,
32871
- " days"
32872
- ] })
32969
+ label("retentionDays", "Delete logs after:"),
32970
+ RETENTION_CHOICES.map((days) => {
32971
+ const highlighted = focus === "retentionDays" && days === pending;
32972
+ const saved = days === setting.retentionDays;
32973
+ return /* @__PURE__ */ jsx62(
32974
+ Text53,
32975
+ {
32976
+ bold: highlighted || saved,
32977
+ underline: highlighted,
32978
+ color: highlighted ? PALETTE.accent : saved ? PALETTE.success : PALETTE.muted,
32979
+ children: `${saved ? "\u2713 " : ""}${days} days`
32980
+ },
32981
+ days
32982
+ );
32983
+ })
32873
32984
  ] }),
32874
32985
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
32875
- /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Older logs are deleted the next time the CLI starts." })
32986
+ notice ? /* @__PURE__ */ jsxs51(Text53, { color: notice.kind === "success" ? PALETTE.success : PALETTE.error, children: [
32987
+ notice.kind === "success" ? "\u2713" : "\u2717",
32988
+ " ",
32989
+ notice.text
32990
+ ] }) : /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "\u2713 marks what is saved. Older logs are deleted the next time the CLI starts." })
32876
32991
  ] }) : /* @__PURE__ */ jsx62(Text53, { color: PALETTE.muted, children: "Loading\u2026" }),
32877
32992
  /* @__PURE__ */ jsx62(Text53, { children: " " }),
32878
32993
  /* @__PURE__ */ jsx62(
@@ -32880,14 +32995,17 @@ function DebugModeScreen({ onDone }) {
32880
32995
  {
32881
32996
  hints: [
32882
32997
  { keys: "\u2191/\u2193", label: "move" },
32883
- { keys: "\u23CE/Space", label: "change" },
32998
+ ...focus === "retentionDays" ? [
32999
+ { keys: "\u2190/\u2192", label: "choose" },
33000
+ { keys: "\u23CE", label: "save" }
33001
+ ] : [{ keys: "\u23CE/Space", label: "toggle" }],
32884
33002
  { keys: "Esc/q", label: "back" }
32885
33003
  ]
32886
33004
  }
32887
33005
  )
32888
33006
  ] });
32889
33007
  }
32890
- var ROWS, nextRetention;
33008
+ var ROWS, snapshotOf2;
32891
33009
  var init_screen12 = __esm({
32892
33010
  "packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx"() {
32893
33011
  "use strict";
@@ -32895,8 +33013,12 @@ var init_screen12 = __esm({
32895
33013
  init_debug_mode_store();
32896
33014
  init_debug_store();
32897
33015
  init_control_hints();
33016
+ init_debug_trail();
32898
33017
  ROWS = ["enabled", "retentionDays"];
32899
- nextRetention = (current) => RETENTION_CHOICES[(RETENTION_CHOICES.indexOf(current) + 1) % RETENTION_CHOICES.length];
33018
+ snapshotOf2 = (setting) => ({
33019
+ enabled: String(setting.enabled),
33020
+ retentionDays: String(setting.retentionDays)
33021
+ });
32900
33022
  }
32901
33023
  });
32902
33024
 
@@ -33333,8 +33455,8 @@ function createProgram() {
33333
33455
  init_config();
33334
33456
  init_package_root();
33335
33457
  import { existsSync as existsSync12 } from "node:fs";
33336
- import { mkdir as mkdir10, readFile as readFile19, rename as rename3, rmdir, unlink } from "node:fs/promises";
33337
- import { dirname as dirname16, join as join30 } from "node:path";
33458
+ import { mkdir as mkdir10, readFile as readFile19, rename as rename3, rmdir as rmdir2, unlink } from "node:fs/promises";
33459
+ import { dirname as dirname17, join as join30 } from "node:path";
33338
33460
  var PACKAGE_NAME3 = "@contentful/experience-design-system-cli";
33339
33461
  async function readJson(path5) {
33340
33462
  try {
@@ -33360,14 +33482,14 @@ async function migrateOldConfig() {
33360
33482
  if (Object.keys(migrated).length > 0) await updateSettings2({ ...migrated, ...await readSettings2() });
33361
33483
  if (existsSync12(oldRuns)) {
33362
33484
  if (!existsSync12(runsFilePath2())) {
33363
- await mkdir10(dirname16(runsFilePath2()), { recursive: true });
33485
+ await mkdir10(dirname17(runsFilePath2()), { recursive: true });
33364
33486
  await rename3(oldRuns, runsFilePath2());
33365
33487
  } else {
33366
33488
  await unlink(oldRuns);
33367
33489
  }
33368
33490
  }
33369
33491
  await Promise.all([oldCredentials, oldDebugMode].map((f) => unlink(f).catch(() => void 0)));
33370
- await rmdir(oldConfigDir2()).catch(() => void 0);
33492
+ await rmdir2(oldConfigDir2()).catch(() => void 0);
33371
33493
  } catch {
33372
33494
  }
33373
33495
  }
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-e051d273.0",
3
+ "version": "2.37.1-dev-build-bdab4dbe.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,7 +1,12 @@
1
+ export type PruneResult = {
2
+ logs: number;
3
+ folders: number;
4
+ };
1
5
  /**
2
6
  * Deletes the debug logs under `<base>/.contentful` that are older than `retentionDays`. It only looks at `.md` files
3
7
  * inside the `debug` folder of a session folder, so nothing the import produced or the user put there is touched. A file
4
- * that cannot be read or deleted is skipped: this runs at startup and must never get in the user's way. Returns how many
5
- * logs it deleted.
8
+ * that cannot be read or deleted is skipped: this runs at startup and must never get in the user's way. A folder the
9
+ * deletion left empty is removed too, up to the session folder; one that still holds anything stays. Returns how many
10
+ * logs and folders it deleted.
6
11
  */
7
- export declare function pruneExpiredLogs(base: string, retentionDays: number, now?: number): Promise<number>;
12
+ export declare function pruneExpiredLogs(base: string, retentionDays: number, now?: number): Promise<PruneResult>;
@@ -1,5 +1,5 @@
1
1
  /** How long a debug log is kept before the CLI deletes it. Only these values are offered. */
2
- export declare const RETENTION_CHOICES: readonly [30, 60, 90];
2
+ export declare const RETENTION_CHOICES: readonly [3, 14, 30];
3
3
  type RetentionDays = (typeof RETENTION_CHOICES)[number];
4
4
  export type DebugModeSetting = {
5
5
  enabled: boolean;
@@ -1,4 +1,8 @@
1
1
  import React from 'react';
2
+ /**
3
+ * Settings > Debug Mode. Logging is switched with Enter. The retention is chosen with ←/→, which only moves a highlight:
4
+ * nothing is saved until Enter, and then the screen says so.
5
+ */
2
6
  export declare function DebugModeScreen({ onDone }: {
3
7
  onDone: () => void;
4
8
  }): React.ReactElement;
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-e051d273.0",
3
+ "version": "2.37.1-dev-build-bdab4dbe.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-e051d273.0",
49
- "@contentful/experience-design-system-types": "2.37.1-dev-build-e051d273.0"
48
+ "@contentful/experience-design-system-types": "2.37.1-dev-build-bdab4dbe.0",
49
+ "@contentful/experience-design-system-backend-pipeline": "2.37.1-dev-build-bdab4dbe.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@tsconfig/node24": "^24.0.4",