@contentful/experience-design-system-cli 2.37.1-dev-build-36f90a5a.0 → 2.37.1-dev-build-ced30421.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,71 +8,6 @@ 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
-
76
11
  // packages/experience-design-system-backend-pipeline/dist/src/agents/types/agent-name.js
77
12
  var AGENT_NAMES;
78
13
  var init_agent_name = __esm({
@@ -837,7 +772,7 @@ async function runAgent(options) {
837
772
  promptLen: prompt.length,
838
773
  promptHead: prompt.slice(0, 500)
839
774
  });
840
- return new Promise((resolve26) => {
775
+ return new Promise((resolve25) => {
841
776
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
842
777
  const child = spawn(binary, args, {
843
778
  stdio: ["pipe", "pipe", "pipe"],
@@ -886,7 +821,7 @@ async function runAgent(options) {
886
821
  stderrLen: stderr.length,
887
822
  stderrTail: stderr.slice(-1e3)
888
823
  });
889
- resolve26(result);
824
+ resolve25(result);
890
825
  });
891
826
  });
892
827
  }
@@ -908,7 +843,7 @@ async function checkAgentAuth(agent) {
908
843
  return "not-found";
909
844
  if (agent !== "claude")
910
845
  return "ok";
911
- return new Promise((resolve26) => {
846
+ return new Promise((resolve25) => {
912
847
  const child = spawn2(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
913
848
  let stdout = "";
914
849
  let done = false;
@@ -917,7 +852,7 @@ async function checkAgentAuth(agent) {
917
852
  return;
918
853
  done = true;
919
854
  child.kill("SIGTERM");
920
- resolve26("unauthenticated");
855
+ resolve25("unauthenticated");
921
856
  }, 5e3);
922
857
  child.stdout?.on("data", (chunk) => {
923
858
  stdout += chunk.toString();
@@ -928,14 +863,14 @@ async function checkAgentAuth(agent) {
928
863
  done = true;
929
864
  clearTimeout(timer);
930
865
  if (code !== 0) {
931
- resolve26("unauthenticated");
866
+ resolve25("unauthenticated");
932
867
  return;
933
868
  }
934
869
  try {
935
870
  const status = JSON.parse(stdout);
936
- resolve26(status.loggedIn ? "ok" : "unauthenticated");
871
+ resolve25(status.loggedIn ? "ok" : "unauthenticated");
937
872
  } catch {
938
- resolve26("unauthenticated");
873
+ resolve25("unauthenticated");
939
874
  }
940
875
  });
941
876
  });
@@ -945,9 +880,9 @@ async function binaryIsOnPath(binary) {
945
880
  const fs = await import("node:fs/promises");
946
881
  return fs.access(binary).then(() => true, () => false);
947
882
  }
948
- return new Promise((resolve26) => {
883
+ return new Promise((resolve25) => {
949
884
  const child = spawn2(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
950
- child.on("close", (code) => resolve26(code === 0));
885
+ child.on("close", (code) => resolve25(code === 0));
951
886
  });
952
887
  }
953
888
  var init_check_agent_auth = __esm({
@@ -2081,233 +2016,6 @@ var init_cache_keys = __esm({
2081
2016
  }
2082
2017
  });
2083
2018
 
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
- finishDebugRun: () => finishDebugRun,
2142
- startDebugRun: () => startDebugRun,
2143
- startDebugSessionIn: () => startDebugSessionIn
2144
- });
2145
- import { mkdir as mkdir8, writeFile as writeFile7 } from "node:fs/promises";
2146
- import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
2147
- import { join as join20, resolve as resolve23 } from "node:path";
2148
- function generateRunId() {
2149
- const now = /* @__PURE__ */ new Date();
2150
- const pad = (n) => String(n).padStart(2, "0");
2151
- return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
2152
- }
2153
- function datePrefix(now = /* @__PURE__ */ new Date()) {
2154
- const pad = (n) => String(n).padStart(2, "0");
2155
- return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
2156
- }
2157
- function slugify(value) {
2158
- return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2159
- }
2160
- async function readBaseDir() {
2161
- try {
2162
- const dir = (await readSettings2())["contentfulBaseDir"];
2163
- return typeof dir === "string" && dir !== "" ? resolve23(dir) : void 0;
2164
- } catch {
2165
- return void 0;
2166
- }
2167
- }
2168
- function nextSessionId(contentfulDir) {
2169
- const today = datePrefix();
2170
- const existing = existsSync9(contentfulDir) ? readdirSync3(contentfulDir) : [];
2171
- const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
2172
- const maxSeq = existing.reduce((max, entry) => {
2173
- const match2 = seqPattern.exec(entry);
2174
- return match2 ? Math.max(max, Number(match2[1])) : max;
2175
- }, 0);
2176
- return `${today}-session-${maxSeq + 1}`;
2177
- }
2178
- function startSession(base) {
2179
- const contentfulDir = join20(base, ".contentful");
2180
- sessionDir ??= join20(contentfulDir, nextSessionId(contentfulDir));
2181
- return sessionDir;
2182
- }
2183
- function currentDebugSessionDir() {
2184
- return sessionDir && join20(sessionDir, "debug");
2185
- }
2186
- async function startDebugSessionIn(base) {
2187
- try {
2188
- if (!await isDebugModeEnabled()) return;
2189
- await mkdir8(join20(startSession(resolve23(base)), "debug"), { recursive: true });
2190
- } catch {
2191
- }
2192
- }
2193
- async function isDebugModeEnabled() {
2194
- try {
2195
- return (await readDebugModeSetting()).enabled;
2196
- } catch {
2197
- return true;
2198
- }
2199
- }
2200
- function redact(value) {
2201
- const clone = { ...value };
2202
- if ("cma_token" in clone) {
2203
- const raw = clone.cma_token;
2204
- clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
2205
- }
2206
- return clone;
2207
- }
2208
- function startDebugRun({
2209
- flow,
2210
- step,
2211
- menuOption,
2212
- inputs
2213
- }) {
2214
- const runId = generateRunId();
2215
- const startedAt = Date.now();
2216
- const redactedInputs = redact(inputs);
2217
- isDebugModeEnabled().then((enabled) => {
2218
- if (!enabled) return;
2219
- pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
2220
- });
2221
- }
2222
- async function finishDebugRun({
2223
- outputs,
2224
- status,
2225
- exitMethod
2226
- }) {
2227
- const run = pendingRun;
2228
- if (!run) return;
2229
- pendingRun = void 0;
2230
- const durationMs = Date.now() - run.startedAt;
2231
- const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
2232
- const root = currentDebugSessionDir();
2233
- if (!root) return;
2234
- const flowSegments = run.flow.split("/");
2235
- const dir = join20(root, ...flowSegments);
2236
- await mkdir8(dir, { recursive: true });
2237
- const filename = nextAttemptFilename(dir, run.menuOption);
2238
- await writeFile7(join20(dir, filename), content, { mode: 384 });
2239
- }
2240
- function nextAttemptFilename(dir, menuOption) {
2241
- const today = datePrefix();
2242
- const optionSlug = slugify(menuOption);
2243
- const existing = existsSync9(dir) ? readdirSync3(dir) : [];
2244
- const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
2245
- const maxAttempt = existing.reduce((max, entry) => {
2246
- const match2 = attemptPattern.exec(entry);
2247
- return match2 ? Math.max(max, Number(match2[1])) : max;
2248
- }, 0);
2249
- return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
2250
- }
2251
- function renderMarkdown(run, finish) {
2252
- const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
2253
- const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
2254
- const flowSlug = run.flow.split("/").join("-");
2255
- return `# Debug Log
2256
-
2257
- - Run ID: ${run.runId}
2258
- - Flow: ${flowSlug}
2259
- - Step: ${stepLabel2}
2260
- - Menu option: ${run.menuOption}
2261
- - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
2262
- - CLI version: ${readPackageVersion()}
2263
- - Platform: ${process.platform} / Node ${process.version}
2264
- - Duration on screen: ${finish.durationMs}ms
2265
- - Status: ${finish.status}
2266
- - Exit method: ${finish.exitMethod}
2267
-
2268
- ## Inputs
2269
- \`\`\`json
2270
- ${JSON.stringify(run.inputs, null, 2)}
2271
- \`\`\`
2272
-
2273
- ## Outputs
2274
- \`\`\`json
2275
- ${JSON.stringify(finish.outputs, null, 2)}
2276
- \`\`\`
2277
- `;
2278
- }
2279
- function handleCrash() {
2280
- return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
2281
- }
2282
- var pendingRun, sessionDir;
2283
- var init_debug_store = __esm({
2284
- "packages/experience-design-system-cli/src/tui/debug-store.ts"() {
2285
- "use strict";
2286
- init_config();
2287
- init_version();
2288
- init_debug_mode_store();
2289
- void Promise.all([isDebugModeEnabled(), readBaseDir()]).then(([enabled, base]) => {
2290
- if (!enabled || !base) return void 0;
2291
- return mkdir8(join20(startSession(base), "debug"), { recursive: true });
2292
- });
2293
- process.once("uncaughtException", (err) => {
2294
- void handleCrash().finally(() => {
2295
- throw err;
2296
- });
2297
- });
2298
- process.once("unhandledRejection", (reason) => {
2299
- void handleCrash().finally(() => {
2300
- throw reason;
2301
- });
2302
- });
2303
- process.once("SIGINT", () => {
2304
- void handleCrash().finally(() => {
2305
- process.exit(130);
2306
- });
2307
- });
2308
- }
2309
- });
2310
-
2311
2019
  // packages/experience-design-system-cli/app.tsx
2312
2020
  import { join as join25 } from "node:path";
2313
2021
  import { useEffect as useEffect27, useState as useState33 } from "react";
@@ -2347,8 +2055,60 @@ function brandBar(width, ramp = BRAND_RAMP) {
2347
2055
  }
2348
2056
  var FOCUS_MARKER = "\u276F";
2349
2057
 
2350
- // packages/experience-design-system-cli/src/tui/home/home.tsx
2351
- init_version();
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
+ }
2352
2112
 
2353
2113
  // packages/experience-design-system-cli/src/tui/use-terminal-width.ts
2354
2114
  import { useEffect, useState } from "react";
@@ -4605,8 +4365,30 @@ function applyScopeDecisions(db, sessionId, decisions) {
4605
4365
  const placeholders = accepted.map(() => "?").join(",");
4606
4366
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
4607
4367
  }
4368
+ removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
4608
4369
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
4609
4370
  }
4371
+ function removeSlotAllowedComponents(db, sessionId, edges, rejectedNames) {
4372
+ if (edges.length === 0 && rejectedNames.length === 0)
4373
+ return;
4374
+ const componentId = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
4375
+ const removeEdge = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND allowed_component = ?");
4376
+ const removeEverywhere = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND allowed_component = ?");
4377
+ db.exec("BEGIN");
4378
+ try {
4379
+ for (const edge of edges) {
4380
+ const row = componentId.get(sessionId, edge.parent);
4381
+ if (row)
4382
+ removeEdge.run(sessionId, row.component_id, edge.child);
4383
+ }
4384
+ for (const name of rejectedNames)
4385
+ removeEverywhere.run(sessionId, name);
4386
+ db.exec("COMMIT");
4387
+ } catch (e) {
4388
+ db.exec("ROLLBACK");
4389
+ throw e;
4390
+ }
4391
+ }
4610
4392
  function findLatestSessionForCommand(db, command) {
4611
4393
  return getLatestCompletedSessionForCommand(db, command);
4612
4394
  }
@@ -12547,11 +12329,11 @@ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node
12547
12329
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/review-session-paths.js
12548
12330
  import { resolve as resolve15 } from "node:path";
12549
12331
  async function getRefineSessionPaths(sessionId, artifactsRoot) {
12550
- const sessionDir2 = resolve15(artifactsRoot, sessionId);
12332
+ const sessionDir = resolve15(artifactsRoot, sessionId);
12551
12333
  return {
12552
- sessionDir: sessionDir2,
12553
- eventsPath: resolve15(sessionDir2, "events.jsonl"),
12554
- statePath: resolve15(sessionDir2, "current-review-state.json")
12334
+ sessionDir,
12335
+ eventsPath: resolve15(sessionDir, "events.jsonl"),
12336
+ statePath: resolve15(sessionDir, "current-review-state.json")
12555
12337
  };
12556
12338
  }
12557
12339
 
@@ -13750,7 +13532,7 @@ function errorMessage(error) {
13750
13532
  return error instanceof Error && error.message ? error.message : String(error);
13751
13533
  }
13752
13534
  function defaultSleep(delayMs) {
13753
- return new Promise((resolve26) => setTimeout(resolve26, delayMs));
13535
+ return new Promise((resolve25) => setTimeout(resolve25, delayMs));
13754
13536
  }
13755
13537
 
13756
13538
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
@@ -13991,7 +13773,7 @@ var ApiClient = class {
13991
13773
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13992
13774
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13993
13775
  const jitter = Math.random() * baseDelay * 0.15;
13994
- await new Promise((resolve26) => setTimeout(resolve26, baseDelay + jitter));
13776
+ await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
13995
13777
  }
13996
13778
  }
13997
13779
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -16104,7 +15886,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
16104
15886
  const message = error instanceof Error ? error.message : String(error);
16105
15887
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
16106
15888
  throw error;
16107
- await new Promise((resolve26) => setTimeout(resolve26, Math.min(250 * attempt, 2e3)));
15889
+ await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
16108
15890
  }
16109
15891
  }
16110
15892
  }
@@ -16931,7 +16713,6 @@ function useCredentialsControls(handlers) {
16931
16713
  }
16932
16714
 
16933
16715
  // packages/experience-design-system-cli/src/tui/user-agent.ts
16934
- init_version();
16935
16716
  function cliUserAgent() {
16936
16717
  return buildUserAgent(readPackageVersion());
16937
16718
  }
@@ -17431,8 +17212,34 @@ function ExtractionScreen({
17431
17212
  );
17432
17213
  }
17433
17214
 
17434
- // packages/experience-design-system-cli/app.tsx
17435
- init_config();
17215
+ // packages/experience-design-system-types/dist/src/config/index.js
17216
+ import { randomBytes as randomBytes3 } from "node:crypto";
17217
+ import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
17218
+ import { homedir as homedir3 } from "node:os";
17219
+ import { dirname as dirname13, join as join17 } from "node:path";
17220
+ function configRoot2() {
17221
+ return process.env["EDS_HOME"] || join17(homedir3(), ".contentful", "experience-design-system-cli");
17222
+ }
17223
+ var configFilePath2 = () => join17(configRoot2(), "config.json");
17224
+ var debugSessionsDir2 = () => join17(configRoot2(), "debug", "sessions");
17225
+ async function readSettings2() {
17226
+ try {
17227
+ return JSON.parse(await readFile18(configFilePath2(), "utf8"));
17228
+ } catch {
17229
+ return {};
17230
+ }
17231
+ }
17232
+ async function writeSettings2(settings) {
17233
+ const path5 = configFilePath2();
17234
+ await mkdir6(dirname13(path5), { recursive: true });
17235
+ const tmp = `${path5}.${process.pid}.${randomBytes3(4).toString("hex")}.tmp`;
17236
+ await writeFile6(tmp, `${JSON.stringify(settings, null, 2)}
17237
+ `, { mode: 384 });
17238
+ await rename2(tmp, path5);
17239
+ }
17240
+ async function updateSettings2(patch) {
17241
+ await writeSettings2({ ...await readSettings2(), ...patch });
17242
+ }
17436
17243
 
17437
17244
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/use-extraction.ts
17438
17245
  import { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
@@ -17708,7 +17515,6 @@ function useExtraction(input) {
17708
17515
  reuseTokens: input.tokenStrategy === "reuse"
17709
17516
  })
17710
17517
  });
17711
- void Promise.resolve().then(() => (init_debug_store(), debug_store_exports)).then((store) => store.startDebugSessionIn(input.projectPath));
17712
17518
  void runExtraction(input, (progress) => {
17713
17519
  if (current.current === input) setState({ status: "running", progress });
17714
17520
  }).then((result) => {
@@ -18590,7 +18396,7 @@ function buildVisibleRows(props) {
18590
18396
  if (visited.has(target)) continue;
18591
18397
  visited.add(target);
18592
18398
  const isCycleMember = cycleParticipants.has(target);
18593
- out.push({ name: target, depth: cur.depth + 1, isCycleMember });
18399
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
18594
18400
  queue.push({ name: target, depth: cur.depth + 1 });
18595
18401
  }
18596
18402
  }
@@ -18637,7 +18443,8 @@ function buildVisibleRows(props) {
18637
18443
  sharedSuffix,
18638
18444
  cycleChild: child.isCycleMember || void 0,
18639
18445
  itemIdx: childRec?.idx ?? -1,
18640
- rootName: key
18446
+ rootName: key,
18447
+ parentName: child.parent
18641
18448
  });
18642
18449
  });
18643
18450
  }
@@ -18720,13 +18527,19 @@ function buildVisibleRows(props) {
18720
18527
  injectedChildren.push({
18721
18528
  name: target,
18722
18529
  depth: parentDepth + 1,
18723
- isCycleChild: true
18530
+ isCycleChild: true,
18531
+ parent: parentName
18724
18532
  });
18725
18533
  }
18726
18534
  };
18727
18535
  emitCycleChildrenOf(root, 0);
18728
18536
  for (const c2 of closureChildren) {
18729
- injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
18537
+ injectedChildren.push({
18538
+ name: c2.name,
18539
+ depth: c2.depth,
18540
+ isCycleChild: false,
18541
+ parent: c2.path[c2.path.length - 2] ?? root
18542
+ });
18730
18543
  emitCycleChildrenOf(c2.name, c2.depth);
18731
18544
  }
18732
18545
  const isLastAtDepth = (idx) => {
@@ -18760,7 +18573,8 @@ function buildVisibleRows(props) {
18760
18573
  sharedSuffix,
18761
18574
  cycleChild: child.isCycleChild || void 0,
18762
18575
  itemIdx: childRec?.idx ?? -1,
18763
- rootName: root
18576
+ rootName: root,
18577
+ parentName: child.parent
18764
18578
  });
18765
18579
  });
18766
18580
  }
@@ -18913,7 +18727,7 @@ function GroupedSidebar(props) {
18913
18727
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
18914
18728
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
18915
18729
  const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
18916
- const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "cycle");
18730
+ const supportsSelectionGlyph = selectionStateByKey !== void 0 && itemName !== void 0 && (row.kind === "standalone" || row.kind === "group-root" || row.kind === "group-child" || row.kind === "flat" || row.kind === "empty" || row.kind === "cycle");
18917
18731
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
18918
18732
  const isCycleRow = row.kind === "cycle";
18919
18733
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -18943,7 +18757,7 @@ function GroupedSidebar(props) {
18943
18757
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
18944
18758
  bold: isSelected || labelStyle.bold,
18945
18759
  inverse: false,
18946
- underline: isSelected && !focused,
18760
+ underline: isSelected && focused,
18947
18761
  wrap: wrapLabels ? "wrap" : "truncate",
18948
18762
  children: [
18949
18763
  " ",
@@ -19602,6 +19416,7 @@ function resolveKey(mode, key, ctx) {
19602
19416
  function resolveMain(key, ctx) {
19603
19417
  const { input } = key;
19604
19418
  const inMain = ctx.focusedColumn === "main";
19419
+ if (key.ctrl && input === "z") return { type: "undo" };
19605
19420
  if (input === "q" || key.escape) {
19606
19421
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
19607
19422
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -19860,21 +19675,42 @@ function rejectNeedsConfirmation(graph, name, state) {
19860
19675
  const ancestors = toReject.filter((n) => n !== name);
19861
19676
  return ancestors.length + toDeselect.length >= 2;
19862
19677
  }
19863
- function partitionDecisions(components, state) {
19678
+ function removeSlotChild(components, edge) {
19679
+ return components.map(
19680
+ (component) => component.name === edge.parent ? {
19681
+ ...component,
19682
+ slots: component.slots?.map((slot) => ({
19683
+ ...slot,
19684
+ allowedComponents: slot.allowedComponents.filter((name) => name !== edge.child)
19685
+ }))
19686
+ } : component
19687
+ );
19688
+ }
19689
+ function withoutSlotChildren(components, removedEdges) {
19690
+ return removedEdges.reduce(removeSlotChild, components);
19691
+ }
19692
+ function partitionDecisions(components, state, removedEdges) {
19864
19693
  const accepted = [];
19865
19694
  const rejected = [];
19866
19695
  for (const c2 of components) {
19867
19696
  if (state.get(c2.name) === "accepted") accepted.push(c2.name);
19868
19697
  else rejected.push(c2.name);
19869
19698
  }
19870
- return { accepted, rejected };
19699
+ const rejectedNames = new Set(rejected);
19700
+ const excludedSlotEdges = removedEdges.filter((e) => !rejectedNames.has(e.parent) && !rejectedNames.has(e.child));
19701
+ return { accepted, rejected, excludedSlotEdges };
19871
19702
  }
19872
19703
 
19873
19704
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
19874
- function useScopeGate({ components, onConfirm, onQuit }) {
19705
+ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
19875
19706
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
19876
19707
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
19877
19708
  const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
19709
+ const [removedEdges, setRemovedEdges] = useState12([]);
19710
+ const components = useMemo2(
19711
+ () => withoutSlotChildren(loadedComponents, removedEdges),
19712
+ [loadedComponents, removedEdges]
19713
+ );
19878
19714
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
19879
19715
  const [focusedColumn, setFocusedColumn] = useState12("main");
19880
19716
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -20046,6 +19882,14 @@ function useScopeGate({ components, onConfirm, onQuit }) {
20046
19882
  return void 0;
20047
19883
  }
20048
19884
  };
19885
+ const focusedNestedEdge = () => {
19886
+ const row = visibleRows[safeCursor];
19887
+ if (row?.kind !== "group-child" || !row.parentName || row.itemIdx < 0) return void 0;
19888
+ const child = groupedItems[row.itemIdx]?.key;
19889
+ return child ? { parent: row.parentName, child } : void 0;
19890
+ };
19891
+ const removeFromParentSlot = (edge) => setRemovedEdges((edges) => [...edges, edge]);
19892
+ const undoSlotRemoval = () => setRemovedEdges((edges) => edges.slice(0, -1));
20049
19893
  const jumpCursorTo = (name) => {
20050
19894
  let idx = -1;
20051
19895
  for (let i = 0; i < visibleRows.length; i++) {
@@ -20145,7 +19989,7 @@ function useScopeGate({ components, onConfirm, onQuit }) {
20145
19989
  onQuit();
20146
19990
  return;
20147
19991
  case "confirm":
20148
- onConfirm(partitionDecisions(components, decisions));
19992
+ onConfirm(partitionDecisions(components, decisions, removedEdges));
20149
19993
  return;
20150
19994
  case "close-help":
20151
19995
  setShowHelp(false);
@@ -20198,6 +20042,11 @@ function useScopeGate({ components, onConfirm, onQuit }) {
20198
20042
  return;
20199
20043
  }
20200
20044
  case "reject": {
20045
+ const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
20046
+ if (edge) {
20047
+ removeFromParentSlot(edge);
20048
+ return;
20049
+ }
20201
20050
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
20202
20051
  if (key) requestReject(key);
20203
20052
  return;
@@ -20205,6 +20054,9 @@ function useScopeGate({ components, onConfirm, onQuit }) {
20205
20054
  case "toggle-all":
20206
20055
  decide({ type: "toggle-all" });
20207
20056
  return;
20057
+ case "undo":
20058
+ undoSlotRemoval();
20059
+ return;
20208
20060
  case "accept-unflagged":
20209
20061
  decide({ type: "accept-unflagged" });
20210
20062
  return;
@@ -20595,7 +20447,7 @@ function GenerationScreen({
20595
20447
  import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
20596
20448
 
20597
20449
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
20598
- import { resolve as resolve24 } from "node:path";
20450
+ import { resolve as resolve23 } from "node:path";
20599
20451
 
20600
20452
  // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
20601
20453
  async function prepareMapTokens(input, generatedSessionId) {
@@ -20730,7 +20582,7 @@ async function buildMapTokensOptions(input) {
20730
20582
  if (mapOverride?.kind === "text") prompt.skillContentOverride = mapOverride.value;
20731
20583
  if (mapOverride?.kind === "path") {
20732
20584
  await resolvePromptOverride(mapOverride);
20733
- prompt.skillPathOverride = resolve24(mapOverride.value);
20585
+ prompt.skillPathOverride = resolve23(mapOverride.value);
20734
20586
  }
20735
20587
  if (input.existingEntitiesPath) {
20736
20588
  const entities = await readExistingContentfulEntitiesFromSession({ path: input.existingEntitiesPath });
@@ -20778,7 +20630,7 @@ function useGeneration(input) {
20778
20630
  }
20779
20631
 
20780
20632
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
20781
- import { join as join21 } from "node:path";
20633
+ import { join as join20 } from "node:path";
20782
20634
  function buildFlowStart(input) {
20783
20635
  const { extraction, handoff, saved, generatePromptPath } = input;
20784
20636
  const credentials = extraction.credentials ?? {
@@ -20791,7 +20643,7 @@ function buildFlowStart(input) {
20791
20643
  handoff,
20792
20644
  agent: extraction.agent,
20793
20645
  projectPath: extraction.projectPath,
20794
- outDir: extraction.projectPath ? join21(extraction.projectPath, ".contentful") : "",
20646
+ outDir: extraction.projectPath ? join20(extraction.projectPath, ".contentful") : "",
20795
20647
  rawTokensPath: extraction.rawTokensPath,
20796
20648
  credentials: {
20797
20649
  spaceId: credentials.spaceId,
@@ -22847,8 +22699,8 @@ function FieldEditor({
22847
22699
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE3.warning, children: [
22848
22700
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE3.warning, children: "FIELD EDITOR \u2014 no fields" }),
22849
22701
  /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify." }),
22850
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "You can add fields manually below or reject this component." }),
22851
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "Enter to save \xB7 Esc to discard" })
22702
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "There is nothing to edit here." }),
22703
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: active ? "[Esc] go back to the list" : "In the list: [r] reject this component \xB7 [a] accept it" })
22852
22704
  ] });
22853
22705
  }
22854
22706
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -23063,7 +22915,7 @@ function FieldEditor({
23063
22915
  children: [
23064
22916
  hasEmptyProperties && /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify. Reject this component or add fields manually." }),
23065
22917
  header,
23066
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
22918
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
23067
22919
  PropRow,
23068
22920
  {
23069
22921
  prop: currentProp,
@@ -23972,6 +23824,7 @@ function finalizeReviewSession(extractSessionId, components) {
23972
23824
  db.exec("ROLLBACK");
23973
23825
  throw error;
23974
23826
  }
23827
+ removeSlotAllowedComponents(db, extractSessionId, [], toReject);
23975
23828
  } finally {
23976
23829
  db.close();
23977
23830
  }
@@ -25703,33 +25556,50 @@ function GenerateReviewStepView({
25703
25556
  const cycle = cycleRows[cyclesCursor];
25704
25557
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
25705
25558
  }, [cycleRows, cyclesCursor, components]);
25706
- const handleBreakEdge = (edge) => {
25707
- const target = components.find((component) => component.key === edge.fromComponent);
25708
- const slot = target?.entry.$slots?.[edge.slotName];
25709
- if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
25710
- const nextEntry = {
25711
- ...target.entry,
25712
- $slots: {
25713
- ...target.entry.$slots,
25714
- [edge.slotName]: {
25715
- ...slot,
25716
- $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
25717
- }
25718
- }
25719
- };
25559
+ const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
25720
25560
  const next = components.map(
25721
- (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
25561
+ (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
25722
25562
  );
25723
25563
  setComponents(next);
25724
25564
  const db = openPipelineDb();
25725
25565
  try {
25726
- storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
25566
+ storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
25727
25567
  } finally {
25728
25568
  db.close();
25729
25569
  }
25730
25570
  recomputeCycles(next);
25731
25571
  livePreviewHook.trigger();
25732
- pushHistorySnapshot(next, "break-cycle-edge");
25572
+ pushHistorySnapshot(next, historyLabel);
25573
+ };
25574
+ const handleBreakEdge = (edge) => {
25575
+ const target = components.find((component) => component.key === edge.fromComponent);
25576
+ const slot = target?.entry.$slots?.[edge.slotName];
25577
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
25578
+ saveSlotChange(
25579
+ target.key,
25580
+ {
25581
+ ...target.entry,
25582
+ $slots: {
25583
+ ...target.entry.$slots,
25584
+ [edge.slotName]: {
25585
+ ...slot,
25586
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
25587
+ }
25588
+ }
25589
+ },
25590
+ "break-cycle-edge"
25591
+ );
25592
+ };
25593
+ const handleRemoveSlotChild = (parentKey, childKey) => {
25594
+ const parent = components.find((component) => component.key === parentKey);
25595
+ if (!parent?.entry.$slots) return;
25596
+ const slots = Object.fromEntries(
25597
+ Object.entries(parent.entry.$slots).map(([slotName, slot]) => [
25598
+ slotName,
25599
+ Array.isArray(slot.$allowedComponents) ? { ...slot, $allowedComponents: slot.$allowedComponents.filter((value) => value !== childKey) } : slot
25600
+ ])
25601
+ );
25602
+ saveSlotChange(parentKey, { ...parent.entry, $slots: slots }, "remove-slot-child");
25733
25603
  };
25734
25604
  const handleRejectComponent = (key) => {
25735
25605
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -26059,6 +25929,11 @@ function GenerateReviewStepView({
26059
25929
  if (input === "r") {
26060
25930
  const current = components[selectedIdx];
26061
25931
  if (!current) return;
25932
+ const row = visibleRowsMemo[cursorRowIdx];
25933
+ if (row?.kind === "group-child" && row.parentName) {
25934
+ handleRemoveSlotChild(row.parentName, current.key);
25935
+ return;
25936
+ }
26062
25937
  handleRejectComponent(current.key);
26063
25938
  return;
26064
25939
  }
@@ -26534,11 +26409,11 @@ function DoneStep({
26534
26409
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/screens/PathPrompt.tsx
26535
26410
  import { useState as useState24 } from "react";
26536
26411
  import { Box as Box37, Text as Text40 } from "ink";
26537
- import { readdirSync as readdirSync4 } from "node:fs";
26538
- import { dirname as dirname15, basename as basename6, join as join22 } from "node:path";
26412
+ import { readdirSync as readdirSync3 } from "node:fs";
26413
+ import { dirname as dirname15, basename as basename6, join as join21 } from "node:path";
26539
26414
 
26540
26415
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts
26541
- import { resolve as resolve25 } from "node:path";
26416
+ import { resolve as resolve24 } from "node:path";
26542
26417
  import { homedir as homedir4 } from "node:os";
26543
26418
  function expandTilde(input) {
26544
26419
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -26552,7 +26427,7 @@ function normalizePath(input) {
26552
26427
  p = p.slice(1, -1);
26553
26428
  }
26554
26429
  p = expandTilde(p);
26555
- return resolve25(p);
26430
+ return resolve24(p);
26556
26431
  }
26557
26432
 
26558
26433
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/use-blinking-cursor.ts
@@ -26575,19 +26450,19 @@ function autocomplete(partial) {
26575
26450
  const base = basename6(normalized);
26576
26451
  let entries;
26577
26452
  try {
26578
- entries = readdirSync4(dir);
26453
+ entries = readdirSync3(dir);
26579
26454
  } catch {
26580
26455
  return null;
26581
26456
  }
26582
26457
  const matches = entries.filter((e) => e.startsWith(base));
26583
26458
  if (matches.length === 0) return null;
26584
- if (matches.length === 1) return join22(dir, matches[0]);
26459
+ if (matches.length === 1) return join21(dir, matches[0]);
26585
26460
  let prefix = matches[0];
26586
26461
  for (const m of matches) {
26587
26462
  while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
26588
26463
  if (!prefix) break;
26589
26464
  }
26590
- return prefix.length > base.length ? join22(dir, prefix) : null;
26465
+ return prefix.length > base.length ? join21(dir, prefix) : null;
26591
26466
  }
26592
26467
  function PathPrompt({
26593
26468
  defaultPath,
@@ -27346,9 +27221,9 @@ import { useEffect as useEffect21, useRef as useRef13, useSyncExternalStore } fr
27346
27221
 
27347
27222
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27348
27223
  import { appendFileSync, writeFileSync } from "node:fs";
27349
- import { mkdir as mkdir9 } from "node:fs/promises";
27224
+ import { mkdir as mkdir8 } from "node:fs/promises";
27350
27225
  import { tmpdir } from "node:os";
27351
- import { join as join24 } from "node:path";
27226
+ import { join as join23 } from "node:path";
27352
27227
 
27353
27228
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/wizard-state-transitions.ts
27354
27229
  function shouldBypassPreview(state) {
@@ -27692,8 +27567,8 @@ function pushFailure(e, deps) {
27692
27567
  }
27693
27568
 
27694
27569
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/save.ts
27695
- import { writeFile as writeFile8 } from "node:fs/promises";
27696
- import { join as join23 } from "node:path";
27570
+ import { writeFile as writeFile7 } from "node:fs/promises";
27571
+ import { join as join22 } from "node:path";
27697
27572
 
27698
27573
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/run-print-files-helpers.ts
27699
27574
  function nextStateAfterPrint(opts) {
@@ -27716,15 +27591,15 @@ function buildSavedCDF(components, tokens, opts = {}) {
27716
27591
  var realSaveDeps = () => ({
27717
27592
  openDb: openPipelineDb,
27718
27593
  readTokens: (path5) => readTokensFromPath2({ flag: "tokens", path: path5 }),
27719
- writeFile: (path5, contents) => writeFile8(path5, contents),
27594
+ writeFile: (path5, contents) => writeFile7(path5, contents),
27720
27595
  appendRun,
27721
27596
  buildSourceFingerprint,
27722
- sleep: (ms) => new Promise((resolve26) => setTimeout(resolve26, ms)),
27597
+ sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
27723
27598
  warn: (message) => process.stderr.write(message)
27724
27599
  });
27725
27600
  async function runPrintFiles(input, deps, onPatch) {
27726
27601
  onPatch({ step: "printing" });
27727
- const componentsPath = join23(input.outDir, "components.json");
27602
+ const componentsPath = join22(input.outDir, "components.json");
27728
27603
  try {
27729
27604
  const db = deps.openDb();
27730
27605
  let components = [];
@@ -27805,7 +27680,7 @@ var EMPTY_PUSH_RESULT = {
27805
27680
  };
27806
27681
 
27807
27682
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/controller.ts
27808
- var WIZARD_LOG = join24(tmpdir(), "experiences-import-wizard.log");
27683
+ var WIZARD_LOG = join23(tmpdir(), "experiences-import-wizard.log");
27809
27684
  function appendWizardLog(entry) {
27810
27685
  appendFileSync(WIZARD_LOG, JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), ...entry }) + "\n");
27811
27686
  }
@@ -27828,7 +27703,7 @@ function realFlowDeps() {
27828
27703
  }
27829
27704
  },
27830
27705
  mkdir: async (path5) => {
27831
- await mkdir9(path5, { recursive: true });
27706
+ await mkdir8(path5, { recursive: true });
27832
27707
  },
27833
27708
  detectSaveConflict,
27834
27709
  buildTimestampedSubdir,
@@ -28092,19 +27967,171 @@ function useFlow(start, deps = realFlowDeps) {
28092
27967
  // packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
28093
27968
  import { useEffect as useEffect22, useState as useState27 } from "react";
28094
27969
  import { Box as Box42, Text as Text44, useInput as useInput9 } from "ink";
28095
- init_debug_store();
27970
+
27971
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
27972
+ import { mkdir as mkdir9, writeFile as writeFile8 } from "node:fs/promises";
27973
+ import { existsSync as existsSync9, readdirSync as readdirSync4 } from "node:fs";
27974
+ import { join as join24 } from "node:path";
27975
+
27976
+ // packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
27977
+ var DEFAULT_DEBUG_MODE_SETTING = {
27978
+ enabled: true
27979
+ };
27980
+ async function readDebugModeSetting() {
27981
+ const { debugMode } = await readSettings2();
27982
+ return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
27983
+ }
27984
+ async function writeDebugModeSetting(setting) {
27985
+ await updateSettings2({ debugMode: setting });
27986
+ }
27987
+
27988
+ // packages/experience-design-system-cli/src/tui/debug-store.ts
27989
+ var pendingRun;
27990
+ function generateRunId() {
27991
+ const now = /* @__PURE__ */ new Date();
27992
+ const pad = (n) => String(n).padStart(2, "0");
27993
+ return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
27994
+ }
27995
+ function datePrefix(now = /* @__PURE__ */ new Date()) {
27996
+ const pad = (n) => String(n).padStart(2, "0");
27997
+ return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
27998
+ }
27999
+ function slugify(value) {
28000
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
28001
+ }
28002
+ function generateSessionId3() {
28003
+ const today = datePrefix();
28004
+ const root = debugSessionsDir2();
28005
+ const existing = existsSync9(root) ? readdirSync4(root) : [];
28006
+ const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
28007
+ const maxSeq = existing.reduce((max, entry) => {
28008
+ const match2 = seqPattern.exec(entry);
28009
+ return match2 ? Math.max(max, Number(match2[1])) : max;
28010
+ }, 0);
28011
+ return `${today}-session-${maxSeq + 1}`;
28012
+ }
28013
+ var SESSION_ID = generateSessionId3();
28014
+ function sessionDebugDir() {
28015
+ return join24(debugSessionsDir2(), SESSION_ID);
28016
+ }
28017
+ function currentDebugSessionDir() {
28018
+ return sessionDebugDir();
28019
+ }
28020
+ void isDebugModeEnabled().then((enabled) => {
28021
+ if (!enabled) return void 0;
28022
+ return mkdir9(sessionDebugDir(), { recursive: true });
28023
+ });
28024
+ async function isDebugModeEnabled() {
28025
+ try {
28026
+ return (await readDebugModeSetting()).enabled;
28027
+ } catch {
28028
+ return true;
28029
+ }
28030
+ }
28031
+ function redact(value) {
28032
+ const clone = { ...value };
28033
+ if ("cma_token" in clone) {
28034
+ const raw = clone.cma_token;
28035
+ clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
28036
+ }
28037
+ return clone;
28038
+ }
28039
+ function startDebugRun({
28040
+ flow,
28041
+ step,
28042
+ menuOption,
28043
+ inputs
28044
+ }) {
28045
+ const runId = generateRunId();
28046
+ const startedAt = Date.now();
28047
+ const redactedInputs = redact(inputs);
28048
+ isDebugModeEnabled().then((enabled) => {
28049
+ if (!enabled) return;
28050
+ pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
28051
+ });
28052
+ }
28053
+ async function finishDebugRun({
28054
+ outputs,
28055
+ status,
28056
+ exitMethod
28057
+ }) {
28058
+ const run = pendingRun;
28059
+ if (!run) return;
28060
+ pendingRun = void 0;
28061
+ const durationMs = Date.now() - run.startedAt;
28062
+ const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
28063
+ const flowSegments = run.flow.split("/");
28064
+ const dir = join24(sessionDebugDir(), ...flowSegments);
28065
+ await mkdir9(dir, { recursive: true });
28066
+ const filename = nextAttemptFilename(dir, run.menuOption);
28067
+ await writeFile8(join24(dir, filename), content, { mode: 384 });
28068
+ }
28069
+ function nextAttemptFilename(dir, menuOption) {
28070
+ const today = datePrefix();
28071
+ const optionSlug = slugify(menuOption);
28072
+ const existing = existsSync9(dir) ? readdirSync4(dir) : [];
28073
+ const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
28074
+ const maxAttempt = existing.reduce((max, entry) => {
28075
+ const match2 = attemptPattern.exec(entry);
28076
+ return match2 ? Math.max(max, Number(match2[1])) : max;
28077
+ }, 0);
28078
+ return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
28079
+ }
28080
+ function renderMarkdown(run, finish) {
28081
+ const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
28082
+ const stepLabel2 = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
28083
+ const flowSlug = run.flow.split("/").join("-");
28084
+ return `# Debug Log
28085
+
28086
+ - Run ID: ${run.runId}
28087
+ - Flow: ${flowSlug}
28088
+ - Step: ${stepLabel2}
28089
+ - Menu option: ${run.menuOption}
28090
+ - Date: ${(/* @__PURE__ */ new Date()).toISOString()}
28091
+ - CLI version: ${readPackageVersion()}
28092
+ - Platform: ${process.platform} / Node ${process.version}
28093
+ - Duration on screen: ${finish.durationMs}ms
28094
+ - Status: ${finish.status}
28095
+ - Exit method: ${finish.exitMethod}
28096
+
28097
+ ## Inputs
28098
+ \`\`\`json
28099
+ ${JSON.stringify(run.inputs, null, 2)}
28100
+ \`\`\`
28101
+
28102
+ ## Outputs
28103
+ \`\`\`json
28104
+ ${JSON.stringify(finish.outputs, null, 2)}
28105
+ \`\`\`
28106
+ `;
28107
+ }
28108
+ function handleCrash() {
28109
+ return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
28110
+ }
28111
+ process.once("uncaughtException", (err) => {
28112
+ void handleCrash().finally(() => {
28113
+ throw err;
28114
+ });
28115
+ });
28116
+ process.once("unhandledRejection", (reason) => {
28117
+ void handleCrash().finally(() => {
28118
+ throw reason;
28119
+ });
28120
+ });
28121
+ process.once("SIGINT", () => {
28122
+ void handleCrash().finally(() => {
28123
+ process.exit(130);
28124
+ });
28125
+ });
28096
28126
 
28097
28127
  // packages/experience-design-system-cli/src/tui/help/help-info.ts
28098
- init_config();
28099
- init_debug_store();
28100
- init_debug_mode_store();
28101
- init_version();
28102
28128
  async function readHelpInfo() {
28103
28129
  const debugMode = await readDebugModeSetting();
28104
28130
  return {
28105
28131
  storage: [
28106
28132
  { label: "Config folder", value: configRoot2() },
28107
- { label: "Settings file", value: configFilePath2() }
28133
+ { label: "Settings file", value: configFilePath2() },
28134
+ { label: "Debug logs", value: debugSessionsDir2() }
28108
28135
  ],
28109
28136
  troubleshooting: [
28110
28137
  { label: "CLI version", value: readPackageVersion() },
@@ -28113,7 +28140,7 @@ async function readHelpInfo() {
28113
28140
  { label: "Debug Mode", value: debugMode.enabled ? "on" : "off" },
28114
28141
  {
28115
28142
  label: "This session",
28116
- value: !debugMode.enabled ? "no logs written while Debug Mode is off" : currentDebugSessionDir() ?? "not started: set the default project directory in Settings, or start an import"
28143
+ value: debugMode.enabled ? currentDebugSessionDir() : "no logs written while Debug Mode is off"
28117
28144
  }
28118
28145
  ]
28119
28146
  };
@@ -28230,7 +28257,6 @@ import { Box as Box44, Text as Text46, useInput as useInput11 } from "ink";
28230
28257
  import TextInput4 from "ink-text-input";
28231
28258
 
28232
28259
  // packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
28233
- init_config();
28234
28260
  var readV1Store = readSettings2;
28235
28261
  var writeV1Store = writeSettings2;
28236
28262
 
@@ -28243,8 +28269,7 @@ async function readCredentials() {
28243
28269
  cmaToken: store.cmaToken || "",
28244
28270
  host: store.host || "",
28245
28271
  defaultComponentDir: store.defaultComponentDir || "",
28246
- defaultTokenFile: store.defaultTokenFile || "",
28247
- contentfulBaseDir: store.contentfulBaseDir || ""
28272
+ defaultTokenFile: store.defaultTokenFile || ""
28248
28273
  };
28249
28274
  }
28250
28275
  async function writeCredentials(config) {
@@ -28260,7 +28285,6 @@ async function writeCredentials(config) {
28260
28285
  }
28261
28286
 
28262
28287
  // packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
28263
- init_debug_store();
28264
28288
  import { Fragment as Fragment17, jsx as jsx55, jsxs as jsxs45 } from "react/jsx-runtime";
28265
28289
  var FIELD_ORDER = [
28266
28290
  "spaceId",
@@ -28268,8 +28292,7 @@ var FIELD_ORDER = [
28268
28292
  "cmaToken",
28269
28293
  "host",
28270
28294
  "defaultComponentDir",
28271
- "defaultTokenFile",
28272
- "contentfulBaseDir"
28295
+ "defaultTokenFile"
28273
28296
  ];
28274
28297
  function debugFields(config) {
28275
28298
  return {
@@ -28278,8 +28301,7 @@ function debugFields(config) {
28278
28301
  cma_token: config?.cmaToken ?? "",
28279
28302
  host: config?.host ?? "",
28280
28303
  default_component_dir: config?.defaultComponentDir ?? "",
28281
- default_token_file: config?.defaultTokenFile ?? "",
28282
- contentful_base_dir: config?.contentfulBaseDir ?? ""
28304
+ default_token_file: config?.defaultTokenFile ?? ""
28283
28305
  };
28284
28306
  }
28285
28307
  var FIELD_LABELS = {
@@ -28288,8 +28310,7 @@ var FIELD_LABELS = {
28288
28310
  cmaToken: "CMA Token",
28289
28311
  host: "API Host (optional)",
28290
28312
  defaultComponentDir: "Default component directory (optional)",
28291
- defaultTokenFile: "Default token file (optional)",
28292
- contentfulBaseDir: "Default project directory, where .contentful goes (optional)"
28313
+ defaultTokenFile: "Default token file (optional)"
28293
28314
  };
28294
28315
  function ConfigurationScreen({ onDone }) {
28295
28316
  const [stage, setStage] = useState29("loading");
@@ -28326,7 +28347,6 @@ function ConfigurationScreen({ onDone }) {
28326
28347
  setNotice(null);
28327
28348
  writeCredentials(config).then(() => {
28328
28349
  setLastSaved(config);
28329
- if (config.contentfulBaseDir) void startDebugSessionIn(config.contentfulBaseDir);
28330
28350
  setNotice({ kind: "success", text: "Configuration saved" });
28331
28351
  setStage("form");
28332
28352
  }).catch((err) => {
@@ -28456,7 +28476,6 @@ async function writeAnalyticsSetting(setting) {
28456
28476
  }
28457
28477
 
28458
28478
  // packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
28459
- init_debug_store();
28460
28479
  import { Fragment as Fragment18, jsx as jsx56, jsxs as jsxs46 } from "react/jsx-runtime";
28461
28480
  function OptInAnalyticsScreen({ onDone }) {
28462
28481
  const [loading, setLoading] = useState30(true);
@@ -28517,8 +28536,6 @@ function OptInAnalyticsScreen({ onDone }) {
28517
28536
  // packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
28518
28537
  import { useEffect as useEffect25, useState as useState31 } from "react";
28519
28538
  import { Box as Box46, Text as Text48, useInput as useInput13 } from "ink";
28520
- init_version();
28521
- init_debug_store();
28522
28539
  import { jsx as jsx57, jsxs as jsxs47 } from "react/jsx-runtime";
28523
28540
  var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
28524
28541
  function UpgradeScreen({ onDone }) {
@@ -28590,8 +28607,6 @@ function renderBody(upgradeCheck) {
28590
28607
  // packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
28591
28608
  import { useEffect as useEffect26, useState as useState32 } from "react";
28592
28609
  import { Box as Box47, Text as Text49, useInput as useInput14 } from "ink";
28593
- init_debug_mode_store();
28594
- init_debug_store();
28595
28610
  import { jsx as jsx58, jsxs as jsxs48 } from "react/jsx-runtime";
28596
28611
  function DebugModeScreen({ onDone }) {
28597
28612
  const [loading, setLoading] = useState32(true);