@contentful/experience-design-system-cli 2.37.1-dev-build-a029dc0a.0 → 2.37.1-dev-build-1c5cd11a.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -32,31 +32,6 @@ var init_package_root = __esm({
32
32
  }
33
33
  });
34
34
 
35
- // packages/experience-design-system-cli/src/legacy/legacy-cli-path.ts
36
- import { existsSync as existsSync2 } from "node:fs";
37
- import { join as join2 } from "node:path";
38
- function findLegacyCliPath() {
39
- const root = findPackageRoot(import.meta.url, PACKAGE_NAME);
40
- const candidates = [
41
- join2(root, "legacy", "bin", "cli.js"),
42
- join2(root, "..", "experience-design-system-cli-legacy", "bin", "cli.js")
43
- ];
44
- const found = candidates.find((candidate) => existsSync2(candidate));
45
- if (!found) {
46
- throw new Error(`Legacy CLI not found. Looked in:
47
- ${candidates.join("\n")}`);
48
- }
49
- return found;
50
- }
51
- var PACKAGE_NAME;
52
- var init_legacy_cli_path = __esm({
53
- "packages/experience-design-system-cli/src/legacy/legacy-cli-path.ts"() {
54
- "use strict";
55
- init_package_root();
56
- PACKAGE_NAME = "@contentful/experience-design-system-cli";
57
- }
58
- });
59
-
60
35
  // packages/experience-design-system-cli/src/tui/home/home.theme.ts
61
36
  function brandBar(width, ramp = BRAND_RAMP) {
62
37
  if (width <= 0 || ramp.length === 0) return [];
@@ -669,9 +644,83 @@ var init_config_root = __esm({
669
644
  });
670
645
 
671
646
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/helpers/source-excerpt.js
647
+ function escapeForRegExp(value) {
648
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
649
+ }
650
+ function identifierPattern(name) {
651
+ return new RegExp(`(?<![A-Za-z0-9_$])${escapeForRegExp(name)}(?![A-Za-z0-9_$])`);
652
+ }
653
+ function excerptAroundNames(text, names, maxChars, contextLines = 6) {
654
+ if (text.length <= maxChars)
655
+ return { content: text, usesNotShown: [] };
656
+ const patterns = names.filter((name) => name.length > 0).map((name) => ({ name, pattern: identifierPattern(name) }));
657
+ const lines = text.split("\n");
658
+ const windows = [];
659
+ lines.forEach((line, index) => {
660
+ const mentioned = patterns.filter(({ pattern }) => pattern.test(line)).map(({ name }) => name);
661
+ if (mentioned.length === 0)
662
+ return;
663
+ const start = Math.max(0, index - contextLines);
664
+ const end = Math.min(lines.length - 1, index + contextLines);
665
+ const last = windows[windows.length - 1];
666
+ if (last && start <= last.end + 1) {
667
+ last.end = Math.max(last.end, end);
668
+ for (const name of mentioned)
669
+ last.names.add(name);
670
+ } else {
671
+ windows.push({ start, end, names: new Set(mentioned) });
672
+ }
673
+ });
674
+ if (windows.length === 0) {
675
+ return { content: `${text.slice(0, maxChars)}
676
+ ${TRUNCATED_MARKER}`, usesNotShown: [] };
677
+ }
678
+ const lastWindowFor = /* @__PURE__ */ new Map();
679
+ for (const window of windows)
680
+ for (const name of window.names)
681
+ lastWindowFor.set(name, window);
682
+ const kept = [];
683
+ const cut = /* @__PURE__ */ new Set();
684
+ let used = 0;
685
+ for (const window of [...windows].reverse()) {
686
+ const chunk = lines.slice(window.start, window.end + 1).join("\n");
687
+ const separator = kept.length > 0 ? `
688
+ ${ELLIPSIS_MARKER}
689
+ ` : "";
690
+ if (used + separator.length + chunk.length > maxChars) {
691
+ if (kept.length === 0) {
692
+ const head = chunk.slice(0, maxChars);
693
+ kept.push({ window, text: head });
694
+ used += head.length;
695
+ for (const name of window.names) {
696
+ if (lastWindowFor.get(name) === window && !identifierPattern(name).test(head))
697
+ cut.add(name);
698
+ }
699
+ continue;
700
+ }
701
+ for (const name of window.names) {
702
+ if (lastWindowFor.get(name) === window)
703
+ cut.add(name);
704
+ }
705
+ continue;
706
+ }
707
+ kept.push({ window, text: chunk });
708
+ used += separator.length + chunk.length;
709
+ }
710
+ kept.sort((a, b) => a.window.start - b.window.start);
711
+ const parts = kept.map((entry, index) => (index > 0 ? `
712
+ ${ELLIPSIS_MARKER}
713
+ ` : "") + entry.text);
714
+ const usesNotShown = names.filter((name, index) => cut.has(name) && names.indexOf(name) === index);
715
+ return { content: `${parts.join("")}
716
+ ${TRUNCATED_MARKER}`, usesNotShown };
717
+ }
718
+ var ELLIPSIS_MARKER, TRUNCATED_MARKER;
672
719
  var init_source_excerpt = __esm({
673
720
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/helpers/source-excerpt.js"() {
674
721
  "use strict";
722
+ ELLIPSIS_MARKER = "/* \u2026 */";
723
+ TRUNCATED_MARKER = "/* truncated */";
675
724
  }
676
725
  });
677
726
 
@@ -752,6 +801,14 @@ function getSessionById(db, sessionId) {
752
801
  const row = db.prepare("SELECT id FROM sessions WHERE id = ?").get(sessionId);
753
802
  return row ?? null;
754
803
  }
804
+ function getLatestCompletedSessionForCommand(db, command) {
805
+ const row = db.prepare(`SELECT s.id FROM sessions s
806
+ JOIN steps st ON st.session_id = s.id
807
+ WHERE st.command = ? AND st.status = 'complete'
808
+ ORDER BY st.started_at DESC, st.id DESC
809
+ LIMIT 1`).get(command);
810
+ return row?.id ?? null;
811
+ }
755
812
  var init_read = __esm({
756
813
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/sessions/read.js"() {
757
814
  "use strict";
@@ -1100,6 +1157,13 @@ function getRawTokenNamePaths(db, sessionId) {
1100
1157
  const rows = db.prepare("SELECT raw_name, path FROM raw_token_name_paths WHERE session_id = ? ORDER BY raw_name").all(sessionId);
1101
1158
  return Object.fromEntries(rows.map((row) => [String(row.raw_name), String(row.path)]));
1102
1159
  }
1160
+ function getRawTokenNamePathRows(db, sessionId) {
1161
+ return db.prepare("SELECT raw_name, path, source FROM raw_token_name_paths WHERE session_id = ? ORDER BY raw_name").all(sessionId).map((row) => ({
1162
+ rawName: String(row.raw_name),
1163
+ path: String(row.path),
1164
+ source: String(row.source)
1165
+ }));
1166
+ }
1103
1167
  var init_read3 = __esm({
1104
1168
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/tokens/read.js"() {
1105
1169
  "use strict";
@@ -1168,6 +1232,27 @@ function upsertRawTokenGroup(db, sessionId, call) {
1168
1232
  db.prepare(`INSERT INTO raw_token_groups (session_id, path, description) VALUES (?, ?, ?)
1169
1233
  ON CONFLICT(session_id, path) DO UPDATE SET description = excluded.description`).run(sessionId, call.path, call.description ?? null);
1170
1234
  }
1235
+ function updateRawTokenNamePaths(db, sessionId, tokenNamePaths, source) {
1236
+ const entries = Object.entries(tokenNamePaths);
1237
+ const deletePaths = db.prepare("DELETE FROM raw_token_name_paths WHERE session_id = ? AND source = ?");
1238
+ const insertPath = db.prepare("INSERT OR IGNORE INTO raw_token_name_paths (session_id, raw_name, path, source) VALUES (?, ?, ?, ?)");
1239
+ const deleteAutomaticByName = db.prepare("DELETE FROM raw_token_name_paths WHERE session_id = ? AND raw_name = ? AND source = 'automatic'");
1240
+ deletePaths.run(sessionId, source);
1241
+ for (const [rawName, path5] of entries) {
1242
+ if (source === "manual")
1243
+ deleteAutomaticByName.run(sessionId, rawName);
1244
+ insertPath.run(sessionId, rawName, path5, source);
1245
+ }
1246
+ }
1247
+ function updateRawPropTokenPaths(db, sessionId, componentId, propName, paths, source) {
1248
+ db.prepare(`DELETE FROM raw_prop_token_paths
1249
+ WHERE session_id = ? AND component_id = ? AND prop_name = ?`).run(sessionId, componentId, propName);
1250
+ const insertPath = db.prepare(`INSERT INTO raw_prop_token_paths (session_id, component_id, prop_name, source, position, path)
1251
+ VALUES (?, ?, ?, ?, ?, ?)`);
1252
+ paths.forEach((path5, position) => {
1253
+ insertPath.run(sessionId, componentId, propName, source, position, path5);
1254
+ });
1255
+ }
1171
1256
  var init_write3 = __esm({
1172
1257
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/tokens/write.js"() {
1173
1258
  "use strict";
@@ -1241,6 +1326,12 @@ var init_apply_tool_calls = __esm({
1241
1326
  });
1242
1327
 
1243
1328
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/services/tokens/replace-raw-token-name-paths.js
1329
+ function replaceRawTokenNamePaths(db, sessionId, tokenNamePaths, source = "automatic") {
1330
+ withTransaction(db, () => {
1331
+ updateRawTokenNamePaths(db, sessionId, tokenNamePaths, source);
1332
+ updateSessionTimestamp(db, sessionId, (/* @__PURE__ */ new Date()).toISOString());
1333
+ });
1334
+ }
1244
1335
  var init_replace_raw_token_name_paths = __esm({
1245
1336
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/services/tokens/replace-raw-token-name-paths.js"() {
1246
1337
  "use strict";
@@ -1251,6 +1342,12 @@ var init_replace_raw_token_name_paths = __esm({
1251
1342
  });
1252
1343
 
1253
1344
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/services/tokens/replace-raw-prop-token-paths.js
1345
+ function replaceRawPropTokenPaths(db, sessionId, componentId, propName, paths, source) {
1346
+ withTransaction(db, () => {
1347
+ updateRawPropTokenPaths(db, sessionId, componentId, propName, paths, source);
1348
+ updateSessionTimestamp(db, sessionId, (/* @__PURE__ */ new Date()).toISOString());
1349
+ });
1350
+ }
1254
1351
  var init_replace_raw_prop_token_paths = __esm({
1255
1352
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/services/tokens/replace-raw-prop-token-paths.js"() {
1256
1353
  "use strict";
@@ -2024,7 +2121,7 @@ async function runAgent(options) {
2024
2121
  promptLen: prompt.length,
2025
2122
  promptHead: prompt.slice(0, 500)
2026
2123
  });
2027
- return new Promise((resolve22) => {
2124
+ return new Promise((resolve25) => {
2028
2125
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
2029
2126
  const child = spawn3(binary, args, {
2030
2127
  stdio: ["pipe", "pipe", "pipe"],
@@ -2073,7 +2170,7 @@ async function runAgent(options) {
2073
2170
  stderrLen: stderr.length,
2074
2171
  stderrTail: stderr.slice(-1e3)
2075
2172
  });
2076
- resolve22(result);
2173
+ resolve25(result);
2077
2174
  });
2078
2175
  });
2079
2176
  }
@@ -2095,7 +2192,7 @@ async function checkAgentAuth(agent) {
2095
2192
  return "not-found";
2096
2193
  if (agent !== "claude")
2097
2194
  return "ok";
2098
- return new Promise((resolve22) => {
2195
+ return new Promise((resolve25) => {
2099
2196
  const child = spawn4(binary, ["auth", "status", "--json"], { stdio: ["ignore", "pipe", "pipe"] });
2100
2197
  let stdout = "";
2101
2198
  let done = false;
@@ -2104,7 +2201,7 @@ async function checkAgentAuth(agent) {
2104
2201
  return;
2105
2202
  done = true;
2106
2203
  child.kill("SIGTERM");
2107
- resolve22("unauthenticated");
2204
+ resolve25("unauthenticated");
2108
2205
  }, 5e3);
2109
2206
  child.stdout?.on("data", (chunk) => {
2110
2207
  stdout += chunk.toString();
@@ -2115,14 +2212,14 @@ async function checkAgentAuth(agent) {
2115
2212
  done = true;
2116
2213
  clearTimeout(timer);
2117
2214
  if (code !== 0) {
2118
- resolve22("unauthenticated");
2215
+ resolve25("unauthenticated");
2119
2216
  return;
2120
2217
  }
2121
2218
  try {
2122
2219
  const status = JSON.parse(stdout);
2123
- resolve22(status.loggedIn ? "ok" : "unauthenticated");
2220
+ resolve25(status.loggedIn ? "ok" : "unauthenticated");
2124
2221
  } catch {
2125
- resolve22("unauthenticated");
2222
+ resolve25("unauthenticated");
2126
2223
  }
2127
2224
  });
2128
2225
  });
@@ -2132,9 +2229,9 @@ async function binaryIsOnPath(binary) {
2132
2229
  const fs = await import("node:fs/promises");
2133
2230
  return fs.access(binary).then(() => true, () => false);
2134
2231
  }
2135
- return new Promise((resolve22) => {
2232
+ return new Promise((resolve25) => {
2136
2233
  const child = spawn4(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
2137
- child.on("close", (code) => resolve22(code === 0));
2234
+ child.on("close", (code) => resolve25(code === 0));
2138
2235
  });
2139
2236
  }
2140
2237
  var init_check_agent_auth = __esm({
@@ -3271,6 +3368,8 @@ var init_cache_keys = __esm({
3271
3368
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/db.js
3272
3369
  import { DatabaseSync } from "node:sqlite";
3273
3370
  import { mkdirSync, readFileSync as readFileSync3 } from "node:fs";
3371
+ import { readFile as readFile4 } from "node:fs/promises";
3372
+ import { createHash as createHash5 } from "node:crypto";
3274
3373
  import { dirname as dirname4, resolve as resolve6 } from "node:path";
3275
3374
  function getPipelineDbPath() {
3276
3375
  if (process.env.EDS_PIPELINE_DB_PATH) {
@@ -3588,6 +3687,109 @@ function loadComponentRationale(db, sessionId, componentName) {
3588
3687
  }))
3589
3688
  };
3590
3689
  }
3690
+ function applyToolCalls(db, sessionId, componentId, componentName, calls, incomingWarnings, options = {}) {
3691
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3692
+ const warnings = [...incomingWarnings];
3693
+ let classified = 0;
3694
+ let excluded = 0;
3695
+ let slots = 0;
3696
+ const updateProp = db.prepare(`UPDATE raw_props SET cdf_type = ?, cdf_category = ?, cdf_token_kind = ?, required = ?, description = ?, rationale = ?
3697
+ WHERE session_id = ? AND component_id = ? AND name = ?`);
3698
+ const clearProp = db.prepare(`UPDATE raw_props
3699
+ SET cdf_type = CASE WHEN type = 'boolean' THEN 'boolean' ELSE 'string' END,
3700
+ cdf_category = 'unattached',
3701
+ cdf_token_kind = NULL,
3702
+ required = 0,
3703
+ rationale = ?
3704
+ WHERE session_id = ? AND component_id = ? AND name = ?`);
3705
+ const deleteAllowedValues = db.prepare(`DELETE FROM raw_prop_allowed_values WHERE session_id = ? AND component_id = ? AND prop_name = ?`);
3706
+ const deleteTokenPaths = db.prepare(`DELETE FROM raw_prop_token_paths WHERE session_id = ? AND component_id = ? AND prop_name = ?`);
3707
+ const insertAllowedValue = db.prepare(`INSERT OR IGNORE INTO raw_prop_allowed_values (session_id, component_id, prop_name, value, position)
3708
+ VALUES (?, ?, ?, ?, ?)`);
3709
+ const deleteAllowedComponents = db.prepare(`DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND slot_name = ?`);
3710
+ const insertAllowedComponent = db.prepare(`INSERT OR IGNORE INTO raw_slot_allowed_components (session_id, component_id, slot_name, allowed_component, position)
3711
+ VALUES (?, ?, ?, ?, ?)`);
3712
+ const updateSlot = db.prepare(`UPDATE raw_slots SET required = ?, description = ? WHERE session_id = ? AND component_id = ? AND name = ?`);
3713
+ db.exec("BEGIN");
3714
+ try {
3715
+ for (const call of calls) {
3716
+ if (call.tool === "classify_component") {
3717
+ if (call.description !== void 0) {
3718
+ db.prepare("UPDATE raw_components SET description = ? WHERE session_id = ? AND component_id = ?").run(call.description, sessionId, componentId);
3719
+ }
3720
+ if (call.rationale) {
3721
+ if (call.rationale.description !== void 0) {
3722
+ db.prepare("UPDATE raw_components SET component_description_rationale = ? WHERE session_id = ? AND component_id = ?").run(call.rationale.description, sessionId, componentId);
3723
+ }
3724
+ if (call.rationale.props !== void 0) {
3725
+ db.prepare("UPDATE raw_components SET props_rationale = ? WHERE session_id = ? AND component_id = ?").run(call.rationale.props, sessionId, componentId);
3726
+ }
3727
+ if (call.rationale.slots !== void 0) {
3728
+ db.prepare("UPDATE raw_components SET slots_rationale = ? WHERE session_id = ? AND component_id = ?").run(call.rationale.slots, sessionId, componentId);
3729
+ }
3730
+ }
3731
+ } else if (call.tool === "classify_prop") {
3732
+ const changes = updateProp.run(call.cdf_type, call.cdf_category, call.token_kind ?? null, call.required !== void 0 ? call.required ? 1 : 0 : 0, call.description ?? null, call.reason ?? null, sessionId, componentId, call.prop);
3733
+ if (changes.changes === 0) {
3734
+ warnings.push(`${componentName}: classify_prop '${call.prop}' \u2014 prop not found, skipped`);
3735
+ continue;
3736
+ }
3737
+ if (call.cdf_type === "token") {
3738
+ deleteAllowedValues.run(sessionId, componentId, call.prop);
3739
+ if (call.values && call.values.length > 0) {
3740
+ const count = call.values.length;
3741
+ warnings.push(`${componentName}: classify_prop '${call.prop}' \u2014 dropped ${count} value${count === 1 ? "" : "s"} on a token property; its options list is $token.allowed, not $values`);
3742
+ }
3743
+ } else {
3744
+ deleteTokenPaths.run(sessionId, componentId, call.prop);
3745
+ if (call.values && call.values.length > 0) {
3746
+ deleteAllowedValues.run(sessionId, componentId, call.prop);
3747
+ call.values.forEach((v, i) => insertAllowedValue.run(sessionId, componentId, call.prop, v, i));
3748
+ }
3749
+ }
3750
+ if (call.default !== void 0) {
3751
+ const storedDefault = typeof call.default === "boolean" ? String(call.default) : call.default;
3752
+ db.prepare(`UPDATE raw_props SET default_value = ? WHERE session_id = ? AND component_id = ? AND name = ?`).run(storedDefault, sessionId, componentId, call.prop);
3753
+ }
3754
+ classified++;
3755
+ } else if (call.tool === "exclude_prop") {
3756
+ clearProp.run(call.reason || null, sessionId, componentId, call.prop);
3757
+ excluded++;
3758
+ } else if (call.tool === "classify_slot") {
3759
+ const slotRequired = call.required !== void 0 ? call.required ? 1 : 0 : 1;
3760
+ const slotChanges = updateSlot.run(slotRequired, call.description ?? null, sessionId, componentId, call.slot);
3761
+ if (slotChanges.changes === 0) {
3762
+ warnings.push(`${componentName}: classify_slot '${call.slot}' \u2014 slot not found, skipped`);
3763
+ continue;
3764
+ }
3765
+ if (call.rationale !== void 0) {
3766
+ db.prepare("UPDATE raw_slots SET rationale = ? WHERE session_id = ? AND component_id = ? AND name = ?").run(call.rationale, sessionId, componentId, call.slot);
3767
+ }
3768
+ if (call.allowed_components !== void 0) {
3769
+ deleteAllowedComponents.run(sessionId, componentId, call.slot);
3770
+ const allowedComponents = options.allowedComponentNames ? call.allowed_components.filter((allowedComponent) => options.allowedComponentNames.has(allowedComponent)) : call.allowed_components;
3771
+ if (options.allowedComponentNames) {
3772
+ const dropped = [
3773
+ ...new Set(call.allowed_components.filter((ac) => !options.allowedComponentNames.has(ac)))
3774
+ ];
3775
+ for (const allowedComponent of dropped) {
3776
+ warnings.push(`${componentName}: classify_slot '${call.slot}' \u2014 dropped unknown allowed component '${allowedComponent}'`);
3777
+ }
3778
+ }
3779
+ allowedComponents.forEach((ac, i) => insertAllowedComponent.run(sessionId, componentId, call.slot, ac, i));
3780
+ }
3781
+ slots++;
3782
+ }
3783
+ }
3784
+ db.prepare(`UPDATE raw_components SET status = 'generated', extracted_at = ? WHERE session_id = ? AND component_id = ?`).run(now, sessionId, componentId);
3785
+ db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
3786
+ db.exec("COMMIT");
3787
+ } catch (e) {
3788
+ db.exec("ROLLBACK");
3789
+ throw e;
3790
+ }
3791
+ return { classified, excluded, slots, warnings };
3792
+ }
3591
3793
  function getOrCreateSession(db, sessionFlag, sessionName, hints) {
3592
3794
  return getOrCreateSessionForCommand(db, sessionFlag, sessionName, hints);
3593
3795
  }
@@ -3797,6 +3999,176 @@ function loadRawComponents(db, sessionId, allowedNames) {
3797
3999
  })
3798
4000
  }));
3799
4001
  }
4002
+ function rewrittenSourcePaths(basePath) {
4003
+ for (const [emitted, sources] of TS_ESM_EXTENSION_REWRITES) {
4004
+ if (!basePath.endsWith(emitted))
4005
+ continue;
4006
+ const stem = basePath.slice(0, -emitted.length);
4007
+ return sources.map((ext) => `${stem}${ext}`);
4008
+ }
4009
+ return [];
4010
+ }
4011
+ function identifiersIn(propTypes) {
4012
+ const names = /* @__PURE__ */ new Set();
4013
+ for (const propType of propTypes) {
4014
+ for (const match2 of propType.matchAll(IDENTIFIER_PATTERN))
4015
+ names.add(match2[0]);
4016
+ }
4017
+ return [...names];
4018
+ }
4019
+ function declaresAnyType(text, typeNames) {
4020
+ return typeNames.some((name) => new RegExp(`\\b(?:type|interface|enum|const|class)\\s+${escapeForRegExp(name)}\\b`).test(text));
4021
+ }
4022
+ function extractRelativeImportPaths(sourceText) {
4023
+ const specifiers = /* @__PURE__ */ new Set();
4024
+ for (const match2 of sourceText.matchAll(RELATIVE_IMPORT_PATTERN)) {
4025
+ if (match2[1])
4026
+ specifiers.add(match2[1]);
4027
+ }
4028
+ return [...specifiers];
4029
+ }
4030
+ async function resolveRelativeImport(specifier, fromDir) {
4031
+ const basePath = resolve6(fromDir, specifier);
4032
+ const candidates = [
4033
+ basePath,
4034
+ ...rewrittenSourcePaths(basePath),
4035
+ ...SIBLING_FILE_EXTENSIONS.map((ext) => `${basePath}${ext}`),
4036
+ ...SIBLING_FILE_EXTENSIONS.map((ext) => resolve6(basePath, `index${ext}`))
4037
+ ];
4038
+ for (const candidate of candidates) {
4039
+ try {
4040
+ await readFile4(candidate, "utf8");
4041
+ return candidate;
4042
+ } catch {
4043
+ }
4044
+ }
4045
+ return void 0;
4046
+ }
4047
+ async function resolveImportSpecifiers(sourceText, fromDir) {
4048
+ const resolvedPaths = [];
4049
+ for (const specifier of extractRelativeImportPaths(sourceText)) {
4050
+ const resolvedPath = await resolveRelativeImport(specifier, fromDir);
4051
+ if (resolvedPath)
4052
+ resolvedPaths.push(resolvedPath);
4053
+ }
4054
+ return resolvedPaths;
4055
+ }
4056
+ async function loadSiblingFiles(sourceText, sourcePath, propNames, candidateTypeNames = []) {
4057
+ const visited = /* @__PURE__ */ new Set([resolve6(sourcePath)]);
4058
+ const discovered = [];
4059
+ let frontier = [{ text: sourceText, dir: dirname4(sourcePath) }];
4060
+ for (let hop = 0; hop < MAX_SIBLING_DEPTH && discovered.length < MAX_SIBLING_CANDIDATES_EXPLORED; hop++) {
4061
+ const nextFrontier = [];
4062
+ for (const node of frontier) {
4063
+ if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
4064
+ break;
4065
+ const resolvedPaths = await resolveImportSpecifiers(node.text, node.dir);
4066
+ for (const resolvedPath of resolvedPaths) {
4067
+ if (visited.has(resolvedPath))
4068
+ continue;
4069
+ visited.add(resolvedPath);
4070
+ if (discovered.length >= MAX_SIBLING_CANDIDATES_EXPLORED)
4071
+ break;
4072
+ let content;
4073
+ try {
4074
+ content = await readFile4(resolvedPath, "utf8");
4075
+ } catch {
4076
+ continue;
4077
+ }
4078
+ discovered.push({ path: resolvedPath, content });
4079
+ nextFrontier.push({ text: content, dir: dirname4(resolvedPath) });
4080
+ }
4081
+ }
4082
+ frontier = nextFrontier;
4083
+ }
4084
+ const inHand = [sourceText, ...discovered.map((d) => d.content)];
4085
+ const declaredTypeNames = candidateTypeNames.filter((name) => inHand.some((text) => declaresAnyType(text, [name])));
4086
+ const usesNotShown = /* @__PURE__ */ new Set();
4087
+ const searchNames = [.../* @__PURE__ */ new Set([...propNames, ...declaredTypeNames])];
4088
+ let enlarged = 0;
4089
+ const siblings = discovered.slice(0, MAX_SIBLING_FILES).map((d) => {
4090
+ const enlarge = enlarged < MAX_ENLARGED_SIBLINGS && declaresAnyType(d.content, declaredTypeNames);
4091
+ if (enlarge)
4092
+ enlarged++;
4093
+ const budget = enlarge ? MAX_TYPE_DECLARING_SIBLING_CHARS : MAX_SIBLING_SNIPPET_CHARS;
4094
+ const excerpt = excerptAroundNames(d.content, searchNames, budget);
4095
+ for (const name of excerpt.usesNotShown)
4096
+ usesNotShown.add(name);
4097
+ return { path: d.path, content: excerpt.content };
4098
+ });
4099
+ const truncatedCount = Math.max(0, discovered.length - MAX_SIBLING_FILES);
4100
+ return {
4101
+ siblings,
4102
+ truncatedCount,
4103
+ usesNotShown: propNames.filter((name) => usesNotShown.has(name)),
4104
+ declaredTypeNames
4105
+ };
4106
+ }
4107
+ async function loadComponentSourceRef(name, sourcePath, propNames = [], propTypes = []) {
4108
+ let content = null;
4109
+ let siblingFiles = [];
4110
+ let truncatedSiblingCount = 0;
4111
+ const usesNotShown = /* @__PURE__ */ new Set();
4112
+ try {
4113
+ const rawText = await readFile4(sourcePath, "utf8");
4114
+ let siblingUsesNotShown;
4115
+ let declaredTypeNames;
4116
+ ({
4117
+ siblings: siblingFiles,
4118
+ truncatedCount: truncatedSiblingCount,
4119
+ usesNotShown: siblingUsesNotShown,
4120
+ declaredTypeNames
4121
+ } = await loadSiblingFiles(rawText, sourcePath, propNames, identifiersIn(propTypes)));
4122
+ const mainExcerpt = excerptAroundNames(rawText, [.../* @__PURE__ */ new Set([...propNames, ...declaredTypeNames])], MAX_COMPONENT_SOURCE_CHARS);
4123
+ content = mainExcerpt.content;
4124
+ for (const name2 of mainExcerpt.usesNotShown)
4125
+ usesNotShown.add(name2);
4126
+ for (const name2 of siblingUsesNotShown)
4127
+ usesNotShown.add(name2);
4128
+ } catch {
4129
+ }
4130
+ const ref = { component: name, sourcePath, content };
4131
+ if (siblingFiles.length > 0)
4132
+ ref.siblingFiles = siblingFiles;
4133
+ if (truncatedSiblingCount > 0)
4134
+ ref.truncatedSiblingCount = truncatedSiblingCount;
4135
+ const notShown = propNames.filter((name2) => usesNotShown.has(name2));
4136
+ if (notShown.length > 0)
4137
+ ref.usesNotShown = notShown;
4138
+ return ref;
4139
+ }
4140
+ async function loadComponentSourceRefs(db, sessionId) {
4141
+ const rows = db.prepare(`SELECT component_id, name, source, source_path FROM raw_components WHERE session_id = ? AND status = 'generated' ORDER BY rowid`).all(sessionId);
4142
+ const propsFor = db.prepare(`SELECT name, type FROM raw_props WHERE session_id = ? AND component_id = ? ORDER BY position`);
4143
+ return Promise.all(rows.map((r) => {
4144
+ const props = propsFor.all(sessionId, r.component_id);
4145
+ return loadComponentSourceRef(r.name, r.source_path ?? r.source, props.map((p) => p.name), props.map((p) => p.type));
4146
+ }));
4147
+ }
4148
+ function renameEmptySlots(db, sessionId, componentId, componentName, slotCount) {
4149
+ const emptySlots = db.prepare(`SELECT name, position FROM raw_slots
4150
+ WHERE session_id = ? AND component_id = ? AND trim(name) = ''
4151
+ ORDER BY position`).all(sessionId, componentId);
4152
+ if (emptySlots.length === 0)
4153
+ return { renames: [], warnings: [] };
4154
+ const renames = [];
4155
+ const warnings = [];
4156
+ const rename4 = db.prepare(`UPDATE raw_slots SET name = ? WHERE session_id = ? AND component_id = ? AND name = ? AND position = ?`);
4157
+ db.exec("BEGIN");
4158
+ try {
4159
+ for (const slot of emptySlots) {
4160
+ const newName = slotCount === 1 ? "children" : `slot_${slot.position}`;
4161
+ rename4.run(newName, sessionId, componentId, slot.name, slot.position);
4162
+ renames.push({ oldName: slot.name, newName });
4163
+ warnings.push(`${componentName}: slot at position ${slot.position} had empty name \u2014 renamed to "${newName}" for classification`);
4164
+ }
4165
+ db.exec("COMMIT");
4166
+ } catch (e) {
4167
+ db.exec("ROLLBACK");
4168
+ throw e;
4169
+ }
4170
+ return { renames, warnings };
4171
+ }
3800
4172
  function parseReviewReasons(raw) {
3801
4173
  try {
3802
4174
  const parsed = JSON.parse(raw ?? "[]");
@@ -4014,29 +4386,10 @@ function applyScopeDecisions(db, sessionId, decisions) {
4014
4386
  const placeholders = accepted.map(() => "?").join(",");
4015
4387
  db.prepare(`UPDATE raw_components SET status = 'generated' WHERE session_id = ? AND name IN (${placeholders})`).run(sessionId, ...accepted);
4016
4388
  }
4017
- removeSlotAllowedComponents(db, sessionId, decisions.excludedSlotEdges ?? [], rejected);
4018
4389
  db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, sessionId);
4019
4390
  }
4020
- function removeSlotAllowedComponents(db, sessionId, edges, rejectedNames) {
4021
- if (edges.length === 0 && rejectedNames.length === 0)
4022
- return;
4023
- const componentId = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
4024
- const removeEdge = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ? AND allowed_component = ?");
4025
- const removeEverywhere = db.prepare("DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND allowed_component = ?");
4026
- db.exec("BEGIN");
4027
- try {
4028
- for (const edge of edges) {
4029
- const row = componentId.get(sessionId, edge.parent);
4030
- if (row)
4031
- removeEdge.run(sessionId, row.component_id, edge.child);
4032
- }
4033
- for (const name of rejectedNames)
4034
- removeEverywhere.run(sessionId, name);
4035
- db.exec("COMMIT");
4036
- } catch (e) {
4037
- db.exec("ROLLBACK");
4038
- throw e;
4039
- }
4391
+ function findLatestSessionForCommand(db, command) {
4392
+ return getLatestCompletedSessionForCommand(db, command);
4040
4393
  }
4041
4394
  function seedCDFFromPreviewResponse(db, sessionId, removedItems) {
4042
4395
  if (removedItems.length === 0)
@@ -4105,6 +4458,35 @@ function backfillUnclassifiedProps(db, sessionId) {
4105
4458
  )`).run(sessionId, sessionId);
4106
4459
  return Number(withCategory.changes) + Number(withoutCategory.changes);
4107
4460
  }
4461
+ function computeMapTokensInputHash(db, sessionId, componentSourceRefs = []) {
4462
+ const props = db.prepare(`SELECT rc.name AS component_name, rp.name AS prop_name, rp.cdf_token_kind, rp.default_value
4463
+ FROM raw_props rp
4464
+ JOIN raw_components rc ON rc.session_id = rp.session_id AND rc.component_id = rp.component_id
4465
+ WHERE rp.session_id = ? AND rp.cdf_type = 'token' AND rp.cdf_category = 'design'
4466
+ ORDER BY rc.name, rp.name`).all(sessionId);
4467
+ const tokens = db.prepare(`SELECT path, type FROM raw_tokens WHERE session_id = ? ORDER BY path`).all(sessionId);
4468
+ const defaultMappings = db.prepare("SELECT raw_name, path, source FROM raw_token_name_paths WHERE session_id = ? ORDER BY raw_name").all(sessionId);
4469
+ const payload = {
4470
+ props: props.map((p) => ({
4471
+ component: p.component_name,
4472
+ prop: p.prop_name,
4473
+ tokenKind: p.cdf_token_kind,
4474
+ rawDefault: p.default_value
4475
+ })),
4476
+ tokens,
4477
+ defaultMappings,
4478
+ // The agent's evidence, not just its inputs: a comment or allowlist edit
4479
+ // in a source file (or a sibling it reads) changes the correct answer
4480
+ // without touching props or tokens, so it must invalidate the cache too.
4481
+ sourceRefs: [...componentSourceRefs].sort((a, b) => a.component.localeCompare(b.component)).map((ref) => ({
4482
+ component: ref.component,
4483
+ content: ref.content,
4484
+ siblingFiles: (ref.siblingFiles ?? []).map((s) => ({ path: s.path, content: s.content })).sort((a, b) => a.path.localeCompare(b.path)),
4485
+ usesNotShown: [...ref.usesNotShown ?? []].sort()
4486
+ }))
4487
+ };
4488
+ return createHash5("sha256").update(JSON.stringify(payload)).digest("hex");
4489
+ }
4108
4490
  function lookupCache(db, inputHash, entityType, entityId, promptHash = "") {
4109
4491
  const row = db.prepare(`SELECT input_hash, entity_type, entity_id, source_session_id, human_edited, created_at, updated_at, prompt_hash
4110
4492
  FROM generation_cache
@@ -4122,6 +4504,24 @@ function lookupCache(db, inputHash, entityType, entityId, promptHash = "") {
4122
4504
  updatedAt: row.updated_at
4123
4505
  };
4124
4506
  }
4507
+ function lookupCacheByEntity(db, entityType, entityId) {
4508
+ const row = db.prepare(`SELECT input_hash, entity_type, entity_id, source_session_id, human_edited, created_at, updated_at, prompt_hash
4509
+ FROM generation_cache
4510
+ WHERE entity_type = ? AND entity_id = ?
4511
+ ORDER BY updated_at DESC LIMIT 1`).get(entityType, entityId);
4512
+ if (!row)
4513
+ return null;
4514
+ return {
4515
+ inputHash: row.input_hash,
4516
+ entityType: row.entity_type,
4517
+ entityId: row.entity_id,
4518
+ sourceSessionId: row.source_session_id,
4519
+ humanEdited: row.human_edited === 1,
4520
+ promptHash: row.prompt_hash,
4521
+ createdAt: row.created_at,
4522
+ updatedAt: row.updated_at
4523
+ };
4524
+ }
4125
4525
  function storeCache(db, inputHash, entityType, entityId, sourceSessionId, humanEdited, promptHash = "") {
4126
4526
  storeCaches(db, [{ inputHash, entityType, entityId, sourceSessionId, humanEdited, promptHash }]);
4127
4527
  }
@@ -4184,6 +4584,95 @@ function loadSlotCycles(db, sessionId) {
4184
4584
  suggestedBreak: r.suggested_break_json ? JSON.parse(r.suggested_break_json) : null
4185
4585
  }));
4186
4586
  }
4587
+ function findUnknownSlotAllowedComponents(db, sessionId, allowedComponentNames2, componentId) {
4588
+ const rows = db.prepare(`SELECT a.component_id, c.name AS component_name, a.slot_name, a.allowed_component
4589
+ FROM raw_slot_allowed_components a
4590
+ JOIN raw_components c ON c.session_id = a.session_id AND c.component_id = a.component_id
4591
+ WHERE a.session_id = ? AND (? IS NULL OR a.component_id = ?)
4592
+ ORDER BY a.component_id, a.slot_name, a.position`).all(sessionId, componentId ?? null, componentId ?? null);
4593
+ return rows.filter((row) => !allowedComponentNames2.has(row.allowed_component)).map((row) => ({
4594
+ componentId: row.component_id,
4595
+ componentName: row.component_name,
4596
+ slotName: row.slot_name,
4597
+ allowedComponent: row.allowed_component
4598
+ }));
4599
+ }
4600
+ function filterUnknownSlotAllowedComponents(db, sessionId, allowedComponentNames2) {
4601
+ const unknown5 = findUnknownSlotAllowedComponents(db, sessionId, allowedComponentNames2);
4602
+ if (unknown5.length === 0)
4603
+ return unknown5;
4604
+ db.exec("BEGIN");
4605
+ try {
4606
+ const remove = db.prepare(`DELETE FROM raw_slot_allowed_components
4607
+ WHERE session_id = ? AND component_id = ? AND slot_name = ? AND allowed_component = ?`);
4608
+ for (const row of unknown5) {
4609
+ remove.run(sessionId, row.componentId, row.slotName, row.allowedComponent);
4610
+ }
4611
+ db.exec("COMMIT");
4612
+ } catch (e) {
4613
+ db.exec("ROLLBACK");
4614
+ throw e;
4615
+ }
4616
+ return unknown5;
4617
+ }
4618
+ function copyComponentFromCache(db, sourceSessionId, targetSessionId, componentId, manageTransaction = true, options = {}) {
4619
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4620
+ if (manageTransaction)
4621
+ db.exec("BEGIN");
4622
+ try {
4623
+ const srcComp = db.prepare(`SELECT description, status, component_description_rationale, props_rationale, slots_rationale
4624
+ FROM raw_components WHERE session_id = ? AND component_id = ?`).get(sourceSessionId, componentId);
4625
+ if (srcComp) {
4626
+ db.prepare(`UPDATE raw_components
4627
+ SET description = ?, status = ?, component_description_rationale = ?, props_rationale = ?, slots_rationale = ?, extracted_at = ?
4628
+ WHERE session_id = ? AND component_id = ?`).run(srcComp.description, srcComp.status, srcComp.component_description_rationale, srcComp.props_rationale, srcComp.slots_rationale, now, targetSessionId, componentId);
4629
+ }
4630
+ const srcProps = db.prepare(`SELECT name, cdf_type, cdf_category, cdf_token_kind, required, description, default_value, rationale
4631
+ FROM raw_props WHERE session_id = ? AND component_id = ?`).all(sourceSessionId, componentId);
4632
+ for (const p of srcProps) {
4633
+ db.prepare(`UPDATE raw_props SET cdf_type = ?, cdf_category = ?, cdf_token_kind = ?, required = ?, description = ?, default_value = ?, rationale = ?
4634
+ WHERE session_id = ? AND component_id = ? AND name = ?`).run(p.cdf_type, p.cdf_category, p.cdf_token_kind, p.required, p.description, p.default_value, p.rationale, targetSessionId, componentId, p.name);
4635
+ }
4636
+ db.prepare(`DELETE FROM raw_prop_allowed_values WHERE session_id = ? AND component_id = ?`).run(targetSessionId, componentId);
4637
+ const srcAV = db.prepare(`SELECT prop_name, position, value FROM raw_prop_allowed_values WHERE session_id = ? AND component_id = ?`).all(sourceSessionId, componentId);
4638
+ const insertAV = db.prepare(`INSERT INTO raw_prop_allowed_values (session_id, component_id, prop_name, position, value) VALUES (?, ?, ?, ?, ?)`);
4639
+ for (const av of srcAV) {
4640
+ insertAV.run(targetSessionId, componentId, av.prop_name, av.position, av.value);
4641
+ }
4642
+ const srcSlots = db.prepare(`SELECT name, required, description, rationale FROM raw_slots WHERE session_id = ? AND component_id = ?`).all(sourceSessionId, componentId);
4643
+ for (const s of srcSlots) {
4644
+ db.prepare(`UPDATE raw_slots SET required = ?, description = ?, rationale = ? WHERE session_id = ? AND component_id = ? AND name = ?`).run(s.required, s.description, s.rationale, targetSessionId, componentId, s.name);
4645
+ }
4646
+ db.prepare(`DELETE FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ?`).run(targetSessionId, componentId);
4647
+ const srcSAC = db.prepare(`SELECT slot_name, position, allowed_component FROM raw_slot_allowed_components WHERE session_id = ? AND component_id = ?`).all(sourceSessionId, componentId);
4648
+ const insertSAC = db.prepare(`INSERT INTO raw_slot_allowed_components (session_id, component_id, slot_name, allowed_component, position) VALUES (?, ?, ?, ?, ?)`);
4649
+ const allowedSAC = options.allowedComponentNames ? srcSAC.filter((sac) => options.allowedComponentNames.has(sac.allowed_component)) : srcSAC;
4650
+ for (const sac of allowedSAC) {
4651
+ insertSAC.run(targetSessionId, componentId, sac.slot_name, sac.allowed_component, sac.position);
4652
+ }
4653
+ db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, targetSessionId);
4654
+ if (manageTransaction)
4655
+ db.exec("COMMIT");
4656
+ } catch (e) {
4657
+ if (manageTransaction)
4658
+ db.exec("ROLLBACK");
4659
+ throw e;
4660
+ }
4661
+ }
4662
+ function copyComponentsFromCache(db, entries, options = {}) {
4663
+ if (entries.length === 0)
4664
+ return;
4665
+ db.exec("BEGIN");
4666
+ try {
4667
+ for (const entry of entries) {
4668
+ copyComponentFromCache(db, entry.sourceSessionId, entry.targetSessionId, entry.componentId, false, options);
4669
+ }
4670
+ db.exec("COMMIT");
4671
+ } catch (e) {
4672
+ db.exec("ROLLBACK");
4673
+ throw e;
4674
+ }
4675
+ }
4187
4676
  function copyTokensFromCache(db, sourceSessionId, targetSessionId) {
4188
4677
  const now = (/* @__PURE__ */ new Date()).toISOString();
4189
4678
  db.exec("BEGIN");
@@ -4201,17 +4690,57 @@ function copyTokensFromCache(db, sourceSessionId, targetSessionId) {
4201
4690
  throw e;
4202
4691
  }
4203
4692
  }
4693
+ function copyMapTokensFromCache(db, sourceSessionId, targetSessionId) {
4694
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4695
+ let copiedCount = 0;
4696
+ db.exec("BEGIN");
4697
+ try {
4698
+ const sourceRows = db.prepare(`SELECT rc.name AS component_name, rptp.prop_name, rptp.source, rptp.position, rptp.path
4699
+ FROM raw_prop_token_paths rptp
4700
+ JOIN raw_components rc ON rc.session_id = rptp.session_id AND rc.component_id = rptp.component_id
4701
+ WHERE rptp.session_id = ?
4702
+ ORDER BY rc.name, rptp.prop_name, rptp.position`).all(sourceSessionId);
4703
+ const targetComponents = db.prepare(`SELECT component_id, name FROM raw_components WHERE session_id = ?`).all(targetSessionId);
4704
+ const targetIdByName = new Map(targetComponents.map((c2) => [c2.name, c2.component_id]));
4705
+ const targetProps = new Set(db.prepare(`SELECT component_id, name FROM raw_props WHERE session_id = ?`).all(targetSessionId).map((p) => `${p.component_id}::${p.name}`));
4706
+ const insertPath = db.prepare(`INSERT INTO raw_prop_token_paths (session_id, component_id, prop_name, source, position, path)
4707
+ VALUES (?, ?, ?, ?, ?, ?)`);
4708
+ const clearedProps = /* @__PURE__ */ new Set();
4709
+ const copiedProps = /* @__PURE__ */ new Set();
4710
+ for (const row of sourceRows) {
4711
+ const targetComponentId = targetIdByName.get(row.component_name);
4712
+ if (!targetComponentId)
4713
+ continue;
4714
+ if (!targetProps.has(`${targetComponentId}::${row.prop_name}`))
4715
+ continue;
4716
+ const propKey = `${targetComponentId}::${row.prop_name}`;
4717
+ if (!clearedProps.has(propKey)) {
4718
+ clearedProps.add(propKey);
4719
+ db.prepare(`DELETE FROM raw_prop_token_paths WHERE session_id = ? AND component_id = ? AND prop_name = ?`).run(targetSessionId, targetComponentId, row.prop_name);
4720
+ }
4721
+ insertPath.run(targetSessionId, targetComponentId, row.prop_name, row.source, row.position, row.path);
4722
+ copiedProps.add(propKey);
4723
+ }
4724
+ copiedCount = copiedProps.size;
4725
+ db.prepare("UPDATE sessions SET updated_at = ? WHERE id = ?").run(now, targetSessionId);
4726
+ db.exec("COMMIT");
4727
+ } catch (e) {
4728
+ db.exec("ROLLBACK");
4729
+ throw e;
4730
+ }
4731
+ return copiedCount;
4732
+ }
4204
4733
  async function getCliCacheVersion() {
4205
4734
  if (_cliCacheVersionCache)
4206
4735
  return _cliCacheVersionCache;
4207
4736
  try {
4208
4737
  const { hashContent: hashContent3 } = await Promise.resolve().then(() => (init_cache_keys(), cache_keys_exports));
4209
- const { resolveSkillPath: resolveSkillPath3 } = await Promise.resolve().then(() => (init_agents(), agents_exports));
4738
+ const { resolveSkillPath: resolveSkillPath2 } = await Promise.resolve().then(() => (init_agents(), agents_exports));
4210
4739
  const skills = ["components", "tokens", "select"];
4211
4740
  const parts = [];
4212
4741
  for (const s of skills) {
4213
4742
  try {
4214
- const p = resolveSkillPath3(s);
4743
+ const p = resolveSkillPath2(s);
4215
4744
  parts.push(readFileSync3(p, "utf8"));
4216
4745
  } catch {
4217
4746
  parts.push(`<missing:${s}>`);
@@ -4292,7 +4821,7 @@ function lookupSelectCache(db, componentHash, promptHash, cliVersion) {
4292
4821
  updatedAt: row.updated_at
4293
4822
  };
4294
4823
  }
4295
- var SCHEMA, _cliCacheVersionCache;
4824
+ var SCHEMA, MAX_COMPONENT_SOURCE_CHARS, MAX_SIBLING_FILES, MAX_SIBLING_SNIPPET_CHARS, MAX_TYPE_DECLARING_SIBLING_CHARS, MAX_ENLARGED_SIBLINGS, MAX_SIBLING_DEPTH, MAX_SIBLING_CANDIDATES_EXPLORED, RELATIVE_IMPORT_PATTERN, SIBLING_FILE_EXTENSIONS, TS_ESM_EXTENSION_REWRITES, IDENTIFIER_PATTERN, _cliCacheVersionCache;
4296
4825
  var init_db = __esm({
4297
4826
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/session/repositories/db.js"() {
4298
4827
  "use strict";
@@ -4491,6 +5020,22 @@ CREATE INDEX IF NOT EXISTS idx_generation_cache_entity ON generation_cache(enti
4491
5020
  CREATE INDEX IF NOT EXISTS idx_generation_cache_session ON generation_cache(source_session_id);
4492
5021
  CREATE INDEX IF NOT EXISTS idx_scanned_files_session ON scanned_files(session_id);
4493
5022
  `;
5023
+ MAX_COMPONENT_SOURCE_CHARS = 8e3;
5024
+ MAX_SIBLING_FILES = 5;
5025
+ MAX_SIBLING_SNIPPET_CHARS = 1200;
5026
+ MAX_TYPE_DECLARING_SIBLING_CHARS = 4e3;
5027
+ MAX_ENLARGED_SIBLINGS = 2;
5028
+ MAX_SIBLING_DEPTH = 2;
5029
+ MAX_SIBLING_CANDIDATES_EXPLORED = 25;
5030
+ RELATIVE_IMPORT_PATTERN = /from\s+['"](\.[^'"]+)['"]/g;
5031
+ SIBLING_FILE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
5032
+ TS_ESM_EXTENSION_REWRITES = [
5033
+ [".js", [".ts", ".tsx", ".js", ".jsx"]],
5034
+ [".jsx", [".tsx", ".jsx"]],
5035
+ [".mjs", [".mts", ".mjs"]],
5036
+ [".cjs", [".cts", ".cjs"]]
5037
+ ];
5038
+ IDENTIFIER_PATTERN = /[A-Za-z_$][A-Za-z0-9_$]*/g;
4494
5039
  _cliCacheVersionCache = null;
4495
5040
  }
4496
5041
  });
@@ -4975,7 +5520,7 @@ var init_extract_tsx_components = __esm({
4975
5520
  });
4976
5521
 
4977
5522
  // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/framework-adapters/shared/file-extraction-workers.js
4978
- import { readFile as readFile4 } from "node:fs/promises";
5523
+ import { readFile as readFile5 } from "node:fs/promises";
4979
5524
  async function runFileExtractionWorkers(filePaths, concurrency, extractFile, formatError, onProgress, onResult) {
4980
5525
  const warnings = [];
4981
5526
  const items = [];
@@ -4987,7 +5532,7 @@ async function runFileExtractionWorkers(filePaths, concurrency, extractFile, for
4987
5532
  if (!filePath)
4988
5533
  break;
4989
5534
  try {
4990
- const source = await readFile4(filePath, "utf-8");
5535
+ const source = await readFile5(filePath, "utf-8");
4991
5536
  const outcome = await extractFile(filePath, source);
4992
5537
  warnings.push(...outcome.warnings ?? []);
4993
5538
  if (outcome.item)
@@ -8075,7 +8620,7 @@ var init_resolve_type_property = __esm({
8075
8620
  // packages/experience-design-system-backend-pipeline/dist/src/steps/extraction/src/framework-adapters/vue/extract-vue-components.js
8076
8621
  import os from "node:os";
8077
8622
  import { basename, dirname as dirname7, resolve as resolve9, join as join9 } from "node:path";
8078
- import { readFile as readFile5 } from "node:fs/promises";
8623
+ import { readFile as readFile6 } from "node:fs/promises";
8079
8624
  import { existsSync as existsSync7, readFileSync as readFileSync5, readdirSync, statSync as statSync3 } from "node:fs";
8080
8625
  import { parse as parseSFC } from "@vue/compiler-sfc";
8081
8626
  import { Project as Project3, Node as Node6 } from "ts-morph";
@@ -8262,7 +8807,7 @@ async function extractNamedObjectExportProps(importedRef, visitedImports) {
8262
8807
  if (visitedImports.has(visitKey))
8263
8808
  return [];
8264
8809
  visitedImports.add(visitKey);
8265
- const source = await readFile5(importedRef.filePath, "utf-8");
8810
+ const source = await readFile6(importedRef.filePath, "utf-8");
8266
8811
  const project = new Project3({
8267
8812
  compilerOptions: {
8268
8813
  strict: false,
@@ -8491,7 +9036,7 @@ async function extractOptionsProps(filePath, scriptContent, visited = /* @__PURE
8491
9036
  return [];
8492
9037
  }
8493
9038
  async function extractInheritedVueProps(filePath, visited) {
8494
- const source = await readFile5(filePath, "utf-8");
9039
+ const source = await readFile6(filePath, "utf-8");
8495
9040
  const { descriptor } = parseSFC(source);
8496
9041
  if (!descriptor.script) {
8497
9042
  return [];
@@ -11789,9 +12334,9 @@ var init_candidate_files2 = __esm({
11789
12334
  });
11790
12335
 
11791
12336
  // packages/experience-design-system-backend-pipeline/dist/src/steps/composition/src/helpers/candidates/composition-cache-key.js
11792
- import { createHash as createHash5 } from "node:crypto";
12337
+ import { createHash as createHash6 } from "node:crypto";
11793
12338
  function hashContent2(content) {
11794
- return createHash5("sha256").update(content).digest("hex");
12339
+ return createHash6("sha256").update(content).digest("hex");
11795
12340
  }
11796
12341
  function buildCompositionInputHash(input) {
11797
12342
  const fileDigest = input.files.map((f) => `${f.path} ${hashContent2(f.content)}`).sort().join("");
@@ -12502,9 +13047,9 @@ var init_validate3 = __esm({
12502
13047
  });
12503
13048
 
12504
13049
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/helpers/create-component-id.js
12505
- import { createHash as createHash6 } from "node:crypto";
13050
+ import { createHash as createHash7 } from "node:crypto";
12506
13051
  function createComponentId(name, resolvedSourcePath) {
12507
- const sourceHash = createHash6("sha256").update(`${name}:${resolvedSourcePath}`).digest("hex").slice(0, 12);
13052
+ const sourceHash = createHash7("sha256").update(`${name}:${resolvedSourcePath}`).digest("hex").slice(0, 12);
12508
13053
  return `${name}-${sourceHash}`;
12509
13054
  }
12510
13055
  var init_create_component_id = __esm({
@@ -12613,13 +13158,13 @@ var init_review_session_paths = __esm({
12613
13158
  });
12614
13159
 
12615
13160
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/ensure-review-session.js
12616
- import { access as access2, mkdir, readFile as readFile6, writeFile } from "node:fs/promises";
13161
+ import { access as access2, mkdir, readFile as readFile7, writeFile } from "node:fs/promises";
12617
13162
  async function ensureRefineSession(sessionId, artifactsRoot, initialSnapshot) {
12618
13163
  const paths = await getRefineSessionPaths(sessionId, artifactsRoot);
12619
13164
  await mkdir(paths.sessionDir, { recursive: true });
12620
13165
  try {
12621
13166
  await access2(paths.statePath);
12622
- const savedState = await readFile6(paths.statePath, "utf8");
13167
+ const savedState = await readFile7(paths.statePath, "utf8");
12623
13168
  return JSON.parse(savedState);
12624
13169
  } catch {
12625
13170
  await writeFile(paths.statePath, JSON.stringify(initialSnapshot, null, 2), "utf8");
@@ -12661,14 +13206,14 @@ var init_save_review_state = __esm({
12661
13206
  });
12662
13207
 
12663
13208
  // packages/experience-design-system-backend-pipeline/dist/src/steps/selection/src/controller/review/merge-preview-validation-errors-into-review-session.js
12664
- import { access as access3, readFile as readFile7 } from "node:fs/promises";
13209
+ import { access as access3, readFile as readFile8 } from "node:fs/promises";
12665
13210
  async function mergePreviewValidationErrorsIntoReviewSession(sessionId, errors, opts = {}) {
12666
13211
  const artifactsRoot = opts.artifactsRoot ?? getRefineArtifactsRoot();
12667
13212
  const paths = await getRefineSessionPaths(sessionId, artifactsRoot);
12668
13213
  let snapshot;
12669
13214
  try {
12670
13215
  await access3(paths.statePath);
12671
- snapshot = JSON.parse(await readFile7(paths.statePath, "utf8"));
13216
+ snapshot = JSON.parse(await readFile8(paths.statePath, "utf8"));
12672
13217
  } catch {
12673
13218
  snapshot = await loadAndValidateForReview(sessionId, void 0);
12674
13219
  snapshot = await ensureRefineSession(sessionId, artifactsRoot, snapshot);
@@ -12716,7 +13261,7 @@ var init_merge_preview_validation_errors_into_review_session = __esm({
12716
13261
  });
12717
13262
 
12718
13263
  // packages/experience-design-system-backend-pipeline/dist/src/steps/selection/src/controller/review/reject-components-by-name.js
12719
- import { readFile as readFile8 } from "node:fs/promises";
13264
+ import { readFile as readFile9 } from "node:fs/promises";
12720
13265
  async function rejectComponentsByName(sessionId, names, opts = {}) {
12721
13266
  if (names.length === 0)
12722
13267
  return;
@@ -12732,7 +13277,7 @@ async function rejectComponentsByName(sessionId, names, opts = {}) {
12732
13277
  const nameSet = new Set(names);
12733
13278
  let snapshot;
12734
13279
  try {
12735
- snapshot = JSON.parse(await readFile8(paths.statePath, "utf8"));
13280
+ snapshot = JSON.parse(await readFile9(paths.statePath, "utf8"));
12736
13281
  } catch {
12737
13282
  return;
12738
13283
  }
@@ -13093,10 +13638,10 @@ var init_run_record = __esm({
13093
13638
  });
13094
13639
 
13095
13640
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/runs/repositories/read-runs-file.js
13096
- import { readFile as readFile9 } from "node:fs/promises";
13641
+ import { readFile as readFile10 } from "node:fs/promises";
13097
13642
  async function readRunsFileMaybe() {
13098
13643
  try {
13099
- const raw = await readFile9(runsFilePath(), "utf8");
13644
+ const raw = await readFile10(runsFilePath(), "utf8");
13100
13645
  const parsed = JSON.parse(raw);
13101
13646
  if (!READABLE_VERSIONS.has(parsed.version)) {
13102
13647
  throw new Error(`runs.json version mismatch: file is v${parsed.version}, this CLI expects v${RUNS_FILE_VERSION} (also reads: ${[...READABLE_VERSIONS].join(", ")}). Back up and remove the file to start fresh.`);
@@ -13205,9 +13750,9 @@ var init_update_run = __esm({
13205
13750
  });
13206
13751
 
13207
13752
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/runs/helpers/sha256-hex.js
13208
- import { createHash as createHash7 } from "node:crypto";
13753
+ import { createHash as createHash8 } from "node:crypto";
13209
13754
  function sha256Hex(buf) {
13210
- return createHash7("sha256").update(buf).digest("hex");
13755
+ return createHash8("sha256").update(buf).digest("hex");
13211
13756
  }
13212
13757
  var init_sha256_hex = __esm({
13213
13758
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/runs/helpers/sha256-hex.js"() {
@@ -13216,7 +13761,7 @@ var init_sha256_hex = __esm({
13216
13761
  });
13217
13762
 
13218
13763
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/runs/services/build-source-fingerprint.js
13219
- import { readFile as readFile10, stat } from "node:fs/promises";
13764
+ import { readFile as readFile11, stat } from "node:fs/promises";
13220
13765
  import { resolve as resolve17 } from "node:path";
13221
13766
  function rowField(row, key) {
13222
13767
  const v = row[key];
@@ -13251,7 +13796,7 @@ async function buildSourceFingerprint(opts) {
13251
13796
  const abs = resolve17(opts.rawTokensPath);
13252
13797
  rawTokensPath = abs;
13253
13798
  try {
13254
- const [st, buf] = await Promise.all([stat(abs), readFile10(abs)]);
13799
+ const [st, buf] = await Promise.all([stat(abs), readFile11(abs)]);
13255
13800
  rawTokensMtime = st.mtime.toISOString();
13256
13801
  rawTokensContentHash = sha256Hex(buf);
13257
13802
  } catch {
@@ -13416,6 +13961,21 @@ var init_write_scope_decisions_snapshot = __esm({
13416
13961
  });
13417
13962
 
13418
13963
  // packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/load-accepted-names.js
13964
+ import { readFile as readFile12 } from "node:fs/promises";
13965
+ async function loadAcceptedNames(sessionId) {
13966
+ try {
13967
+ const artifactsRoot = getRefineArtifactsRoot();
13968
+ const paths = await getRefineSessionPaths(sessionId, artifactsRoot);
13969
+ const raw = await readFile12(paths.statePath, "utf8");
13970
+ const snapshot = JSON.parse(raw);
13971
+ const accepted = snapshot.components.filter((c2) => c2.status === "accepted").map((c2) => c2.name);
13972
+ if (accepted.length === 0)
13973
+ return null;
13974
+ return new Set(accepted);
13975
+ } catch {
13976
+ return null;
13977
+ }
13978
+ }
13419
13979
  var init_load_accepted_names = __esm({
13420
13980
  "packages/experience-design-system-backend-pipeline/dist/src/persistence/src/review-session/repositories/load-accepted-names.js"() {
13421
13981
  "use strict";
@@ -14341,7 +14901,7 @@ function errorMessage(error) {
14341
14901
  return error instanceof Error && error.message ? error.message : String(error);
14342
14902
  }
14343
14903
  function defaultSleep(delayMs) {
14344
- return new Promise((resolve22) => setTimeout(resolve22, delayMs));
14904
+ return new Promise((resolve25) => setTimeout(resolve25, delayMs));
14345
14905
  }
14346
14906
  var MAX_RETRY_AFTER_MS;
14347
14907
  var init_http_utils = __esm({
@@ -14617,7 +15177,7 @@ var init_api_client = __esm({
14617
15177
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
14618
15178
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
14619
15179
  const jitter = Math.random() * baseDelay * 0.15;
14620
- await new Promise((resolve22) => setTimeout(resolve22, baseDelay + jitter));
15180
+ await new Promise((resolve25) => setTimeout(resolve25, baseDelay + jitter));
14621
15181
  }
14622
15182
  }
14623
15183
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -15304,7 +15864,7 @@ var init_collect_json_files = __esm({
15304
15864
  });
15305
15865
 
15306
15866
  // packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/tokens/read-tokens-from-path.js
15307
- import { readFile as readFile11, stat as stat3 } from "node:fs/promises";
15867
+ import { readFile as readFile13, stat as stat3 } from "node:fs/promises";
15308
15868
  async function readTokensFromPath(flag, p) {
15309
15869
  let s;
15310
15870
  try {
@@ -15327,7 +15887,7 @@ async function readMergedFromDir(flag, dir) {
15327
15887
  const merged = {};
15328
15888
  for (const file of files.sort()) {
15329
15889
  try {
15330
- const text = await readFile11(file, "utf8");
15890
+ const text = await readFile13(file, "utf8");
15331
15891
  const parsed = JSON.parse(text);
15332
15892
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
15333
15893
  Object.assign(merged, parsed);
@@ -15341,7 +15901,7 @@ async function readMergedFromDir(flag, dir) {
15341
15901
  async function readSingleFile(flag, p) {
15342
15902
  let text;
15343
15903
  try {
15344
- text = await readFile11(p, "utf8");
15904
+ text = await readFile13(p, "utf8");
15345
15905
  } catch {
15346
15906
  throw new Error(`file not found: ${p} (from ${flag})`);
15347
15907
  }
@@ -15447,6 +16007,20 @@ var init_fetch_and_persist = __esm({
15447
16007
  });
15448
16008
 
15449
16009
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/read-from-session.js
16010
+ import { readFile as readFile14 } from "node:fs/promises";
16011
+ async function readExistingContentfulEntitiesFromSession(request) {
16012
+ if (!request.path)
16013
+ return void 0;
16014
+ try {
16015
+ const raw = await readFile14(request.path, "utf8");
16016
+ const parsed = JSON.parse(raw);
16017
+ if (!Array.isArray(parsed.components) || !Array.isArray(parsed.tokens))
16018
+ return void 0;
16019
+ return parsed;
16020
+ } catch {
16021
+ return void 0;
16022
+ }
16023
+ }
15450
16024
  var init_read_from_session = __esm({
15451
16025
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/read-from-session.js"() {
15452
16026
  "use strict";
@@ -15454,6 +16028,12 @@ var init_read_from_session = __esm({
15454
16028
  });
15455
16029
 
15456
16030
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/summarizers/summarize-tokens.js
16031
+ function summarizeTokens(tokens) {
16032
+ const kinds = /* @__PURE__ */ new Set();
16033
+ for (const t of tokens)
16034
+ kinds.add(t.type);
16035
+ return { count: tokens.length, kinds: [...kinds].sort() };
16036
+ }
15457
16037
  var init_summarize_tokens = __esm({
15458
16038
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/summarizers/summarize-tokens.js"() {
15459
16039
  "use strict";
@@ -15469,6 +16049,29 @@ var init_summarize_for_select = __esm({
15469
16049
  });
15470
16050
 
15471
16051
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/count-character-edits.js
16052
+ function countCharacterEdits(a, b) {
16053
+ if (a === b)
16054
+ return 0;
16055
+ if (a.length === 0)
16056
+ return b.length;
16057
+ if (b.length === 0)
16058
+ return a.length;
16059
+ if (a.length > b.length)
16060
+ [a, b] = [b, a];
16061
+ let prev = new Array(a.length + 1);
16062
+ let curr = new Array(a.length + 1);
16063
+ for (let i = 0; i <= a.length; i++)
16064
+ prev[i] = i;
16065
+ for (let j = 1; j <= b.length; j++) {
16066
+ curr[0] = j;
16067
+ for (let i = 1; i <= a.length; i++) {
16068
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
16069
+ curr[i] = Math.min(curr[i - 1] + 1, prev[i] + 1, prev[i - 1] + cost);
16070
+ }
16071
+ [prev, curr] = [curr, prev];
16072
+ }
16073
+ return prev[a.length];
16074
+ }
15472
16075
  var init_count_character_edits = __esm({
15473
16076
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/count-character-edits.js"() {
15474
16077
  "use strict";
@@ -15476,6 +16079,10 @@ var init_count_character_edits = __esm({
15476
16079
  });
15477
16080
 
15478
16081
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/simplify-name-for-comparison.js
16082
+ function simplifyNameForComparison(name) {
16083
+ const stripped = name.toLowerCase().replace(/[^a-z0-9]/g, "");
16084
+ return stripped.endsWith("s") && stripped.length > 1 ? stripped.slice(0, -1) : stripped;
16085
+ }
15479
16086
  var init_simplify_name_for_comparison = __esm({
15480
16087
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/simplify-name-for-comparison.js"() {
15481
16088
  "use strict";
@@ -15483,24 +16090,70 @@ var init_simplify_name_for_comparison = __esm({
15483
16090
  });
15484
16091
 
15485
16092
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/find-nearly-matching-component.js
16093
+ function findNearlyMatchingComponent(components, codebaseName) {
16094
+ const target = simplifyNameForComparison(codebaseName);
16095
+ if (!target)
16096
+ return void 0;
16097
+ let best;
16098
+ for (const c2 of components) {
16099
+ const edits = countCharacterEdits(target, simplifyNameForComparison(c2.name));
16100
+ if (edits > MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH)
16101
+ continue;
16102
+ if (!best || edits < best.edits)
16103
+ best = { component: c2, edits };
16104
+ if (edits === 0)
16105
+ break;
16106
+ }
16107
+ return best?.component;
16108
+ }
16109
+ var MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH;
15486
16110
  var init_find_nearly_matching_component = __esm({
15487
16111
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/existing-entities/find-nearly-matching-component.js"() {
15488
16112
  "use strict";
15489
16113
  init_count_character_edits();
15490
16114
  init_simplify_name_for_comparison();
16115
+ MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH = 2;
15491
16116
  }
15492
16117
  });
15493
16118
 
15494
16119
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/summarize-for-generate.js
15495
- var init_summarize_for_generate = __esm({
15496
- "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/summarize-for-generate.js"() {
15497
- "use strict";
16120
+ function summarizeForGenerateAgent(entities, codebaseComponentName) {
16121
+ const match2 = findNearlyMatchingComponent(entities.components, codebaseComponentName);
16122
+ const otherComponents = entities.components.filter((c2) => c2.sys.id !== match2?.sys.id).map((c2) => ({ id: c2.sys.id, name: c2.name }));
16123
+ return {
16124
+ likelyMatch: match2 ? {
16125
+ id: match2.sys.id,
16126
+ name: match2.name,
16127
+ designProperties: match2.designProperties.map((p) => ({
16128
+ id: p.id,
16129
+ name: p.name,
16130
+ type: p.type
16131
+ })),
16132
+ contentProperties: match2.contentProperties.map((p) => ({
16133
+ id: p.id,
16134
+ name: p.name,
16135
+ type: p.type
16136
+ })),
16137
+ slots: (match2.slots ?? []).map((s) => ({ id: s.id, name: s.name }))
16138
+ } : void 0,
16139
+ otherComponents,
16140
+ tokens: summarizeTokens(entities.tokens)
16141
+ };
16142
+ }
16143
+ var init_summarize_for_generate = __esm({
16144
+ "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/summarize-for-generate.js"() {
16145
+ "use strict";
15498
16146
  init_find_nearly_matching_component();
15499
16147
  init_summarize_tokens();
15500
16148
  }
15501
16149
  });
15502
16150
 
15503
16151
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/summarize-for-map-tokens.js
16152
+ function summarizeForMapTokens(request) {
16153
+ return {
16154
+ tokens: request.entities.tokens.map((t) => ({ id: t.sys.id, name: t.name, type: t.type }))
16155
+ };
16156
+ }
15504
16157
  var init_summarize_for_map_tokens = __esm({
15505
16158
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/existing-entities/summarize-for-map-tokens.js"() {
15506
16159
  "use strict";
@@ -15508,6 +16161,9 @@ var init_summarize_for_map_tokens = __esm({
15508
16161
  });
15509
16162
 
15510
16163
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/normalize-token-key.js
16164
+ function normalizeTokenKey(key) {
16165
+ return key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").replace(/[ _]+/g, "-").toLowerCase();
16166
+ }
15511
16167
  var init_normalize_token_key = __esm({
15512
16168
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/normalize-token-key.js"() {
15513
16169
  "use strict";
@@ -15515,6 +16171,11 @@ var init_normalize_token_key = __esm({
15515
16171
  });
15516
16172
 
15517
16173
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/terminal-member.js
16174
+ function terminalMember(reference) {
16175
+ if (!/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)+$/.test(reference))
16176
+ return void 0;
16177
+ return reference.slice(reference.lastIndexOf(".") + 1);
16178
+ }
15518
16179
  var init_terminal_member = __esm({
15519
16180
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/terminal-member.js"() {
15520
16181
  "use strict";
@@ -15522,6 +16183,114 @@ var init_terminal_member = __esm({
15522
16183
  });
15523
16184
 
15524
16185
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/resolve-token-defaults.js
16186
+ function describeType(tokenKind) {
16187
+ return tokenKind === null ? "the property type" : `a ${tokenKind} token`;
16188
+ }
16189
+ function resolveTokenDefaults(defaults, leaves) {
16190
+ const leavesByPath = new Map(leaves.map((leaf) => [leaf.path, leaf]));
16191
+ const leavesByNormalizedKey = buildNormalizedIndex(leaves);
16192
+ const outcomesByRawDefault = /* @__PURE__ */ new Map();
16193
+ const diagnostics = [];
16194
+ const outcomesFor = (rawDefault) => {
16195
+ const outcomes = outcomesByRawDefault.get(rawDefault) ?? { resolvedPaths: [], diagnostics: [] };
16196
+ outcomesByRawDefault.set(rawDefault, outcomes);
16197
+ return outcomes;
16198
+ };
16199
+ const recordResolvedPath = (rawDefault, path5) => {
16200
+ outcomesFor(rawDefault).resolvedPaths.push(path5);
16201
+ };
16202
+ const recordDiagnostic = (d) => {
16203
+ outcomesFor(d.rawDefault).diagnostics.push(d);
16204
+ diagnostics.push(d);
16205
+ };
16206
+ for (const input of defaults) {
16207
+ classifyOneDefault(input, leavesByPath, leavesByNormalizedKey, recordResolvedPath, recordDiagnostic, describeType);
16208
+ }
16209
+ const mappings = finalizeMappings(outcomesByRawDefault, recordDiagnostic);
16210
+ return { mappings, diagnostics };
16211
+ }
16212
+ function buildNormalizedIndex(leaves) {
16213
+ const out = /* @__PURE__ */ new Map();
16214
+ for (const leaf of leaves) {
16215
+ const key = leaf.path.slice(leaf.path.lastIndexOf(".") + 1);
16216
+ const normalizedKey = normalizeTokenKey(key);
16217
+ const matches = out.get(normalizedKey) ?? [];
16218
+ matches.push(leaf);
16219
+ out.set(normalizedKey, matches);
16220
+ }
16221
+ return out;
16222
+ }
16223
+ function classifyOneDefault(input, leavesByPath, leavesByNormalizedKey, recordResolvedPath, recordDiagnostic, describeType2) {
16224
+ const exact = leavesByPath.get(input.rawDefault);
16225
+ if (exact !== void 0) {
16226
+ if (input.tokenKind === null || exact.type === input.tokenKind) {
16227
+ recordResolvedPath(input.rawDefault, exact.path);
16228
+ } else {
16229
+ recordDiagnostic({
16230
+ rawDefault: input.rawDefault,
16231
+ tokenKind: input.tokenKind,
16232
+ reason: "type_mismatch",
16233
+ candidatePaths: [exact.path],
16234
+ message: `Token default '${input.rawDefault}' is a ${exact.type} token, not ${describeType2(input.tokenKind)}.`
16235
+ });
16236
+ }
16237
+ return;
16238
+ }
16239
+ const member = terminalMember(input.rawDefault);
16240
+ const candidates = member === void 0 ? [] : leavesByNormalizedKey.get(normalizeTokenKey(member)) ?? [];
16241
+ const compatible = input.tokenKind === null ? candidates : candidates.filter((c2) => c2.type === input.tokenKind);
16242
+ if (compatible.length === 1) {
16243
+ recordResolvedPath(input.rawDefault, compatible[0].path);
16244
+ return;
16245
+ }
16246
+ if (compatible.length > 1) {
16247
+ recordDiagnostic({
16248
+ rawDefault: input.rawDefault,
16249
+ tokenKind: input.tokenKind,
16250
+ reason: "ambiguous",
16251
+ candidatePaths: compatible.map((c2) => c2.path).sort(),
16252
+ message: `Token default '${input.rawDefault}' matches multiple compatible DTCG leaves: ${compatible.map((c2) => c2.path).sort().join(", ")}.`
16253
+ });
16254
+ return;
16255
+ }
16256
+ if (candidates.length > 0 && input.tokenKind !== null) {
16257
+ recordDiagnostic({
16258
+ rawDefault: input.rawDefault,
16259
+ tokenKind: input.tokenKind,
16260
+ reason: "type_mismatch",
16261
+ candidatePaths: candidates.map((c2) => c2.path).sort(),
16262
+ message: `Token default '${input.rawDefault}' has matching DTCG leaf names, but none is ${describeType2(input.tokenKind)}.`
16263
+ });
16264
+ return;
16265
+ }
16266
+ recordDiagnostic({
16267
+ rawDefault: input.rawDefault,
16268
+ tokenKind: input.tokenKind,
16269
+ reason: "no_match",
16270
+ candidatePaths: [],
16271
+ message: `Token default '${input.rawDefault}' does not match a DTCG token leaf.`
16272
+ });
16273
+ }
16274
+ function finalizeMappings(outcomesByRawDefault, recordDiagnostic) {
16275
+ const mappings = {};
16276
+ for (const [rawDefault, outcomes] of outcomesByRawDefault) {
16277
+ if (outcomes.diagnostics.length > 0)
16278
+ continue;
16279
+ const uniquePaths = [...new Set(outcomes.resolvedPaths)];
16280
+ if (uniquePaths.length === 1) {
16281
+ mappings[rawDefault] = uniquePaths[0];
16282
+ continue;
16283
+ }
16284
+ recordDiagnostic({
16285
+ rawDefault,
16286
+ tokenKind: null,
16287
+ reason: "ambiguous",
16288
+ candidatePaths: uniquePaths.sort(),
16289
+ message: `Token default '${rawDefault}' resolves to different compatible DTCG leaves across properties: ${uniquePaths.sort().join(", ")}.`
16290
+ });
16291
+ }
16292
+ return mappings;
16293
+ }
15525
16294
  var init_resolve_token_defaults = __esm({
15526
16295
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/token-defaults/resolve-token-defaults.js"() {
15527
16296
  "use strict";
@@ -15539,6 +16308,13 @@ var init_resolve_token_defaults2 = __esm({
15539
16308
  });
15540
16309
 
15541
16310
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/normalize-component-for-cache.js
16311
+ function normalizeComponentForCache(component) {
16312
+ const slots = component.slots.map((slot, index, allSlots) => ({
16313
+ ...slot,
16314
+ name: slot.name.trim() || (allSlots.length === 1 ? "children" : `slot_${index}`)
16315
+ }));
16316
+ return { ...component, slots };
16317
+ }
15542
16318
  var init_normalize_component_for_cache = __esm({
15543
16319
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/normalize-component-for-cache.js"() {
15544
16320
  "use strict";
@@ -15546,6 +16322,15 @@ var init_normalize_component_for_cache = __esm({
15546
16322
  });
15547
16323
 
15548
16324
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/lookup-component-cache.js
16325
+ function lookupComponentCache(db, component, promptHash) {
16326
+ const normalized = normalizeComponentForCache(component);
16327
+ const inputHash = hashComponentShape(normalized);
16328
+ const cached = lookupCache(db, inputHash, "component", component.component_id, promptHash);
16329
+ if (cached)
16330
+ return cached;
16331
+ const legacyInputHash = hashComponentShape(component);
16332
+ return legacyInputHash === inputHash ? null : lookupCache(db, legacyInputHash, "component", component.component_id, promptHash);
16333
+ }
15549
16334
  var init_lookup_component_cache = __esm({
15550
16335
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/lookup-component-cache.js"() {
15551
16336
  "use strict";
@@ -15555,6 +16340,17 @@ var init_lookup_component_cache = __esm({
15555
16340
  });
15556
16341
 
15557
16342
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/resolve-component-cache.js
16343
+ function resolveComponentCache(db, component, promptHash, allowedComponentNames2) {
16344
+ const cached = lookupComponentCache(db, component, promptHash);
16345
+ if (cached && findUnknownSlotAllowedComponents(db, cached.sourceSessionId, allowedComponentNames2, component.component_id).length === 0) {
16346
+ return { entry: cached, humanEdited: cached.humanEdited };
16347
+ }
16348
+ const pinned = lookupCacheByEntity(db, "component", component.component_id);
16349
+ if (pinned?.humanEdited && findUnknownSlotAllowedComponents(db, pinned.sourceSessionId, allowedComponentNames2, component.component_id).length === 0) {
16350
+ return { entry: pinned, humanEdited: true };
16351
+ }
16352
+ return null;
16353
+ }
15558
16354
  var init_resolve_component_cache = __esm({
15559
16355
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/components/resolve-component-cache.js"() {
15560
16356
  "use strict";
@@ -15574,6 +16370,21 @@ var init_resolve_shared_inputs = __esm({
15574
16370
  });
15575
16371
 
15576
16372
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/filter-allowed-paths.js
16373
+ function filterAllowedPaths(args) {
16374
+ const { component, prop, tokenAllowed, tokenTypeByPath, propTokenKind, warnings } = args;
16375
+ const kept = [];
16376
+ for (const path5 of tokenAllowed) {
16377
+ const tokenType = tokenTypeByPath.get(path5);
16378
+ if (tokenType === void 0) {
16379
+ warnings.push(`map_token_prop '${component}.${prop}': dropped unknown token path '${path5}'`);
16380
+ } else if (propTokenKind !== null && tokenType !== propTokenKind) {
16381
+ warnings.push(`map_token_prop '${component}.${prop}': dropped '${path5}' \u2014 it is a ${tokenType} token, but the property's $token.kind is ${propTokenKind}`);
16382
+ } else {
16383
+ kept.push(path5);
16384
+ }
16385
+ }
16386
+ return kept;
16387
+ }
15577
16388
  var init_filter_allowed_paths = __esm({
15578
16389
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/filter-allowed-paths.js"() {
15579
16390
  "use strict";
@@ -15581,6 +16392,12 @@ var init_filter_allowed_paths = __esm({
15581
16392
  });
15582
16393
 
15583
16394
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/is-prop-reviewed.js
16395
+ function isPropReviewed(db, sessionId, componentId, propName) {
16396
+ const row = db.prepare(`SELECT COUNT(*) AS count FROM raw_prop_token_paths
16397
+ WHERE session_id = ? AND component_id = ? AND prop_name = ?
16398
+ AND source = 'review'`).get(sessionId, componentId, propName);
16399
+ return row.count > 0;
16400
+ }
15584
16401
  var init_is_prop_reviewed = __esm({
15585
16402
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/is-prop-reviewed.js"() {
15586
16403
  "use strict";
@@ -15588,6 +16405,10 @@ var init_is_prop_reviewed = __esm({
15588
16405
  });
15589
16406
 
15590
16407
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-token-type-by-path.js
16408
+ function loadTokenTypeByPath(db, sessionId) {
16409
+ const rows = db.prepare("SELECT path, type FROM raw_tokens WHERE session_id = ?").all(sessionId);
16410
+ return new Map(rows.map((r) => [r.path, r.type]));
16411
+ }
15591
16412
  var init_load_token_type_by_path = __esm({
15592
16413
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-token-type-by-path.js"() {
15593
16414
  "use strict";
@@ -15595,6 +16416,48 @@ var init_load_token_type_by_path = __esm({
15595
16416
  });
15596
16417
 
15597
16418
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/map-tokens/apply-map-token-prop-calls.js
16419
+ function applyMapTokenPropCalls(db, sessionId, calls, incomingWarnings) {
16420
+ const warnings = [...incomingWarnings];
16421
+ let applied = 0;
16422
+ const tokenTypeByPath = loadTokenTypeByPath(db, sessionId);
16423
+ const findComponent = db.prepare("SELECT component_id FROM raw_components WHERE session_id = ? AND name = ?");
16424
+ const findProp = db.prepare("SELECT cdf_type, cdf_category, cdf_token_kind FROM raw_props WHERE session_id = ? AND component_id = ? AND name = ?");
16425
+ for (const call of calls) {
16426
+ const component = findComponent.get(sessionId, call.component);
16427
+ if (!component) {
16428
+ warnings.push(`map_token_prop: unknown component '${call.component}' \u2014 skipped`);
16429
+ continue;
16430
+ }
16431
+ const prop = findProp.get(sessionId, component.component_id, call.prop);
16432
+ if (!prop) {
16433
+ warnings.push(`map_token_prop '${call.component}.${call.prop}': unknown prop \u2014 skipped`);
16434
+ continue;
16435
+ }
16436
+ if (prop.cdf_type !== "token" || prop.cdf_category !== "design") {
16437
+ warnings.push(`map_token_prop '${call.component}.${call.prop}': target is not a design-category token prop \u2014 skipped`);
16438
+ continue;
16439
+ }
16440
+ if (isPropReviewed(db, sessionId, component.component_id, call.prop)) {
16441
+ warnings.push(`map_token_prop '${call.component}.${call.prop}': a reviewer already set this restriction \u2014 skipped`);
16442
+ continue;
16443
+ }
16444
+ const filteredAllowed = filterAllowedPaths({
16445
+ component: call.component,
16446
+ prop: call.prop,
16447
+ tokenAllowed: call.token_allowed,
16448
+ tokenTypeByPath,
16449
+ propTokenKind: prop.cdf_token_kind,
16450
+ warnings
16451
+ });
16452
+ if (filteredAllowed.length === 0) {
16453
+ warnings.push(`map_token_prop '${call.component}.${call.prop}': no valid token_allowed remain \u2014 skipped`);
16454
+ continue;
16455
+ }
16456
+ replaceRawPropTokenPaths(db, sessionId, component.component_id, call.prop, filteredAllowed, "agent");
16457
+ applied++;
16458
+ }
16459
+ return { applied, warnings };
16460
+ }
15598
16461
  var init_apply_map_token_prop_calls = __esm({
15599
16462
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/map-tokens/apply-map-token-prop-calls.js"() {
15600
16463
  "use strict";
@@ -15608,6 +16471,14 @@ var init_apply_map_token_prop_calls = __esm({
15608
16471
  // packages/experience-design-system-backend-pipeline/dist/src/agents/helpers/resolution/binary-exists.js
15609
16472
  import { execFile } from "node:child_process";
15610
16473
  import { promisify } from "node:util";
16474
+ async function binaryExists(name) {
16475
+ try {
16476
+ await execFileAsync(process.platform === "win32" ? "where" : "which", [name]);
16477
+ return true;
16478
+ } catch {
16479
+ return false;
16480
+ }
16481
+ }
15611
16482
  var execFileAsync;
15612
16483
  var init_binary_exists = __esm({
15613
16484
  "packages/experience-design-system-backend-pipeline/dist/src/agents/helpers/resolution/binary-exists.js"() {
@@ -15617,6 +16488,12 @@ var init_binary_exists = __esm({
15617
16488
  });
15618
16489
 
15619
16490
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/count-mappable-props.js
16491
+ function countMappableProps(cdfEntries) {
16492
+ return cdfEntries.reduce((count, { entry }) => {
16493
+ const props = entry.$properties ?? {};
16494
+ return count + Object.values(props).filter((prop) => prop.$type === "token" && prop.$category === "design").length;
16495
+ }, 0);
16496
+ }
15620
16497
  var init_count_mappable_props = __esm({
15621
16498
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/count-mappable-props.js"() {
15622
16499
  "use strict";
@@ -15624,6 +16501,14 @@ var init_count_mappable_props = __esm({
15624
16501
  });
15625
16502
 
15626
16503
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-raw-defaults.js
16504
+ function loadRawDefaults(db, sessionId) {
16505
+ return db.prepare(`SELECT rp.default_value AS default_reference, rp.cdf_token_kind
16506
+ FROM raw_props rp
16507
+ JOIN raw_components rc ON rc.session_id = rp.session_id AND rc.component_id = rp.component_id
16508
+ WHERE rp.session_id = ? AND rc.status = 'generated'
16509
+ AND rp.cdf_type = 'token' AND rp.cdf_category = 'design'
16510
+ AND rp.default_value IS NOT NULL`).all(sessionId);
16511
+ }
15627
16512
  var init_load_raw_defaults = __esm({
15628
16513
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-raw-defaults.js"() {
15629
16514
  "use strict";
@@ -15631,6 +16516,9 @@ var init_load_raw_defaults = __esm({
15631
16516
  });
15632
16517
 
15633
16518
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-token-leaves.js
16519
+ function loadTokenLeaves(db, sessionId) {
16520
+ return db.prepare("SELECT path, type FROM raw_tokens WHERE session_id = ? ORDER BY path").all(sessionId);
16521
+ }
15634
16522
  var init_load_token_leaves = __esm({
15635
16523
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/helpers/map-tokens/load-token-leaves.js"() {
15636
16524
  "use strict";
@@ -15638,7 +16526,114 @@ var init_load_token_leaves = __esm({
15638
16526
  });
15639
16527
 
15640
16528
  // packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/map-tokens/run-map-tokens.js
15641
- var DEFAULT_TIMEOUT_MS2;
16529
+ import { resolve as resolve18 } from "node:path";
16530
+ async function runMapTokens(request) {
16531
+ const timeoutMs = request.agentTimeoutMs ?? DEFAULT_TIMEOUT_MS2;
16532
+ const db = openPipelineDb();
16533
+ try {
16534
+ const sessionId = request.sessionId ?? findLatestSessionForCommand(db, "generate components");
16535
+ if (!sessionId) {
16536
+ throw new MapTokensRunFailure({ type: "no-session" });
16537
+ }
16538
+ const tokenLeaves = loadTokenLeaves(db, sessionId);
16539
+ const knownTokenPaths = new Set(tokenLeaves.map((t) => t.path));
16540
+ if (request.tokenMapInline) {
16541
+ const validMappings = {};
16542
+ for (const [rawName, path5] of Object.entries(request.tokenMapInline)) {
16543
+ if (knownTokenPaths.has(path5))
16544
+ validMappings[rawName] = path5;
16545
+ }
16546
+ replaceRawTokenNamePaths(db, sessionId, validMappings, "manual");
16547
+ }
16548
+ const rawDefaults = loadRawDefaults(db, sessionId);
16549
+ const defaultResolution = resolveTokenDefaults(rawDefaults.map((row) => ({ rawDefault: row.default_reference, tokenKind: row.cdf_token_kind })), tokenLeaves);
16550
+ const manualMappings = new Map(getRawTokenNamePathRows(db, sessionId).filter((row) => row.source === "manual").map((row) => [row.rawName, row.path]));
16551
+ const automaticMappings = {};
16552
+ for (const [rawName, path5] of Object.entries(defaultResolution.mappings)) {
16553
+ if (manualMappings.get(rawName) === void 0)
16554
+ automaticMappings[rawName] = path5;
16555
+ }
16556
+ replaceRawTokenNamePaths(db, sessionId, automaticMappings, "automatic");
16557
+ const cdfEntries = loadCDFComponents(db, sessionId);
16558
+ if (cdfEntries.length === 0) {
16559
+ throw new MapTokensRunFailure({ type: "no-components", sessionId });
16560
+ }
16561
+ const mappablePropCount = countMappableProps(cdfEntries);
16562
+ const { groups, tokens } = getDtcgTokensForSession(db, sessionId);
16563
+ const tokenCount = tokens.length;
16564
+ if (mappablePropCount === 0 || tokenCount === 0) {
16565
+ return { type: "nothing-to-map", sessionId, mappablePropCount, tokenCount };
16566
+ }
16567
+ const generatedCdf = Object.fromEntries(cdfEntries.map((c2) => [c2.key, c2.entry]));
16568
+ const tokenTree = rebuildDTCGTree(groups, tokens);
16569
+ const componentSourceRefs = await loadComponentSourceRefs(db, sessionId);
16570
+ const buildMapPrompt = () => buildPrompt({
16571
+ skill: "map-tokens",
16572
+ mode: "autonomous",
16573
+ generatedCdf,
16574
+ tokenTree,
16575
+ componentSourceRefs,
16576
+ outDir: process.cwd(),
16577
+ existingTokensInline: request.existingEntitiesInline,
16578
+ ...request.skillContentOverride !== void 0 ? { skillContentOverride: request.skillContentOverride } : {},
16579
+ ...request.skillContentOverride === void 0 && request.skillPathOverride ? { skillPathOverride: resolve18(request.skillPathOverride) } : {}
16580
+ });
16581
+ if (request.printPrompt) {
16582
+ const prompt2 = await buildMapPrompt();
16583
+ return { type: "printed-prompt", sessionId, prompt: prompt2 };
16584
+ }
16585
+ if (request.skipAgent) {
16586
+ const stepId2 = createStep(db, sessionId, "map tokens", {
16587
+ agent: request.agent,
16588
+ model: request.model ?? "",
16589
+ skipAgent: "true"
16590
+ });
16591
+ updateStep(db, stepId2, "complete", { applied: "0", skipAgent: "true" });
16592
+ return { type: "skipped", sessionId, stepId: stepId2 };
16593
+ }
16594
+ const agent = request.agent;
16595
+ const noCache = request.cache === false || process.env["EDS_NO_CACHE"] === "1";
16596
+ const promptHash = await hashPromptForSkill("map-tokens", agent, request.model, void 0, request.existingEntitiesInline ? [hashContent(request.existingEntitiesInline)] : [], request.skillContentOverride);
16597
+ const inputHash = computeMapTokensInputHash(db, sessionId, componentSourceRefs);
16598
+ if (!noCache) {
16599
+ const cached = lookupCache(db, inputHash, "token_mapping", "__map_tokens__", promptHash);
16600
+ if (cached) {
16601
+ const applied2 = copyMapTokensFromCache(db, cached.sourceSessionId, sessionId);
16602
+ const stepId2 = createStep(db, sessionId, "map tokens", { agent, model: request.model ?? "" });
16603
+ updateStep(db, stepId2, "complete", { cached: "true", applied: String(applied2) });
16604
+ return { type: "cached", sessionId, applied: applied2, stepId: stepId2 };
16605
+ }
16606
+ }
16607
+ const binary = resolveBinary(agent);
16608
+ if (!await binaryExists(binary)) {
16609
+ throw new MapTokensRunFailure({
16610
+ type: "binary-not-found",
16611
+ agent,
16612
+ binary,
16613
+ skillPath: resolveSkillPath("map-tokens")
16614
+ });
16615
+ }
16616
+ const stepId = createStep(db, sessionId, "map tokens", { agent, model: request.model ?? "" });
16617
+ const prompt = await buildMapPrompt();
16618
+ const invoker = createLocalCliAgentInvoker();
16619
+ const result = await invoker.invoke({ agent, model: request.model, prompt, timeoutMs });
16620
+ if (result.timedOut || result.exitCode !== 0) {
16621
+ const error = result.timedOut ? `timed out after ${timeoutMs / 6e4} minutes` : describeAgentFailure(result);
16622
+ updateStep(db, stepId, "failed", {}, error);
16623
+ throw new MapTokensRunFailure({ type: "agent-failed", sessionId, stepId, error });
16624
+ }
16625
+ const { calls, warnings: parseWarnings } = parseMapTokenPropToolCalls(result.stdout);
16626
+ const { applied, warnings } = applyMapTokenPropCalls(db, sessionId, calls, parseWarnings);
16627
+ if (!noCache) {
16628
+ storeCache(db, inputHash, "token_mapping", "__map_tokens__", sessionId, false, promptHash);
16629
+ }
16630
+ updateStep(db, stepId, "complete", { applied: String(applied), warnings: String(warnings.length) });
16631
+ return { type: "applied", sessionId, applied, warnings, stepId };
16632
+ } finally {
16633
+ db.close();
16634
+ }
16635
+ }
16636
+ var DEFAULT_TIMEOUT_MS2, MapTokensRunFailure;
15642
16637
  var init_run_map_tokens = __esm({
15643
16638
  "packages/experience-design-system-backend-pipeline/dist/src/steps/generation/src/controller/map-tokens/run-map-tokens.js"() {
15644
16639
  "use strict";
@@ -15658,6 +16653,25 @@ var init_run_map_tokens = __esm({
15658
16653
  init_rebuild_dtcg_tree();
15659
16654
  init_resolve_token_defaults();
15660
16655
  DEFAULT_TIMEOUT_MS2 = 5 * 60 * 1e3;
16656
+ MapTokensRunFailure = class _MapTokensRunFailure extends Error {
16657
+ reason;
16658
+ constructor(reason) {
16659
+ super(_MapTokensRunFailure.format(reason));
16660
+ this.reason = reason;
16661
+ }
16662
+ static format(r) {
16663
+ switch (r.type) {
16664
+ case "no-session":
16665
+ return "no completed generate components session found. Run generate components first, or pass sessionId.";
16666
+ case "no-components":
16667
+ return `no generated components in session '${r.sessionId}'. Run generate components first.`;
16668
+ case "binary-not-found":
16669
+ return `agent '${r.agent}' not found in $PATH (looked for binary: ${r.binary}). Install it, choose another agent, or run the mapping manually via: ${r.skillPath}`;
16670
+ case "agent-failed":
16671
+ return `map tokens agent failed \u2014 ${r.error}`;
16672
+ }
16673
+ }
16674
+ };
15661
16675
  }
15662
16676
  });
15663
16677
 
@@ -17325,11 +18339,11 @@ var init_detect_data_wrapper_patterns = __esm({
17325
18339
  });
17326
18340
 
17327
18341
  // packages/experience-design-system-extraction/dist/src/extract/services/quality/helpers/inspection/inspect-component-source.js
17328
- import { readFile as readFile12 } from "node:fs/promises";
18342
+ import { readFile as readFile15 } from "node:fs/promises";
17329
18343
  async function inspectComponentSource(component) {
17330
18344
  let sourceText = "";
17331
18345
  try {
17332
- sourceText = await readFile12(component.source, "utf8");
18346
+ sourceText = await readFile15(component.source, "utf8");
17333
18347
  } catch {
17334
18348
  return {
17335
18349
  wrapperConfidence: 0,
@@ -17720,7 +18734,7 @@ async function retryDatabaseWrite(operation, attempts = 8) {
17720
18734
  const message = error instanceof Error ? error.message : String(error);
17721
18735
  if (!/database is locked|database is busy/i.test(message) || attempt >= attempts)
17722
18736
  throw error;
17723
- await new Promise((resolve22) => setTimeout(resolve22, Math.min(250 * attempt, 2e3)));
18737
+ await new Promise((resolve25) => setTimeout(resolve25, Math.min(250 * attempt, 2e3)));
17724
18738
  }
17725
18739
  }
17726
18740
  }
@@ -17768,7 +18782,7 @@ var init_resolve_composition_agent_name = __esm({
17768
18782
  });
17769
18783
 
17770
18784
  // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-extract-and-compose-session/helpers/read-candidate-files.js
17771
- import { readFile as readFile13 } from "node:fs/promises";
18785
+ import { readFile as readFile16 } from "node:fs/promises";
17772
18786
  async function readCandidateFiles(components, extraFiles = []) {
17773
18787
  const paths = new Set(extraFiles);
17774
18788
  for (const c2 of components) {
@@ -17778,7 +18792,7 @@ async function readCandidateFiles(components, extraFiles = []) {
17778
18792
  const out = [];
17779
18793
  await Promise.all([...paths].map(async (p) => {
17780
18794
  try {
17781
- const content = await readFile13(p, "utf8");
18795
+ const content = await readFile16(p, "utf8");
17782
18796
  out.push({ path: p, content });
17783
18797
  } catch {
17784
18798
  }
@@ -18011,7 +19025,7 @@ var init_write_tokens_file = __esm({
18011
19025
  });
18012
19026
 
18013
19027
  // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-tokens-session/run-generate-tokens-session.js
18014
- import { readFile as readFile14 } from "node:fs/promises";
19028
+ import { readFile as readFile17 } from "node:fs/promises";
18015
19029
  import { basename as basename5, resolve as pathResolve } from "node:path";
18016
19030
  async function runGenerateTokensSession(request) {
18017
19031
  const { rawTokensPath, outDir, agent, agentModel, promptOverrides, skillPath, noCache, bedrock = false, onProgress, onSessionCreated } = request;
@@ -18020,7 +19034,7 @@ async function runGenerateTokensSession(request) {
18020
19034
  throw new Error(`Prompt override error(s): ${promptErrors.join("; ")}`);
18021
19035
  const tokensOverride = overridesMap.get("tokens");
18022
19036
  const skillContentOverride = tokensOverride ? await resolvePromptOverride(tokensOverride) : void 0;
18023
- const rawTokensInline = await readFile14(pathResolve(rawTokensPath), "utf8");
19037
+ const rawTokensInline = await readFile17(pathResolve(rawTokensPath), "utf8");
18024
19038
  const tokenInputHash = hashTokenContent(rawTokensInline);
18025
19039
  const db = openPipelineDb();
18026
19040
  try {
@@ -18105,6 +19119,426 @@ var init_run_generate_tokens_session = __esm({
18105
19119
  }
18106
19120
  });
18107
19121
 
19122
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/build-empty-session-response.js
19123
+ function buildEmptySessionResponse(sessionId) {
19124
+ return {
19125
+ sessionId,
19126
+ results: [],
19127
+ allOk: true,
19128
+ renamedSlotsCount: 0,
19129
+ duplicateNames: [],
19130
+ droppedAllowedComponents: [],
19131
+ emptySession: true
19132
+ };
19133
+ }
19134
+ var init_build_empty_session_response = __esm({
19135
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/build-empty-session-response.js"() {
19136
+ "use strict";
19137
+ }
19138
+ });
19139
+
19140
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/collect-duplicate-names.js
19141
+ function collectDuplicateNames(components) {
19142
+ const nameCounts = /* @__PURE__ */ new Map();
19143
+ for (const c2 of components) {
19144
+ const sources = nameCounts.get(c2.name) ?? [];
19145
+ sources.push(c2.source);
19146
+ nameCounts.set(c2.name, sources);
19147
+ }
19148
+ return [...nameCounts.entries()].filter(([, srcs]) => srcs.length > 1).map(([name, sources]) => ({ name, sources }));
19149
+ }
19150
+ var init_collect_duplicate_names = __esm({
19151
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/collect-duplicate-names.js"() {
19152
+ "use strict";
19153
+ }
19154
+ });
19155
+
19156
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/filter-dropped-allowed-components.js
19157
+ function filterDroppedAllowedComponents(db, sessionId, components, allowedComponentNames2, acceptedNames) {
19158
+ const dropped = filterUnknownSlotAllowedComponents(db, sessionId, allowedComponentNames2);
19159
+ if (dropped.length === 0)
19160
+ return { components, dropped: [] };
19161
+ return { components: loadRawComponents(db, sessionId, acceptedNames), dropped };
19162
+ }
19163
+ var init_filter_dropped_allowed_components = __esm({
19164
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/filter-dropped-allowed-components.js"() {
19165
+ "use strict";
19166
+ init_db();
19167
+ }
19168
+ });
19169
+
19170
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/read-existing-entities.js
19171
+ async function readExistingEntities(request) {
19172
+ if (request.existingContentfulEntities !== void 0)
19173
+ return request.existingContentfulEntities;
19174
+ if (!request.existingEntitiesPath)
19175
+ return void 0;
19176
+ return readExistingContentfulEntitiesFromSession({ path: request.existingEntitiesPath });
19177
+ }
19178
+ var init_read_existing_entities = __esm({
19179
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/read-existing-entities.js"() {
19180
+ "use strict";
19181
+ init_read_from_session();
19182
+ }
19183
+ });
19184
+
19185
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/resolve-generate-prompt.js
19186
+ import { resolve as resolve19 } from "node:path";
19187
+ async function resolveGeneratePrompt(overrides) {
19188
+ const { overrides: parsed, errors } = parsePromptOverrides(overrides);
19189
+ if (errors.length > 0)
19190
+ throw new Error(errors.join("; "));
19191
+ const entry = parsed.get("generate");
19192
+ if (!entry)
19193
+ return {};
19194
+ const text = await resolvePromptOverride(entry);
19195
+ if (entry.kind === "text")
19196
+ return { text };
19197
+ return { path: resolve19(entry.value), text };
19198
+ }
19199
+ var init_resolve_generate_prompt = __esm({
19200
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/resolve-generate-prompt.js"() {
19201
+ "use strict";
19202
+ init_parse_prompt_overrides();
19203
+ init_resolve_prompt_override();
19204
+ }
19205
+ });
19206
+
19207
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/run-one-generate-component.js
19208
+ async function runOneGenerateComponent(options, component, index, total) {
19209
+ const { db, sessionId, invoker, agent, model, tokensInline, tokenMapInline, verbose, noCache, skillPathOverride, skillContentOverride, promptHash, existingContentfulEntities, existingTokensInline, precomputedCachedNames, allowedComponentNames: allowedComponentNames2, onProgress } = options;
19210
+ const { renames } = renameEmptySlots(db, sessionId, component.component_id, component.name, component.slots.length);
19211
+ let effectiveSlots = component.slots;
19212
+ if (renames.length > 0) {
19213
+ const renameMap = new Map(renames.map((r) => [r.oldName, r.newName]));
19214
+ effectiveSlots = component.slots.map((s) => renameMap.has(s.name) ? { ...s, name: renameMap.get(s.name) } : s);
19215
+ for (const rename4 of renames) {
19216
+ onProgress?.({
19217
+ kind: "component:slot-renamed",
19218
+ componentName: component.name,
19219
+ oldName: rename4.oldName,
19220
+ newName: rename4.newName
19221
+ });
19222
+ }
19223
+ }
19224
+ effectiveSlots = effectiveSlots.map((slot) => slot.allowedComponents ? { ...slot, allowedComponents: slot.allowedComponents.filter((name) => allowedComponentNames2.has(name)) } : slot);
19225
+ const cacheComponent = normalizeComponentForCache(component);
19226
+ if (!noCache && precomputedCachedNames.has(component.name)) {
19227
+ onProgress?.({ kind: "component:cached", index, total, name: component.name, pinned: false });
19228
+ return cachedResult(component.name);
19229
+ }
19230
+ if (!noCache) {
19231
+ const resolution = resolveComponentCache(db, component, promptHash, allowedComponentNames2);
19232
+ if (resolution && !resolution.humanEdited) {
19233
+ copyComponentFromCache(db, resolution.entry.sourceSessionId, sessionId, component.component_id, true, {
19234
+ allowedComponentNames: allowedComponentNames2
19235
+ });
19236
+ storeCache(db, hashComponentShape(cacheComponent), "component", component.component_id, resolution.entry.sourceSessionId, resolution.entry.humanEdited, promptHash);
19237
+ onProgress?.({ kind: "component:cached", index, total, name: component.name, pinned: false });
19238
+ return cachedResult(component.name);
19239
+ }
19240
+ if (resolution?.humanEdited) {
19241
+ copyComponentFromCache(db, resolution.entry.sourceSessionId, sessionId, component.component_id, true, {
19242
+ allowedComponentNames: allowedComponentNames2
19243
+ });
19244
+ onProgress?.({ kind: "component:cached", index, total, name: component.name, pinned: true });
19245
+ return cachedResult(component.name, [`${component.name}: source changed but human edits preserved`]);
19246
+ }
19247
+ }
19248
+ const rawComponentsInline = JSON.stringify([
19249
+ {
19250
+ name: component.name,
19251
+ source: component.source,
19252
+ framework: component.framework,
19253
+ props: component.props,
19254
+ slots: effectiveSlots
19255
+ }
19256
+ ], null, 2);
19257
+ const sourceRef = await loadComponentSourceRef(component.name, component.sourcePath ?? component.source, component.props.map((p) => p.name), component.props.map((p) => p.type));
19258
+ const existingComponentsInline = existingContentfulEntities ? JSON.stringify(summarizeForGenerateAgent(existingContentfulEntities, component.name)) : void 0;
19259
+ const prompt = await buildPrompt({
19260
+ skill: "components",
19261
+ mode: "autonomous",
19262
+ rawComponentsInline,
19263
+ tokensInline,
19264
+ tokenMapInline,
19265
+ outDir: process.cwd(),
19266
+ componentName: component.name,
19267
+ componentSourceRefs: [sourceRef],
19268
+ skillPathOverride,
19269
+ skillContentOverride,
19270
+ existingComponentsInline,
19271
+ existingTokensInline,
19272
+ componentAllowlistInline: JSON.stringify([...allowedComponentNames2].sort())
19273
+ });
19274
+ const maxAttempts = 2;
19275
+ let lastError = "";
19276
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
19277
+ if (attempt > 1)
19278
+ await new Promise((res) => setTimeout(res, RETRY_BACKOFF_MS));
19279
+ onProgress?.({ kind: "component:started", index, total, name: component.name, attempt, maxAttempts });
19280
+ const { result } = await invokeAgentWithOutput(invoker, { agent, model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS4 }, verbose);
19281
+ if (result.timedOut) {
19282
+ const error = `timed out after ${DEFAULT_TIMEOUT_MS4 / 6e4} minutes`;
19283
+ onProgress?.({ kind: "component:failed", index, total, name: component.name, error });
19284
+ return failed(component.name, error, renames.length);
19285
+ }
19286
+ if (result.exitCode !== 0) {
19287
+ lastError = describeAgentFailure(result);
19288
+ continue;
19289
+ }
19290
+ const { calls, warnings } = parseToolCalls(result.stdout);
19291
+ if (calls.length === 0) {
19292
+ lastError = describeAgentFailure(result);
19293
+ continue;
19294
+ }
19295
+ const applied = applyToolCalls(db, sessionId, component.component_id, component.name, calls, warnings, {
19296
+ allowedComponentNames: allowedComponentNames2
19297
+ });
19298
+ if (!noCache) {
19299
+ storeCache(db, hashComponentShape(cacheComponent), "component", component.component_id, sessionId, false, promptHash);
19300
+ }
19301
+ onProgress?.({
19302
+ kind: "component:completed",
19303
+ index,
19304
+ total,
19305
+ name: component.name,
19306
+ classified: applied.classified,
19307
+ excluded: applied.excluded,
19308
+ slots: applied.slots,
19309
+ warnings: applied.warnings
19310
+ });
19311
+ return {
19312
+ componentName: component.name,
19313
+ classified: applied.classified,
19314
+ excluded: applied.excluded,
19315
+ slots: applied.slots,
19316
+ warnings: applied.warnings,
19317
+ failed: false,
19318
+ cached: false,
19319
+ renamedSlotsCount: renames.length
19320
+ };
19321
+ }
19322
+ onProgress?.({ kind: "component:failed", index, total, name: component.name, error: lastError });
19323
+ return failed(component.name, lastError, renames.length);
19324
+ }
19325
+ function cachedResult(componentName, warnings = []) {
19326
+ return {
19327
+ componentName,
19328
+ classified: 0,
19329
+ excluded: 0,
19330
+ slots: 0,
19331
+ warnings,
19332
+ failed: false,
19333
+ cached: true,
19334
+ renamedSlotsCount: 0
19335
+ };
19336
+ }
19337
+ function failed(componentName, error, renamedSlotsCount) {
19338
+ return {
19339
+ componentName,
19340
+ classified: 0,
19341
+ excluded: 0,
19342
+ slots: 0,
19343
+ warnings: [],
19344
+ failed: true,
19345
+ error,
19346
+ cached: false,
19347
+ renamedSlotsCount
19348
+ };
19349
+ }
19350
+ var DEFAULT_TIMEOUT_MS4, RETRY_BACKOFF_MS;
19351
+ var init_run_one_generate_component = __esm({
19352
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/run-one-generate-component.js"() {
19353
+ "use strict";
19354
+ init_build_prompt();
19355
+ init_describe_agent_failure();
19356
+ init_invoke_agent_with_output();
19357
+ init_parse_tool_calls();
19358
+ init_db();
19359
+ init_normalize_component_for_cache();
19360
+ init_resolve_component_cache();
19361
+ init_summarize_for_generate();
19362
+ DEFAULT_TIMEOUT_MS4 = Number(process.env["EDS_AGENT_TIMEOUT_MS"] ?? 5 * 60 * 1e3);
19363
+ RETRY_BACKOFF_MS = Number(process.env["EDS_RETRY_BACKOFF_MS"] ?? 5e3);
19364
+ }
19365
+ });
19366
+
19367
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/run-with-pool.js
19368
+ async function runWithPool(items, concurrency, worker) {
19369
+ const results = new Array(items.length);
19370
+ let next = 0;
19371
+ async function run() {
19372
+ while (next < items.length) {
19373
+ const i = next++;
19374
+ results[i] = await worker(items[i], i);
19375
+ }
19376
+ }
19377
+ await Promise.all(Array.from({ length: concurrency }, run));
19378
+ return results;
19379
+ }
19380
+ var init_run_with_pool = __esm({
19381
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/helpers/run-with-pool.js"() {
19382
+ "use strict";
19383
+ }
19384
+ });
19385
+
19386
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/check-generate-components-cache.js
19387
+ async function checkGenerateComponentsCache(request) {
19388
+ if (request.noCache) {
19389
+ return { sessionId: request.sessionId, cachedComponentNames: [], fullyCached: false, cacheDisabled: true };
19390
+ }
19391
+ const existingEntities = await readExistingEntities(request);
19392
+ const existingTokensInline = existingEntities ? JSON.stringify(summarizeForMapTokens({ entities: existingEntities })) : void 0;
19393
+ const prompt = await resolveGeneratePrompt(request.promptOverrides);
19394
+ const agent = request.agent;
19395
+ const promptHash = await hashPromptForSkill("components", agent, request.agentModel, prompt.path, existingTokensInline ? [hashContent(existingTokensInline)] : [], prompt.text);
19396
+ const db = openPipelineDb();
19397
+ try {
19398
+ const acceptedNames = await loadAcceptedNames(request.sessionId);
19399
+ const components = loadRawComponents(db, request.sessionId, acceptedNames ?? void 0);
19400
+ if (components.length === 0) {
19401
+ return { sessionId: request.sessionId, cachedComponentNames: [], fullyCached: false, cacheDisabled: false };
19402
+ }
19403
+ const allowedComponentNames2 = /* @__PURE__ */ new Set([
19404
+ ...components.map((component) => component.name),
19405
+ ...(existingEntities?.components ?? []).map((component) => component.name)
19406
+ ]);
19407
+ const cachedComponents = components.flatMap((component) => {
19408
+ const resolution = resolveComponentCache(db, component, promptHash, allowedComponentNames2);
19409
+ return resolution ? [{ component, resolution }] : [];
19410
+ });
19411
+ if (request.restoreCache)
19412
+ restoreCached(db, request.sessionId, cachedComponents, promptHash, allowedComponentNames2);
19413
+ return {
19414
+ sessionId: request.sessionId,
19415
+ cachedComponentNames: cachedComponents.map(({ component }) => component.name),
19416
+ fullyCached: cachedComponents.length === components.length,
19417
+ cacheDisabled: false
19418
+ };
19419
+ } finally {
19420
+ db.close();
19421
+ }
19422
+ }
19423
+ function restoreCached(db, sessionId, cachedComponents, promptHash, allowedComponentNames2) {
19424
+ const restorations = [];
19425
+ const rekeyed = [];
19426
+ const componentStatus = db.prepare("SELECT status FROM raw_components WHERE session_id = ? AND component_id = ?");
19427
+ for (const { component, resolution } of cachedComponents) {
19428
+ const current = componentStatus.get(sessionId, component.component_id);
19429
+ if (current?.status === "generated")
19430
+ continue;
19431
+ renameEmptySlots(db, sessionId, component.component_id, component.name, component.slots.length);
19432
+ restorations.push({
19433
+ sourceSessionId: resolution.entry.sourceSessionId,
19434
+ targetSessionId: sessionId,
19435
+ componentId: component.component_id
19436
+ });
19437
+ rekeyed.push({ component, cached: resolution.entry });
19438
+ }
19439
+ copyComponentsFromCache(db, restorations, { allowedComponentNames: allowedComponentNames2 });
19440
+ storeCaches(db, rekeyed.map(({ component, cached }) => ({
19441
+ inputHash: hashComponentShape(normalizeComponentForCache(component)),
19442
+ entityType: "component",
19443
+ entityId: component.component_id,
19444
+ sourceSessionId: cached.sourceSessionId,
19445
+ humanEdited: cached.humanEdited,
19446
+ promptHash
19447
+ })));
19448
+ }
19449
+ var init_check_generate_components_cache = __esm({
19450
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/check-generate-components-cache.js"() {
19451
+ "use strict";
19452
+ init_summarize_for_map_tokens();
19453
+ init_resolve_component_cache();
19454
+ init_normalize_component_for_cache();
19455
+ init_db();
19456
+ init_cache_keys();
19457
+ init_src();
19458
+ init_read_existing_entities();
19459
+ init_resolve_generate_prompt();
19460
+ }
19461
+ });
19462
+
19463
+ // packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/run-generate-components-session.js
19464
+ async function runGenerateComponentsSession(request) {
19465
+ const prompt = await resolveGeneratePrompt(request.promptOverrides);
19466
+ const existingEntities = await readExistingEntities(request);
19467
+ const existingTokensInline = existingEntities ? JSON.stringify(summarizeForMapTokens({ entities: existingEntities })) : void 0;
19468
+ const existingTokensHash = existingTokensInline ? [hashContent(existingTokensInline)] : [];
19469
+ const agent = request.agent;
19470
+ const promptHash = await hashPromptForSkill("components", agent, request.agentModel, prompt.path, existingTokensHash, prompt.text);
19471
+ const db = openPipelineDb();
19472
+ try {
19473
+ const acceptedNames = await loadAcceptedNames(request.sessionId);
19474
+ const acceptedSet = acceptedNames ? new Set(acceptedNames) : void 0;
19475
+ let components = loadRawComponents(db, request.sessionId, acceptedSet ?? void 0);
19476
+ if (components.length === 0)
19477
+ return buildEmptySessionResponse(request.sessionId);
19478
+ const allowedComponentNames2 = /* @__PURE__ */ new Set([
19479
+ ...components.map((c2) => c2.name),
19480
+ ...(existingEntities?.components ?? []).map((c2) => c2.name)
19481
+ ]);
19482
+ const { components: filtered, dropped } = filterDroppedAllowedComponents(db, request.sessionId, components, allowedComponentNames2, acceptedSet);
19483
+ components = filtered;
19484
+ const duplicateNames = collectDuplicateNames(components);
19485
+ const invoker = createLocalCliAgentInvoker({});
19486
+ const concurrency = Math.max(1, Math.min(DEFAULT_COMPONENT_CONCURRENCY, components.length));
19487
+ const results = await runWithPool(components, concurrency, (component, index) => runOneGenerateComponent({
19488
+ db,
19489
+ sessionId: request.sessionId,
19490
+ invoker,
19491
+ agent,
19492
+ model: request.agentModel,
19493
+ tokensInline: request.tokensInline,
19494
+ tokenMapInline: request.tokenMapInline,
19495
+ verbose: request.verbose ?? false,
19496
+ noCache: request.noCache,
19497
+ skillPathOverride: prompt.path,
19498
+ skillContentOverride: prompt.text,
19499
+ promptHash,
19500
+ existingContentfulEntities: existingEntities,
19501
+ existingTokensInline,
19502
+ precomputedCachedNames: request.precomputedCachedNames ?? /* @__PURE__ */ new Set(),
19503
+ allowedComponentNames: allowedComponentNames2,
19504
+ onProgress: request.onProgress
19505
+ }, component, index, components.length));
19506
+ const allOk = results.every((r) => !r.failed);
19507
+ const renamedSlotsCount = results.reduce((sum, r) => sum + r.renamedSlotsCount, 0);
19508
+ return {
19509
+ sessionId: request.sessionId,
19510
+ results,
19511
+ allOk,
19512
+ renamedSlotsCount,
19513
+ duplicateNames,
19514
+ droppedAllowedComponents: dropped,
19515
+ emptySession: false
19516
+ };
19517
+ } finally {
19518
+ db.close();
19519
+ }
19520
+ }
19521
+ var DEFAULT_COMPONENT_CONCURRENCY;
19522
+ var init_run_generate_components_session = __esm({
19523
+ "packages/experience-design-system-backend-pipeline/dist/src/orchestrators/run-generate-components-session/run-generate-components-session.js"() {
19524
+ "use strict";
19525
+ init_create_local_cli_agent_invoker();
19526
+ init_db();
19527
+ init_cache_keys();
19528
+ init_src();
19529
+ init_summarize_for_map_tokens();
19530
+ init_build_empty_session_response();
19531
+ init_collect_duplicate_names();
19532
+ init_filter_dropped_allowed_components();
19533
+ init_read_existing_entities();
19534
+ init_resolve_generate_prompt();
19535
+ init_run_one_generate_component();
19536
+ init_run_with_pool();
19537
+ init_check_generate_components_cache();
19538
+ DEFAULT_COMPONENT_CONCURRENCY = Number(process.env["EDS_GENERATE_CONCURRENCY"] ?? 10);
19539
+ }
19540
+ });
19541
+
18108
19542
  // packages/experience-design-system-backend-pipeline/dist/src/index.js
18109
19543
  var init_src4 = __esm({
18110
19544
  "packages/experience-design-system-backend-pipeline/dist/src/index.js"() {
@@ -18220,6 +19654,7 @@ var init_src4 = __esm({
18220
19654
  init_component();
18221
19655
  init_run_extract_and_compose_session();
18222
19656
  init_run_generate_tokens_session();
19657
+ init_run_generate_components_session();
18223
19658
  }
18224
19659
  });
18225
19660
 
@@ -19028,7 +20463,7 @@ var init_steps = __esm({
19028
20463
 
19029
20464
  // packages/experience-design-system-types/dist/src/config/index.js
19030
20465
  import { randomBytes as randomBytes3 } from "node:crypto";
19031
- import { mkdir as mkdir6, readFile as readFile15, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
20466
+ import { mkdir as mkdir6, readFile as readFile18, rename as rename2, writeFile as writeFile6 } from "node:fs/promises";
19032
20467
  import { homedir as homedir3 } from "node:os";
19033
20468
  import { dirname as dirname13, join as join19 } from "node:path";
19034
20469
  function configRoot2() {
@@ -19036,7 +20471,7 @@ function configRoot2() {
19036
20471
  }
19037
20472
  async function readSettings2() {
19038
20473
  try {
19039
- return JSON.parse(await readFile15(configFilePath2(), "utf8"));
20474
+ return JSON.parse(await readFile18(configFilePath2(), "utf8"));
19040
20475
  } catch {
19041
20476
  return {};
19042
20477
  }
@@ -19065,7 +20500,7 @@ var init_config = __esm({
19065
20500
 
19066
20501
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/find-skill-path.ts
19067
20502
  import { existsSync as existsSync10 } from "node:fs";
19068
- import { dirname as dirname14, join as join20, resolve as resolve18 } from "node:path";
20503
+ import { dirname as dirname14, join as join20, resolve as resolve20 } from "node:path";
19069
20504
  import { fileURLToPath as fileURLToPath4 } from "node:url";
19070
20505
  function findSkillPath(fileName) {
19071
20506
  const thisDir = dirname14(fileURLToPath4(import.meta.url));
@@ -19073,7 +20508,7 @@ function findSkillPath(fileName) {
19073
20508
  for (; ; ) {
19074
20509
  const candidate = join20(dir, "skills", fileName);
19075
20510
  if (existsSync10(candidate)) return candidate;
19076
- const parent = resolve18(dir, "..");
20511
+ const parent = resolve20(dir, "..");
19077
20512
  if (parent === dir) {
19078
20513
  throw new Error(`skill file not found (looked for skills/${fileName} from ${thisDir})`);
19079
20514
  }
@@ -19087,9 +20522,9 @@ var init_find_skill_path = __esm({
19087
20522
  });
19088
20523
 
19089
20524
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/selection.ts
19090
- import { resolve as resolve19 } from "node:path";
20525
+ import { resolve as resolve21 } from "node:path";
19091
20526
  async function hashSelectPrompt(options) {
19092
- const promptHash = options.promptText ? hashContent(options.promptText) : options.promptPath ? await hashFile(resolve19(options.promptPath)) : await hashFile(SELECT_SKILL_PATH);
20527
+ const promptHash = options.promptText ? hashContent(options.promptText) : options.promptPath ? await hashFile(resolve21(options.promptPath)) : await hashFile(SELECT_SKILL_PATH);
19093
20528
  return hashContent(`${promptHash}|${options.agent}|${options.model ?? ""}`);
19094
20529
  }
19095
20530
  async function runSelection(options) {
@@ -19123,7 +20558,7 @@ async function runSelection(options) {
19123
20558
  });
19124
20559
  const { result } = await invokeAgentWithOutput(
19125
20560
  invoker,
19126
- { agent: options.agent, model: options.model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS4 },
20561
+ { agent: options.agent, model: options.model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS5 },
19127
20562
  false
19128
20563
  );
19129
20564
  if (result.timedOut) throw new Error("selection agent timed out");
@@ -19171,22 +20606,22 @@ async function runSelection(options) {
19171
20606
  writeDb.close();
19172
20607
  }
19173
20608
  }
19174
- var SELECT_SKILL_PATH, DEFAULT_TIMEOUT_MS4;
20609
+ var SELECT_SKILL_PATH, DEFAULT_TIMEOUT_MS5;
19175
20610
  var init_selection2 = __esm({
19176
20611
  "packages/experience-design-system-cli/src/tui/import/steps/06-extraction/selection.ts"() {
19177
20612
  "use strict";
19178
20613
  init_src4();
19179
20614
  init_find_skill_path();
19180
20615
  SELECT_SKILL_PATH = findSkillPath("select-components.md");
19181
- DEFAULT_TIMEOUT_MS4 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
20616
+ DEFAULT_TIMEOUT_MS5 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
19182
20617
  }
19183
20618
  });
19184
20619
 
19185
20620
  // packages/experience-design-system-cli/src/tui/import/steps/06-extraction/run.ts
19186
20621
  import { mkdir as mkdir7 } from "node:fs/promises";
19187
- import { join as join21, resolve as resolve20 } from "node:path";
20622
+ import { join as join21, resolve as resolve22 } from "node:path";
19188
20623
  async function runExtraction(input, onProgress, deps = realDeps) {
19189
- const outDir = join21(resolve20(input.projectPath), ".contentful");
20624
+ const outDir = join21(resolve22(input.projectPath), ".contentful");
19190
20625
  let progress = initialProgress({
19191
20626
  hasCredentials: input.credentials !== null,
19192
20627
  hasRawTokens: input.rawTokensPath !== "",
@@ -19312,7 +20747,7 @@ async function resolveSelectionPrompt(overrides) {
19312
20747
  if (select?.kind === "text") return { promptText: select.value };
19313
20748
  if (select?.kind === "path") {
19314
20749
  await resolvePromptOverride(select);
19315
- return { promptPath: resolve20(select.value) };
20750
+ return { promptPath: resolve22(select.value) };
19316
20751
  }
19317
20752
  return {};
19318
20753
  }
@@ -20313,7 +21748,7 @@ function buildVisibleRows(props) {
20313
21748
  if (visited.has(target)) continue;
20314
21749
  visited.add(target);
20315
21750
  const isCycleMember = cycleParticipants.has(target);
20316
- out.push({ name: target, depth: cur.depth + 1, isCycleMember, parent: cur.name });
21751
+ out.push({ name: target, depth: cur.depth + 1, isCycleMember });
20317
21752
  queue.push({ name: target, depth: cur.depth + 1 });
20318
21753
  }
20319
21754
  }
@@ -20360,8 +21795,7 @@ function buildVisibleRows(props) {
20360
21795
  sharedSuffix,
20361
21796
  cycleChild: child.isCycleMember || void 0,
20362
21797
  itemIdx: childRec?.idx ?? -1,
20363
- rootName: key,
20364
- parentName: child.parent
21798
+ rootName: key
20365
21799
  });
20366
21800
  });
20367
21801
  }
@@ -20444,19 +21878,13 @@ function buildVisibleRows(props) {
20444
21878
  injectedChildren.push({
20445
21879
  name: target,
20446
21880
  depth: parentDepth + 1,
20447
- isCycleChild: true,
20448
- parent: parentName
21881
+ isCycleChild: true
20449
21882
  });
20450
21883
  }
20451
21884
  };
20452
21885
  emitCycleChildrenOf(root, 0);
20453
21886
  for (const c2 of closureChildren) {
20454
- injectedChildren.push({
20455
- name: c2.name,
20456
- depth: c2.depth,
20457
- isCycleChild: false,
20458
- parent: c2.path[c2.path.length - 2] ?? root
20459
- });
21887
+ injectedChildren.push({ name: c2.name, depth: c2.depth, isCycleChild: false });
20460
21888
  emitCycleChildrenOf(c2.name, c2.depth);
20461
21889
  }
20462
21890
  const isLastAtDepth = (idx) => {
@@ -20490,8 +21918,7 @@ function buildVisibleRows(props) {
20490
21918
  sharedSuffix,
20491
21919
  cycleChild: child.isCycleChild || void 0,
20492
21920
  itemIdx: childRec?.idx ?? -1,
20493
- rootName: root,
20494
- parentName: child.parent
21921
+ rootName: root
20495
21922
  });
20496
21923
  });
20497
21924
  }
@@ -20644,7 +22071,7 @@ function GroupedSidebar(props) {
20644
22071
  const rs = itemName ? renderStatusByKey?.get(itemName) : void 0;
20645
22072
  const badge = itemName ? previewBadge(previewAnnotationByKey?.get(itemName)) : null;
20646
22073
  const showInheritance = rs !== void 0 && row.kind !== "cycle" && row.kind !== "empty" && row.kind !== "group-root";
20647
- 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");
22074
+ 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");
20648
22075
  const selState = supportsSelectionGlyph ? selectionStateByKey.get(itemName) ?? "undecided" : void 0;
20649
22076
  const isCycleRow = row.kind === "cycle";
20650
22077
  const selStyle = selectionGlyphStyleFor(selState, isCycleRow);
@@ -20674,7 +22101,7 @@ function GroupedSidebar(props) {
20674
22101
  color: isSelected ? PALETTE2.info : labelStyle.dim ? PALETTE2.muted : labelStyle.color,
20675
22102
  bold: isSelected || labelStyle.bold,
20676
22103
  inverse: false,
20677
- underline: isSelected && focused,
22104
+ underline: isSelected && !focused,
20678
22105
  wrap: wrapLabels ? "wrap" : "truncate",
20679
22106
  children: [
20680
22107
  " ",
@@ -21425,7 +22852,6 @@ function resolveKey(mode, key, ctx) {
21425
22852
  function resolveMain(key, ctx) {
21426
22853
  const { input } = key;
21427
22854
  const inMain = ctx.focusedColumn === "main";
21428
- if (key.ctrl && input === "z") return { type: "undo" };
21429
22855
  if (input === "q" || key.escape) {
21430
22856
  if (key.escape && ctx.jumpFilterActive) return { type: "clear-jump-filter" };
21431
22857
  if (key.escape && ctx.searchActive) return { type: "clear-search" };
@@ -21724,30 +23150,14 @@ function rejectNeedsConfirmation(graph, name, state) {
21724
23150
  const ancestors = toReject.filter((n) => n !== name);
21725
23151
  return ancestors.length + toDeselect.length >= 2;
21726
23152
  }
21727
- function removeSlotChild(components, edge) {
21728
- return components.map(
21729
- (component) => component.name === edge.parent ? {
21730
- ...component,
21731
- slots: component.slots?.map((slot) => ({
21732
- ...slot,
21733
- allowedComponents: slot.allowedComponents.filter((name) => name !== edge.child)
21734
- }))
21735
- } : component
21736
- );
21737
- }
21738
- function withoutSlotChildren(components, removedEdges) {
21739
- return removedEdges.reduce(removeSlotChild, components);
21740
- }
21741
- function partitionDecisions(components, state, removedEdges) {
23153
+ function partitionDecisions(components, state) {
21742
23154
  const accepted = [];
21743
23155
  const rejected = [];
21744
23156
  for (const c2 of components) {
21745
23157
  if (state.get(c2.name) === "accepted") accepted.push(c2.name);
21746
23158
  else rejected.push(c2.name);
21747
23159
  }
21748
- const rejectedNames = new Set(rejected);
21749
- const excludedSlotEdges = removedEdges.filter((e) => !rejectedNames.has(e.parent) && !rejectedNames.has(e.child));
21750
- return { accepted, rejected, excludedSlotEdges };
23160
+ return { accepted, rejected };
21751
23161
  }
21752
23162
  var init_state = __esm({
21753
23163
  "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/state.ts"() {
@@ -21759,15 +23169,10 @@ var init_state = __esm({
21759
23169
 
21760
23170
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/use-scope-gate.ts
21761
23171
  import { useEffect as useEffect7, useMemo as useMemo2, useRef as useRef4, useState as useState12 } from "react";
21762
- function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
23172
+ function useScopeGate({ components, onConfirm, onQuit }) {
21763
23173
  const { columns: totalWidth, rows: terminalRows } = useTerminalSize();
21764
23174
  const columnPlan = useMemo2(() => computeColumnWidths(totalWidth), [totalWidth]);
21765
23175
  const [decisions, setDecisions] = useState12(/* @__PURE__ */ new Map());
21766
- const [removedEdges, setRemovedEdges] = useState12([]);
21767
- const components = useMemo2(
21768
- () => withoutSlotChildren(loadedComponents, removedEdges),
21769
- [loadedComponents, removedEdges]
21770
- );
21771
23176
  const [nav, setNav] = useState12({ cursor: 0, scrollOffset: 0 });
21772
23177
  const [focusedColumn, setFocusedColumn] = useState12("main");
21773
23178
  const [addedComponentsCursor, setAddedComponentsCursor] = useState12(0);
@@ -21939,14 +23344,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
21939
23344
  return void 0;
21940
23345
  }
21941
23346
  };
21942
- const focusedNestedEdge = () => {
21943
- const row = visibleRows[safeCursor];
21944
- if (row?.kind !== "group-child" || !row.parentName || row.itemIdx < 0) return void 0;
21945
- const child = groupedItems[row.itemIdx]?.key;
21946
- return child ? { parent: row.parentName, child } : void 0;
21947
- };
21948
- const removeFromParentSlot = (edge) => setRemovedEdges((edges) => [...edges, edge]);
21949
- const undoSlotRemoval = () => setRemovedEdges((edges) => edges.slice(0, -1));
21950
23347
  const jumpCursorTo = (name) => {
21951
23348
  let idx = -1;
21952
23349
  for (let i = 0; i < visibleRows.length; i++) {
@@ -22046,7 +23443,7 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
22046
23443
  onQuit();
22047
23444
  return;
22048
23445
  case "confirm":
22049
- onConfirm(partitionDecisions(components, decisions, removedEdges));
23446
+ onConfirm(partitionDecisions(components, decisions));
22050
23447
  return;
22051
23448
  case "close-help":
22052
23449
  setShowHelp(false);
@@ -22099,11 +23496,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
22099
23496
  return;
22100
23497
  }
22101
23498
  case "reject": {
22102
- const edge = focusedColumn === "main" ? focusedNestedEdge() : void 0;
22103
- if (edge) {
22104
- removeFromParentSlot(edge);
22105
- return;
22106
- }
22107
23499
  const key = focusedColumn === "added-components" ? addedComponents[safeAddedComponentsCursor]?.name : focusedRowKey();
22108
23500
  if (key) requestReject(key);
22109
23501
  return;
@@ -22111,9 +23503,6 @@ function useScopeGate({ components: loadedComponents, onConfirm, onQuit }) {
22111
23503
  case "toggle-all":
22112
23504
  decide({ type: "toggle-all" });
22113
23505
  return;
22114
- case "undo":
22115
- undoSlotRemoval();
22116
- return;
22117
23506
  case "accept-unflagged":
22118
23507
  decide({ type: "accept-unflagged" });
22119
23508
  return;
@@ -22423,47 +23812,27 @@ var init_screen7 = __esm({
22423
23812
  });
22424
23813
 
22425
23814
  // packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts
22426
- import { execFile as execFile2 } from "node:child_process";
22427
- function buildCacheCheckArgs(input) {
22428
- const args = ["__generate", "components", "--agent", input.agent, "--session", input.sessionId];
22429
- if (input.tokensPath) args.push("--tokens", input.tokensPath);
22430
- if (input.agentModel) args.push("--model", input.agentModel);
22431
- if (input.noCache) args.push("--no-cache");
22432
- for (const prompt of input.promptOverrides) args.push("--prompt", prompt);
22433
- if (input.existingEntitiesPath) args.push("--existing-entities-path", input.existingEntitiesPath);
22434
- args.push("--cache-status", "--restore-cache");
22435
- return args;
22436
- }
22437
- function parseCacheComponents(stdout) {
22438
- const line = /^cache-components=(.+)$/m.exec(stdout)?.[1];
22439
- if (!line) return [];
22440
- try {
22441
- const names = JSON.parse(line);
22442
- return Array.isArray(names) ? names.filter((name) => typeof name === "string") : [];
22443
- } catch {
22444
- return [];
22445
- }
22446
- }
22447
- async function checkGenerationCache(input, run = runLegacyCli) {
23815
+ async function checkGenerationCache(input) {
22448
23816
  if (input.noCache) return [];
22449
23817
  try {
22450
- const result = await run(buildCacheCheckArgs(input));
22451
- if (result.exitCode !== 0) return [];
22452
- return parseCacheComponents(result.stdout);
23818
+ const result = await checkGenerateComponentsCache({
23819
+ sessionId: input.sessionId,
23820
+ agent: input.agent,
23821
+ ...input.agentModel ? { agentModel: input.agentModel } : {},
23822
+ promptOverrides: input.promptOverrides,
23823
+ existingEntitiesPath: input.existingEntitiesPath,
23824
+ noCache: input.noCache,
23825
+ restoreCache: true
23826
+ });
23827
+ return result.cachedComponentNames;
22453
23828
  } catch {
22454
23829
  return [];
22455
23830
  }
22456
23831
  }
22457
- var runLegacyCli;
22458
23832
  var init_cache_check = __esm({
22459
23833
  "packages/experience-design-system-cli/src/tui/import/steps/07-scope-gate/cache-check.ts"() {
22460
23834
  "use strict";
22461
- init_legacy_cli_path();
22462
- runLegacyCli = (args) => new Promise((resolve22) => {
22463
- execFile2("node", [findLegacyCliPath(), ...args], (error, stdout, stderr) => {
22464
- resolve22({ exitCode: error?.code ? Number(error.code) : 0, stdout, stderr });
22465
- });
22466
- });
23835
+ init_src4();
22467
23836
  }
22468
23837
  });
22469
23838
 
@@ -22525,31 +23894,6 @@ var init_use_scope_gate_flow = __esm({
22525
23894
  function initialProgress2() {
22526
23895
  return { components: null, mapTokens: "idle", mapTokensEligible: null };
22527
23896
  }
22528
- function applyGenerateStderr(chunk, previous) {
22529
- let state = previous;
22530
- for (const line of chunk.split("\n")) {
22531
- const finished = PROGRESS_LINE.exec(line);
22532
- if (finished) {
22533
- state = { done: Number(finished[1]), total: Number(finished[2]), current: finished[3].trim() };
22534
- continue;
22535
- }
22536
- const started = STARTED_LINE.exec(line);
22537
- if (started) {
22538
- state = { done: state?.done ?? 0, total: Number(started[2]), current: started[3].trim() };
22539
- }
22540
- }
22541
- return state;
22542
- }
22543
- function parseGenerateResult(output, fallbackCount) {
22544
- const session = /^session=(.+)$/m.exec(output.stdout);
22545
- const count = /(\d+) components?/.exec(output.stderr);
22546
- const renamed = /^renamed-slots:\s*(\d+)$/m.exec(output.stdout);
22547
- return {
22548
- generateSessionId: session ? session[1].trim() : null,
22549
- generatedCount: count ? Number(count[1]) : fallbackCount,
22550
- renamedSlotsCount: renamed ? Number(renamed[1]) : 0
22551
- };
22552
- }
22553
23897
  function shouldRunMapTokens(counts) {
22554
23898
  return counts.mappablePropCount > 0 && counts.rawTokenCount > 0;
22555
23899
  }
@@ -22581,12 +23925,10 @@ function progressRows2(progress, agent) {
22581
23925
  }
22582
23926
  return rows;
22583
23927
  }
22584
- var PROGRESS_LINE, STARTED_LINE, capitalize;
23928
+ var capitalize;
22585
23929
  var init_logic10 = __esm({
22586
23930
  "packages/experience-design-system-cli/src/tui/import/steps/08-generation/logic.ts"() {
22587
23931
  "use strict";
22588
- PROGRESS_LINE = /^progress=generate:(\d+)\/(\d+):(.+)$/;
22589
- STARTED_LINE = /\[(\d+)\/(\d+)\]\s+(.+)/;
22590
23932
  capitalize = (name) => name.charAt(0).toUpperCase() + name.slice(1);
22591
23933
  }
22592
23934
  });
@@ -22620,33 +23962,242 @@ var init_screen8 = __esm({
22620
23962
  }
22621
23963
  });
22622
23964
 
22623
- // packages/experience-design-system-generation/dist/src/agent-names.js
22624
- var AGENT_BINARIES2;
22625
- var init_agent_names = __esm({
22626
- "packages/experience-design-system-generation/dist/src/agent-names.js"() {
23965
+ // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
23966
+ async function prepareMapTokens(input, generatedSessionId) {
23967
+ const db = openPipelineDb();
23968
+ try {
23969
+ if (input.tokenSessionId && input.tokenSessionId !== generatedSessionId) {
23970
+ copyTokensFromCache(db, input.tokenSessionId, generatedSessionId);
23971
+ } else if (!input.tokenSessionId && input.tokensPath) {
23972
+ const tokens = await readTokensFromPath2({ flag: "tokens", path: input.tokensPath });
23973
+ storeDtcgTokens(db, generatedSessionId, [], tokens);
23974
+ }
23975
+ const mappablePropCount = loadCDFComponents(db, generatedSessionId).reduce(
23976
+ (count, { entry }) => count + Object.values(entry.$properties).filter((prop) => prop.$type === "token" && prop.$category === "design").length,
23977
+ 0
23978
+ );
23979
+ const rawTokenCount = getDtcgTokensForSession(db, generatedSessionId).tokens.length;
23980
+ return {
23981
+ eligible: shouldRunMapTokens({ mappablePropCount, rawTokenCount }),
23982
+ mappablePropCount,
23983
+ rawTokenCount
23984
+ };
23985
+ } finally {
23986
+ db.close();
23987
+ }
23988
+ }
23989
+ var init_map_tokens = __esm({
23990
+ "packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts"() {
22627
23991
  "use strict";
22628
- AGENT_BINARIES2 = {
22629
- claude: "claude",
22630
- codex: "codex",
22631
- opencode: "opencode",
22632
- cursor: "cursor-agent",
22633
- copilot: "copilot"
23992
+ init_src4();
23993
+ init_logic10();
23994
+ }
23995
+ });
23996
+
23997
+ // packages/experience-design-system-cli/src/tui/import/steps/08-generation/save-decisions.ts
23998
+ async function saveDecisions(input) {
23999
+ const db = openPipelineDb();
24000
+ try {
24001
+ applyScopeDecisions(db, input.sessionId, input.decisions);
24002
+ await writeScopeDecisionsSnapshot(db, input.sessionId, input.decisions);
24003
+ } finally {
24004
+ db.close();
24005
+ }
24006
+ }
24007
+ var init_save_decisions = __esm({
24008
+ "packages/experience-design-system-cli/src/tui/import/steps/08-generation/save-decisions.ts"() {
24009
+ "use strict";
24010
+ init_src4();
24011
+ }
24012
+ });
24013
+
24014
+ // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
24015
+ import { resolve as resolve23 } from "node:path";
24016
+ async function runGeneration(input, onProgress, deps = realDeps3) {
24017
+ let progress = { components: null, mapTokens: "idle", mapTokensEligible: null };
24018
+ const update = (change) => {
24019
+ progress = { ...progress, ...change };
24020
+ onProgress(progress);
24021
+ };
24022
+ const accepted = input.decisions.accepted;
24023
+ const handedOverNames = await input.cachedNames.catch(() => []);
24024
+ try {
24025
+ await deps.saveDecisions({ sessionId: input.sessionId, decisions: input.decisions });
24026
+ } catch (error) {
24027
+ return fail2("save decisions", errorMessage3(error));
24028
+ }
24029
+ if (accepted.length === 0) return { ok: true, generation: { route: "push", acceptedCount: 0 } };
24030
+ const auth = await deps.checkAgentAuth(input.agent);
24031
+ if (auth === "not-found" || auth === "unauthenticated") {
24032
+ return fail2(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
24033
+ }
24034
+ let generated;
24035
+ try {
24036
+ generated = await deps.runGenerate({
24037
+ sessionId: input.sessionId,
24038
+ agent: input.agent,
24039
+ ...input.agentModel ? { agentModel: input.agentModel } : {},
24040
+ promptOverrides: appendGeneratePromptOverride(input),
24041
+ noCache: input.noCache,
24042
+ existingEntitiesPath: input.existingEntitiesPath,
24043
+ precomputedCachedNames: new Set(handedOverNames),
24044
+ onProgress: (event) => update({ components: applyProgressEvent2(event, progress.components, accepted.length) })
24045
+ });
24046
+ } catch (error) {
24047
+ return fail2("generate components", errorMessage3(error));
24048
+ }
24049
+ if (generated.emptySession) return fail2("generate components", "no raw components in session");
24050
+ if (!generated.allOk) {
24051
+ const firstFailure = generated.results.find((r) => r.failed);
24052
+ return fail2("generate components", firstFailure?.error ?? "unknown error");
24053
+ }
24054
+ let plan;
24055
+ try {
24056
+ plan = await deps.prepareMapTokens(input, input.sessionId);
24057
+ } catch (error) {
24058
+ return fail2("map tokens", errorMessage3(error));
24059
+ }
24060
+ update({ mapTokensEligible: plan.eligible });
24061
+ if (plan.eligible) {
24062
+ update({ mapTokens: "running" });
24063
+ try {
24064
+ const mapTokensOptions = await buildMapTokensOptions(input);
24065
+ await deps.runMapTokens({
24066
+ sessionId: input.sessionId,
24067
+ agent: input.agent,
24068
+ ...input.agentModel ? { model: input.agentModel } : {},
24069
+ cache: !input.noCache,
24070
+ ...mapTokensOptions
24071
+ });
24072
+ } catch (error) {
24073
+ const message = error instanceof MapTokensRunFailure ? error.message : error instanceof Error ? error.message : String(error);
24074
+ return fail2("map tokens", message);
24075
+ }
24076
+ }
24077
+ update({ mapTokens: "complete" });
24078
+ const generatedCount = generated.results.filter((r) => !r.failed).length;
24079
+ return {
24080
+ ok: true,
24081
+ generation: {
24082
+ route: "review",
24083
+ sessionId: input.sessionId,
24084
+ acceptedCount: accepted.length,
24085
+ generatedCount,
24086
+ mapTokensEligible: plan.eligible
24087
+ }
24088
+ };
24089
+ }
24090
+ async function buildMapTokensOptions(input) {
24091
+ const { overrides: parsed, errors } = parsePromptOverrides(input.promptOverrides);
24092
+ if (errors.length > 0) throw new Error(errors.join("; "));
24093
+ const mapOverride = parsed.get("map-tokens");
24094
+ const prompt = {};
24095
+ if (mapOverride?.kind === "text") prompt.skillContentOverride = mapOverride.value;
24096
+ if (mapOverride?.kind === "path") {
24097
+ await resolvePromptOverride(mapOverride);
24098
+ prompt.skillPathOverride = resolve23(mapOverride.value);
24099
+ }
24100
+ if (input.existingEntitiesPath) {
24101
+ const entities = await readExistingContentfulEntitiesFromSession({ path: input.existingEntitiesPath });
24102
+ if (entities) return { ...prompt, existingEntitiesInline: JSON.stringify(summarizeForMapTokens({ entities })) };
24103
+ }
24104
+ return prompt;
24105
+ }
24106
+ function appendGeneratePromptOverride(input) {
24107
+ if (!input.generatePromptPath) return input.promptOverrides;
24108
+ const already = input.promptOverrides.some((override) => override.startsWith("generate="));
24109
+ if (already) return input.promptOverrides;
24110
+ return [...input.promptOverrides, `generate=${input.generatePromptPath}`];
24111
+ }
24112
+ function applyProgressEvent2(event, previous, total) {
24113
+ if (event.kind === "component:started") {
24114
+ return { done: previous?.done ?? 0, total: event.total || total, current: event.name };
24115
+ }
24116
+ if (event.kind === "component:completed" || event.kind === "component:failed" || event.kind === "component:cached") {
24117
+ return { done: (previous?.done ?? 0) + 1, total: event.total || total, current: event.name };
24118
+ }
24119
+ return previous;
24120
+ }
24121
+ var realDeps3, fail2, errorMessage3;
24122
+ var init_run2 = __esm({
24123
+ "packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts"() {
24124
+ "use strict";
24125
+ init_src4();
24126
+ init_logic9();
24127
+ init_map_tokens();
24128
+ init_save_decisions();
24129
+ realDeps3 = {
24130
+ checkAgentAuth,
24131
+ saveDecisions,
24132
+ runGenerate: runGenerateComponentsSession,
24133
+ runMapTokens,
24134
+ prepareMapTokens
22634
24135
  };
24136
+ fail2 = (step, message) => ({ ok: false, step, message });
24137
+ errorMessage3 = (error) => error instanceof Error ? error.message : String(error);
22635
24138
  }
22636
24139
  });
22637
24140
 
22638
- // packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js
22639
- var init_validate_generation_request = __esm({
22640
- "packages/experience-design-system-generation/dist/src/controller/helpers/validate-generation-request.js"() {
24141
+ // packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts
24142
+ import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
24143
+ function useGeneration(input) {
24144
+ const [state, setState] = useState14();
24145
+ const current = useRef6();
24146
+ useEffect9(() => {
24147
+ current.current = input;
24148
+ if (!input) {
24149
+ setState(void 0);
24150
+ return;
24151
+ }
24152
+ setState({ status: "running", progress: initialProgress2() });
24153
+ void runGeneration(input, (progress) => {
24154
+ if (current.current === input) setState({ status: "running", progress });
24155
+ }).then((result) => {
24156
+ if (current.current === input) setState({ status: "done", result });
24157
+ });
24158
+ return () => {
24159
+ if (current.current === input) current.current = void 0;
24160
+ };
24161
+ }, [input]);
24162
+ return state;
24163
+ }
24164
+ var init_use_generation = __esm({
24165
+ "packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts"() {
22641
24166
  "use strict";
22642
- init_agent_names();
24167
+ init_logic10();
24168
+ init_run2();
22643
24169
  }
22644
24170
  });
22645
24171
 
22646
- // packages/experience-design-system-generation/dist/src/services/prompts/helpers/resolve-skill-file.js
22647
- var init_resolve_skill_file = __esm({
22648
- "packages/experience-design-system-generation/dist/src/services/prompts/helpers/resolve-skill-file.js"() {
24172
+ // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
24173
+ import { join as join22 } from "node:path";
24174
+ function buildFlowStart(input) {
24175
+ const { extraction, handoff, saved, generatePromptPath } = input;
24176
+ const credentials = extraction.credentials ?? {
24177
+ spaceId: saved?.spaceId ?? "",
24178
+ environmentId: saved?.environmentId ?? "",
24179
+ cmaToken: saved?.cmaToken ?? "",
24180
+ host: saved?.host ?? ""
24181
+ };
24182
+ return {
24183
+ handoff,
24184
+ agent: extraction.agent,
24185
+ projectPath: extraction.projectPath,
24186
+ outDir: extraction.projectPath ? join22(extraction.projectPath, ".contentful") : "",
24187
+ rawTokensPath: extraction.rawTokensPath,
24188
+ credentials: {
24189
+ spaceId: credentials.spaceId,
24190
+ environmentId: credentials.environmentId || "master",
24191
+ cmaToken: credentials.cmaToken,
24192
+ host: toConfiguredHost2(credentials.host) ?? DEFAULT_CONFIGURED_HOST
24193
+ },
24194
+ ...generatePromptPath ? { generatePromptPath } : {}
24195
+ };
24196
+ }
24197
+ var init_build_flow_start = __esm({
24198
+ "packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts"() {
22649
24199
  "use strict";
24200
+ init_src4();
22650
24201
  }
22651
24202
  });
22652
24203
 
@@ -22939,628 +24490,92 @@ function validateSlotReferences2(components) {
22939
24490
  }
22940
24491
  }
22941
24492
  return errors;
22942
- }
22943
- function setAtPath(root, dottedPath, value) {
22944
- const segments = dottedPath.split(".");
22945
- let cursor = root;
22946
- for (let i = 0; i < segments.length - 1; i += 1) {
22947
- const segment = segments[i];
22948
- const next = cursor[segment];
22949
- if (typeof next !== "object" || next === null) {
22950
- cursor[segment] = {};
22951
- }
22952
- cursor = cursor[segment];
22953
- }
22954
- cursor[segments[segments.length - 1]] = value;
22955
- }
22956
- var COLLISION_LEAF_KEY;
22957
- var init_build2 = __esm({
22958
- "packages/experience-design-system-types/dist/src/cdf/build.js"() {
22959
- "use strict";
22960
- init_schema2();
22961
- COLLISION_LEAF_KEY = "default";
22962
- }
22963
- });
22964
-
22965
- // packages/experience-design-system-types/dist/src/cdf/index.js
22966
- var init_cdf2 = __esm({
22967
- "packages/experience-design-system-types/dist/src/cdf/index.js"() {
22968
- "use strict";
22969
- init_validate5();
22970
- init_schema2();
22971
- init_vocabularies2();
22972
- init_types7();
22973
- init_build2();
22974
- }
22975
- });
22976
-
22977
- // packages/experience-design-system-types/dist/src/dtcg/types.js
22978
- import * as z4 from "zod/mini";
22979
- var DTCGTokenSchema2;
22980
- var init_types8 = __esm({
22981
- "packages/experience-design-system-types/dist/src/dtcg/types.js"() {
22982
- "use strict";
22983
- init_token_types2();
22984
- DTCGTokenSchema2 = z4.strictObject({
22985
- path: z4.string(),
22986
- $type: z4.enum(DESIGN_TOKEN_TYPES2),
22987
- $value: z4.unknown(),
22988
- $description: z4.optional(z4.string())
22989
- });
22990
- }
22991
- });
22992
-
22993
- // packages/experience-design-system-types/dist/src/dtcg/utils.js
22994
- var init_utils = __esm({
22995
- "packages/experience-design-system-types/dist/src/dtcg/utils.js"() {
22996
- "use strict";
22997
- }
22998
- });
22999
-
23000
- // packages/experience-design-system-types/dist/src/dtcg/validate.js
23001
- var TOKEN_TYPE_SET4;
23002
- var init_validate6 = __esm({
23003
- "packages/experience-design-system-types/dist/src/dtcg/validate.js"() {
23004
- "use strict";
23005
- init_token_types2();
23006
- init_utils();
23007
- TOKEN_TYPE_SET4 = new Set(DESIGN_TOKEN_TYPES2);
23008
- }
23009
- });
23010
-
23011
- // packages/experience-design-system-types/dist/src/dtcg/index.js
23012
- var init_dtcg2 = __esm({
23013
- "packages/experience-design-system-types/dist/src/dtcg/index.js"() {
23014
- "use strict";
23015
- init_token_types2();
23016
- init_types8();
23017
- init_utils();
23018
- init_validate6();
23019
- }
23020
- });
23021
-
23022
- // packages/experience-design-system-types/dist/src/index.js
23023
- var init_src5 = __esm({
23024
- "packages/experience-design-system-types/dist/src/index.js"() {
23025
- "use strict";
23026
- init_cdf2();
23027
- init_dtcg2();
23028
- }
23029
- });
23030
-
23031
- // packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js
23032
- var init_format_token_candidates2 = __esm({
23033
- "packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-token-candidates.js"() {
23034
- "use strict";
23035
- init_src5();
23036
- }
23037
- });
23038
-
23039
- // packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-source-refs.js
23040
- var init_format_source_refs = __esm({
23041
- "packages/experience-design-system-generation/dist/src/services/prompts/helpers/format-source-refs.js"() {
23042
- "use strict";
23043
- init_format_token_candidates2();
23044
- }
23045
- });
23046
-
23047
- // packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js
23048
- var init_build_skill_preambles = __esm({
23049
- "packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-skill-preambles.js"() {
23050
- "use strict";
23051
- }
23052
- });
23053
-
23054
- // packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-preamble.js
23055
- var init_build_preamble = __esm({
23056
- "packages/experience-design-system-generation/dist/src/services/prompts/helpers/build-preamble.js"() {
23057
- "use strict";
23058
- init_format_token_candidates2();
23059
- init_format_source_refs();
23060
- init_build_skill_preambles();
23061
- }
23062
- });
23063
-
23064
- // packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js
23065
- var init_build_prompt2 = __esm({
23066
- "packages/experience-design-system-generation/dist/src/services/prompts/build-prompt.js"() {
23067
- "use strict";
23068
- init_resolve_skill_file();
23069
- init_build_preamble();
23070
- init_resolve_skill_file();
23071
- }
23072
- });
23073
-
23074
- // packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js
23075
- var init_execute_generation_orchestrator = __esm({
23076
- "packages/experience-design-system-generation/dist/src/orchestrator/execute-generation-orchestrator.js"() {
23077
- "use strict";
23078
- init_build_prompt2();
23079
- }
23080
- });
23081
-
23082
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js
23083
- function resolveAgentBinary(agent) {
23084
- const envKey = `EDS_AGENT_BINARY_${agent.toUpperCase()}`;
23085
- const override = process.env[envKey];
23086
- if (override && override.trim())
23087
- return override.trim();
23088
- return AGENT_BINARIES2[agent];
23089
- }
23090
- var init_resolve_agent_binary = __esm({
23091
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/resolve-agent-binary.js"() {
23092
- "use strict";
23093
- init_agent_names();
23094
- }
23095
- });
23096
-
23097
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js
23098
- var init_build_agent_args2 = __esm({
23099
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/build-agent-args.js"() {
23100
- "use strict";
23101
- }
23102
- });
23103
-
23104
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/describe-agent-failure.js
23105
- var init_describe_agent_failure2 = __esm({
23106
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/describe-agent-failure.js"() {
23107
- "use strict";
23108
- }
23109
- });
23110
-
23111
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/extract-sentinel-output.js
23112
- var init_extract_sentinel_output2 = __esm({
23113
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/extract-sentinel-output.js"() {
23114
- "use strict";
23115
- }
23116
- });
23117
-
23118
- // packages/experience-design-system-generation/dist/src/services/agent/run-agent.js
23119
- var init_run_agent2 = __esm({
23120
- "packages/experience-design-system-generation/dist/src/services/agent/run-agent.js"() {
23121
- "use strict";
23122
- init_resolve_agent_binary();
23123
- init_build_agent_args2();
23124
- init_describe_agent_failure2();
23125
- init_extract_sentinel_output2();
23126
- }
23127
- });
23128
-
23129
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/check-claude-auth.js
23130
- import { spawn as spawn5 } from "node:child_process";
23131
- function checkClaudeAuth(binary) {
23132
- return new Promise((resolve22) => {
23133
- const child = spawn5(binary, ["auth", "status", "--json"], {
23134
- stdio: ["ignore", "pipe", "pipe"]
23135
- });
23136
- let stdout = "";
23137
- let done = false;
23138
- const timer = setTimeout(() => {
23139
- if (!done) {
23140
- done = true;
23141
- child.kill("SIGTERM");
23142
- resolve22("unauthenticated");
23143
- }
23144
- }, 5e3);
23145
- child.stdout?.on("data", (chunk) => {
23146
- stdout += chunk.toString();
23147
- });
23148
- child.on("close", (code) => {
23149
- if (done)
23150
- return;
23151
- done = true;
23152
- clearTimeout(timer);
23153
- if (code !== 0) {
23154
- resolve22("unauthenticated");
23155
- return;
23156
- }
23157
- try {
23158
- const status = JSON.parse(stdout);
23159
- resolve22(status.loggedIn ? "ok" : "unauthenticated");
23160
- } catch {
23161
- resolve22("unauthenticated");
23162
- }
23163
- });
23164
- });
23165
- }
23166
- var init_check_claude_auth = __esm({
23167
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/check-claude-auth.js"() {
23168
- "use strict";
23169
- }
23170
- });
23171
-
23172
- // packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js
23173
- import { spawn as spawn6 } from "node:child_process";
23174
- async function checkAgentAuth2(agent) {
23175
- const binary = resolveAgentBinary(agent);
23176
- const binaryExists2 = await new Promise((resolve22) => {
23177
- if (binary.startsWith("/")) {
23178
- import("node:fs/promises").then((fs) => fs.access(binary).then(() => resolve22(true), () => resolve22(false)));
23179
- return;
23180
- }
23181
- const child = spawn6(process.platform === "win32" ? "where" : "which", [binary], { stdio: "ignore" });
23182
- child.on("close", (code) => resolve22(code === 0));
23183
- });
23184
- if (!binaryExists2)
23185
- return "not-found";
23186
- if (agent !== "claude")
23187
- return "ok";
23188
- return checkClaudeAuth(binary);
23189
- }
23190
- var init_check_agent_auth2 = __esm({
23191
- "packages/experience-design-system-generation/dist/src/services/agent/helpers/check-agent-auth.js"() {
23192
- "use strict";
23193
- init_resolve_agent_binary();
23194
- init_check_claude_auth();
23195
- }
23196
- });
23197
-
23198
- // packages/experience-design-system-generation/dist/src/services/agent/local-cli-agent-invoker.js
23199
- var init_local_cli_agent_invoker = __esm({
23200
- "packages/experience-design-system-generation/dist/src/services/agent/local-cli-agent-invoker.js"() {
23201
- "use strict";
23202
- init_run_agent2();
23203
- init_check_agent_auth2();
23204
- }
23205
- });
23206
-
23207
- // packages/experience-design-system-generation/dist/src/controller/create-generation-endpoint.js
23208
- var init_create_generation_endpoint = __esm({
23209
- "packages/experience-design-system-generation/dist/src/controller/create-generation-endpoint.js"() {
23210
- "use strict";
23211
- init_validate_generation_request();
23212
- init_execute_generation_orchestrator();
23213
- init_local_cli_agent_invoker();
23214
- }
23215
- });
23216
-
23217
- // packages/experience-design-system-generation/dist/src/services/parsing/helpers/read-tool-call-objects.js
23218
- var init_read_tool_call_objects2 = __esm({
23219
- "packages/experience-design-system-generation/dist/src/services/parsing/helpers/read-tool-call-objects.js"() {
23220
- "use strict";
23221
- }
23222
- });
23223
-
23224
- // packages/experience-design-system-generation/dist/src/services/parsing/parse-prop-tool-calls.js
23225
- var init_parse_prop_tool_calls = __esm({
23226
- "packages/experience-design-system-generation/dist/src/services/parsing/parse-prop-tool-calls.js"() {
23227
- "use strict";
23228
- init_read_tool_call_objects2();
23229
- }
23230
- });
23231
-
23232
- // packages/experience-design-system-generation/dist/src/services/parsing/parse-select-tool-calls.js
23233
- var init_parse_select_tool_calls2 = __esm({
23234
- "packages/experience-design-system-generation/dist/src/services/parsing/parse-select-tool-calls.js"() {
23235
- "use strict";
23236
- init_read_tool_call_objects2();
23237
- }
23238
- });
23239
-
23240
- // packages/experience-design-system-generation/dist/src/services/parsing/parse-token-tool-calls.js
23241
- var init_parse_token_tool_calls2 = __esm({
23242
- "packages/experience-design-system-generation/dist/src/services/parsing/parse-token-tool-calls.js"() {
23243
- "use strict";
23244
- init_read_tool_call_objects2();
23245
- }
23246
- });
23247
-
23248
- // packages/experience-design-system-generation/dist/src/services/parsing/parse-map-token-tool-calls.js
23249
- var init_parse_map_token_tool_calls = __esm({
23250
- "packages/experience-design-system-generation/dist/src/services/parsing/parse-map-token-tool-calls.js"() {
23251
- "use strict";
23252
- }
23253
- });
23254
-
23255
- // packages/experience-design-system-generation/dist/src/progress.js
23256
- var init_progress = __esm({
23257
- "packages/experience-design-system-generation/dist/src/progress.js"() {
23258
- "use strict";
23259
- }
23260
- });
23261
-
23262
- // packages/experience-design-system-generation/dist/src/index.js
23263
- var init_src6 = __esm({
23264
- "packages/experience-design-system-generation/dist/src/index.js"() {
23265
- "use strict";
23266
- init_agent_names();
23267
- init_create_generation_endpoint();
23268
- init_execute_generation_orchestrator();
23269
- init_build_agent_args2();
23270
- init_resolve_agent_binary();
23271
- init_check_agent_auth2();
23272
- init_run_agent2();
23273
- init_parse_prop_tool_calls();
23274
- init_parse_select_tool_calls2();
23275
- init_parse_token_tool_calls2();
23276
- init_parse_map_token_tool_calls();
23277
- init_build_prompt2();
23278
- init_progress();
23279
- init_local_cli_agent_invoker();
23280
- }
23281
- });
23282
-
23283
- // packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts
23284
- async function prepareMapTokens(input, generatedSessionId) {
23285
- const db = openPipelineDb();
23286
- try {
23287
- if (input.tokenSessionId && input.tokenSessionId !== generatedSessionId) {
23288
- copyTokensFromCache(db, input.tokenSessionId, generatedSessionId);
23289
- } else if (!input.tokenSessionId && input.tokensPath) {
23290
- const tokens = await readTokensFromPath2({ flag: "tokens", path: input.tokensPath });
23291
- storeDtcgTokens(db, generatedSessionId, [], tokens);
23292
- }
23293
- const mappablePropCount = loadCDFComponents(db, generatedSessionId).reduce(
23294
- (count, { entry }) => count + Object.values(entry.$properties).filter((prop) => prop.$type === "token" && prop.$category === "design").length,
23295
- 0
23296
- );
23297
- const rawTokenCount = getDtcgTokensForSession(db, generatedSessionId).tokens.length;
23298
- return {
23299
- eligible: shouldRunMapTokens({ mappablePropCount, rawTokenCount }),
23300
- mappablePropCount,
23301
- rawTokenCount
23302
- };
23303
- } finally {
23304
- db.close();
24493
+ }
24494
+ function setAtPath(root, dottedPath, value) {
24495
+ const segments = dottedPath.split(".");
24496
+ let cursor = root;
24497
+ for (let i = 0; i < segments.length - 1; i += 1) {
24498
+ const segment = segments[i];
24499
+ const next = cursor[segment];
24500
+ if (typeof next !== "object" || next === null) {
24501
+ cursor[segment] = {};
24502
+ }
24503
+ cursor = cursor[segment];
23305
24504
  }
24505
+ cursor[segments[segments.length - 1]] = value;
23306
24506
  }
23307
- var init_map_tokens = __esm({
23308
- "packages/experience-design-system-cli/src/tui/import/steps/08-generation/map-tokens.ts"() {
24507
+ var COLLISION_LEAF_KEY;
24508
+ var init_build2 = __esm({
24509
+ "packages/experience-design-system-types/dist/src/cdf/build.js"() {
23309
24510
  "use strict";
23310
- init_src4();
23311
- init_logic10();
24511
+ init_schema2();
24512
+ COLLISION_LEAF_KEY = "default";
23312
24513
  }
23313
24514
  });
23314
24515
 
23315
- // packages/experience-design-system-cli/src/tui/import/steps/08-generation/processes.ts
23316
- import { execFile as execFile3, spawn as spawn7 } from "node:child_process";
23317
- function buildGenerateArgs(cliPath, command) {
23318
- const args = [cliPath, "__generate", "components", "--agent", command.agent, "--session", command.sessionId];
23319
- if (command.tokensPath) args.push("--tokens", command.tokensPath);
23320
- if (command.agentModel) args.push("--model", command.agentModel);
23321
- if (command.noCache) args.push("--no-cache");
23322
- if (command.generatePromptPath) args.push("--generate-prompt-path", command.generatePromptPath);
23323
- for (const prompt of command.promptOverrides) args.push("--prompt", prompt);
23324
- if (command.existingEntitiesPath) args.push("--existing-entities-path", command.existingEntitiesPath);
23325
- if (command.cachedComponents.length > 0) args.push("--cached-components", JSON.stringify(command.cachedComponents));
23326
- return args;
23327
- }
23328
- function buildMapTokensArgs(command) {
23329
- const args = ["map", "tokens", "--session", command.sessionId, "--agent", command.agent];
23330
- if (command.agentModel) args.push("--model", command.agentModel);
23331
- if (command.noCache) args.push("--no-cache");
23332
- for (const prompt of command.promptOverrides) args.push("--prompt", prompt);
23333
- if (command.existingEntitiesPath) args.push("--existing-entities-path", command.existingEntitiesPath);
23334
- return args;
23335
- }
23336
- function spawnGenerate(command, handlers) {
23337
- return new Promise((resolve22) => {
23338
- const child = spawn7("node", buildGenerateArgs(findLegacyCliPath(), command));
23339
- let stdout = "";
23340
- let stderr = "";
23341
- child.stdout.on("data", (data) => {
23342
- stdout += String(data);
23343
- });
23344
- child.stderr.on("data", (data) => {
23345
- const chunk = String(data);
23346
- stderr += chunk;
23347
- handlers.onStderr(chunk);
23348
- });
23349
- child.on("error", (error) => resolve22({ exitCode: 1, stdout, stderr: stderr + error.message }));
23350
- child.on("close", (code) => resolve22({ exitCode: code ?? 0, stdout, stderr }));
23351
- });
23352
- }
23353
- function runMapTokens2(command) {
23354
- return new Promise((resolve22) => {
23355
- execFile3("node", [findLegacyCliPath(), ...buildMapTokensArgs(command)], (error, stdout, stderr) => {
23356
- resolve22({ exitCode: error?.code ? Number(error.code) : 0, stdout, stderr });
23357
- });
23358
- });
23359
- }
23360
- var init_processes = __esm({
23361
- "packages/experience-design-system-cli/src/tui/import/steps/08-generation/processes.ts"() {
24516
+ // packages/experience-design-system-types/dist/src/cdf/index.js
24517
+ var init_cdf2 = __esm({
24518
+ "packages/experience-design-system-types/dist/src/cdf/index.js"() {
23362
24519
  "use strict";
23363
- init_legacy_cli_path();
24520
+ init_validate5();
24521
+ init_schema2();
24522
+ init_vocabularies2();
24523
+ init_types7();
24524
+ init_build2();
23364
24525
  }
23365
24526
  });
23366
24527
 
23367
- // packages/experience-design-system-cli/src/tui/import/steps/08-generation/save-decisions.ts
23368
- async function saveDecisions(input) {
23369
- const db = openPipelineDb();
23370
- try {
23371
- applyScopeDecisions(db, input.sessionId, input.decisions);
23372
- await writeScopeDecisionsSnapshot(db, input.sessionId, input.decisions);
23373
- } finally {
23374
- db.close();
23375
- }
23376
- }
23377
- var init_save_decisions = __esm({
23378
- "packages/experience-design-system-cli/src/tui/import/steps/08-generation/save-decisions.ts"() {
24528
+ // packages/experience-design-system-types/dist/src/dtcg/types.js
24529
+ import * as z4 from "zod/mini";
24530
+ var DTCGTokenSchema2;
24531
+ var init_types8 = __esm({
24532
+ "packages/experience-design-system-types/dist/src/dtcg/types.js"() {
23379
24533
  "use strict";
23380
- init_src4();
24534
+ init_token_types2();
24535
+ DTCGTokenSchema2 = z4.strictObject({
24536
+ path: z4.string(),
24537
+ $type: z4.enum(DESIGN_TOKEN_TYPES2),
24538
+ $value: z4.unknown(),
24539
+ $description: z4.optional(z4.string())
24540
+ });
23381
24541
  }
23382
24542
  });
23383
24543
 
23384
- // packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts
23385
- async function runGeneration(input, onProgress, deps = realDeps3) {
23386
- let progress = initialProgress2();
23387
- const update = (change) => {
23388
- progress = { ...progress, ...change };
23389
- onProgress(progress);
23390
- };
23391
- const accepted = input.decisions.accepted;
23392
- const handedOverNames = await input.cachedNames.catch(() => []);
23393
- try {
23394
- await deps.saveDecisions({ sessionId: input.sessionId, decisions: input.decisions });
23395
- } catch (error) {
23396
- return fail2("save decisions", errorMessage3(error));
23397
- }
23398
- if (accepted.length === 0) return { ok: true, generation: { route: "push", acceptedCount: 0 } };
23399
- const auth = await deps.checkAgentAuth(input.agent);
23400
- if (auth === "not-found" || auth === "unauthenticated") {
23401
- return fail2(`${input.agent} auth check`, agentAuthMessage(input.agent, auth));
23402
- }
23403
- const acceptedSet = new Set(accepted);
23404
- let cachedNames = handedOverNames;
23405
- let cacheHit = !input.noCache && accepted.length > 0 && accepted.every((name) => cachedNames.includes(name));
23406
- if (!cacheHit && !input.noCache && accepted.length > 0) {
23407
- const fresh = await deps.checkCache(cacheCheckFor(input));
23408
- cachedNames = fresh.filter((name) => acceptedSet.has(name));
23409
- cacheHit = accepted.every((name) => cachedNames.includes(name));
23410
- }
23411
- let generatedSessionId = input.sessionId;
23412
- let generatedCount = accepted.length;
23413
- if (!cacheHit) {
23414
- const result = await deps.spawnGenerate(
23415
- {
23416
- sessionId: input.sessionId,
23417
- tokensPath: input.tokensPath,
23418
- agent: input.agent,
23419
- ...input.agentModel ? { agentModel: input.agentModel } : {},
23420
- promptOverrides: input.promptOverrides,
23421
- ...input.generatePromptPath ? { generatePromptPath: input.generatePromptPath } : {},
23422
- noCache: input.noCache,
23423
- existingEntitiesPath: input.existingEntitiesPath,
23424
- cachedComponents: cachedNames
23425
- },
23426
- {
23427
- onStderr: (chunk) => {
23428
- const components = applyGenerateStderr(chunk, progress.components);
23429
- if (components !== progress.components) update({ components });
23430
- }
23431
- }
23432
- );
23433
- if (result.exitCode !== 0) return fail2("generate components", result.stderr.trim() || "Unknown error");
23434
- const parsed = parseGenerateResult(result, accepted.length);
23435
- generatedSessionId = parsed.generateSessionId ?? input.sessionId;
23436
- generatedCount = parsed.generatedCount;
23437
- }
23438
- let plan;
23439
- try {
23440
- plan = await deps.prepareMapTokens(input, generatedSessionId);
23441
- } catch (error) {
23442
- return fail2("map tokens", errorMessage3(error));
23443
- }
23444
- update({ mapTokensEligible: plan.eligible });
23445
- if (plan.eligible) {
23446
- update({ mapTokens: "running" });
23447
- const mapped = await deps.runMapTokens({
23448
- sessionId: generatedSessionId,
23449
- agent: input.agent,
23450
- ...input.agentModel ? { agentModel: input.agentModel } : {},
23451
- promptOverrides: input.promptOverrides,
23452
- noCache: input.noCache,
23453
- existingEntitiesPath: input.existingEntitiesPath
23454
- });
23455
- if (mapped.exitCode !== 0) return fail2("map tokens", mapped.stderr.trim() || "Unknown error");
24544
+ // packages/experience-design-system-types/dist/src/dtcg/utils.js
24545
+ var init_utils = __esm({
24546
+ "packages/experience-design-system-types/dist/src/dtcg/utils.js"() {
24547
+ "use strict";
23456
24548
  }
23457
- update({ mapTokens: "complete" });
23458
- return {
23459
- ok: true,
23460
- generation: {
23461
- route: "review",
23462
- sessionId: generatedSessionId,
23463
- acceptedCount: accepted.length,
23464
- generatedCount,
23465
- mapTokensEligible: plan.eligible
23466
- }
23467
- };
23468
- }
23469
- function cacheCheckFor(input) {
23470
- return {
23471
- sessionId: input.sessionId,
23472
- tokensPath: input.tokensPath,
23473
- agent: input.agent,
23474
- ...input.agentModel ? { agentModel: input.agentModel } : {},
23475
- promptOverrides: input.promptOverrides,
23476
- existingEntitiesPath: input.existingEntitiesPath,
23477
- noCache: input.noCache
23478
- };
23479
- }
23480
- var realDeps3, fail2, errorMessage3;
23481
- var init_run2 = __esm({
23482
- "packages/experience-design-system-cli/src/tui/import/steps/08-generation/run.ts"() {
24549
+ });
24550
+
24551
+ // packages/experience-design-system-types/dist/src/dtcg/validate.js
24552
+ var TOKEN_TYPE_SET4;
24553
+ var init_validate6 = __esm({
24554
+ "packages/experience-design-system-types/dist/src/dtcg/validate.js"() {
23483
24555
  "use strict";
23484
- init_src6();
23485
- init_logic9();
23486
- init_cache_check();
23487
- init_logic10();
23488
- init_map_tokens();
23489
- init_processes();
23490
- init_save_decisions();
23491
- realDeps3 = {
23492
- checkAgentAuth: checkAgentAuth2,
23493
- saveDecisions,
23494
- checkCache: checkGenerationCache,
23495
- spawnGenerate,
23496
- prepareMapTokens,
23497
- runMapTokens: runMapTokens2
23498
- };
23499
- fail2 = (step, message) => ({ ok: false, step, message });
23500
- errorMessage3 = (error) => error instanceof Error ? error.message : String(error);
24556
+ init_token_types2();
24557
+ init_utils();
24558
+ TOKEN_TYPE_SET4 = new Set(DESIGN_TOKEN_TYPES2);
23501
24559
  }
23502
24560
  });
23503
24561
 
23504
- // packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts
23505
- import { useEffect as useEffect9, useRef as useRef6, useState as useState14 } from "react";
23506
- function useGeneration(input) {
23507
- const [state, setState] = useState14();
23508
- const current = useRef6();
23509
- useEffect9(() => {
23510
- current.current = input;
23511
- if (!input) {
23512
- setState(void 0);
23513
- return;
23514
- }
23515
- setState({ status: "running", progress: initialProgress2() });
23516
- void runGeneration(input, (progress) => {
23517
- if (current.current === input) setState({ status: "running", progress });
23518
- }).then((result) => {
23519
- if (current.current === input) setState({ status: "done", result });
23520
- });
23521
- return () => {
23522
- if (current.current === input) current.current = void 0;
23523
- };
23524
- }, [input]);
23525
- return state;
23526
- }
23527
- var init_use_generation = __esm({
23528
- "packages/experience-design-system-cli/src/tui/import/steps/08-generation/use-generation.ts"() {
24562
+ // packages/experience-design-system-types/dist/src/dtcg/index.js
24563
+ var init_dtcg2 = __esm({
24564
+ "packages/experience-design-system-types/dist/src/dtcg/index.js"() {
23529
24565
  "use strict";
23530
- init_logic10();
23531
- init_run2();
24566
+ init_token_types2();
24567
+ init_types8();
24568
+ init_utils();
24569
+ init_validate6();
23532
24570
  }
23533
24571
  });
23534
24572
 
23535
- // packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts
23536
- import { join as join22 } from "node:path";
23537
- function buildFlowStart(input) {
23538
- const { extraction, handoff, saved, generatePromptPath } = input;
23539
- const credentials = extraction.credentials ?? {
23540
- spaceId: saved?.spaceId ?? "",
23541
- environmentId: saved?.environmentId ?? "",
23542
- cmaToken: saved?.cmaToken ?? "",
23543
- host: saved?.host ?? ""
23544
- };
23545
- return {
23546
- handoff,
23547
- agent: extraction.agent,
23548
- projectPath: extraction.projectPath,
23549
- outDir: extraction.projectPath ? join22(extraction.projectPath, ".contentful") : "",
23550
- rawTokensPath: extraction.rawTokensPath,
23551
- credentials: {
23552
- spaceId: credentials.spaceId,
23553
- environmentId: credentials.environmentId || "master",
23554
- cmaToken: credentials.cmaToken,
23555
- host: toConfiguredHost2(credentials.host) ?? DEFAULT_CONFIGURED_HOST
23556
- },
23557
- ...generatePromptPath ? { generatePromptPath } : {}
23558
- };
23559
- }
23560
- var init_build_flow_start = __esm({
23561
- "packages/experience-design-system-cli/src/tui/import/steps/10-flow/flow/build-flow-start.ts"() {
24573
+ // packages/experience-design-system-types/dist/src/index.js
24574
+ var init_src5 = __esm({
24575
+ "packages/experience-design-system-types/dist/src/index.js"() {
23562
24576
  "use strict";
23563
- init_src4();
24577
+ init_cdf2();
24578
+ init_dtcg2();
23564
24579
  }
23565
24580
  });
23566
24581
 
@@ -23589,8 +24604,8 @@ function missingNote(missingNames) {
23589
24604
  Note: ${plural2(missingNames.length, "component name")} from the server (${missingNames.join(", ")}) ${verb} not match anything in this session \u2014 they cannot be edited or skipped from here.`;
23590
24605
  }
23591
24606
  function contextText(errors, missingNames) {
23592
- const failed = failedComponentNames(errors);
23593
- return `${plural2(failed.length, "component")} failed server validation. Edit their definitions in the review TUI, or skip them and retry preview without them.${missingNote(missingNames)}`;
24607
+ const failed2 = failedComponentNames(errors);
24608
+ return `${plural2(failed2.length, "component")} failed server validation. Edit their definitions in the review TUI, or skip them and retry preview without them.${missingNote(missingNames)}`;
23594
24609
  }
23595
24610
  function skipLabel(matchedNames) {
23596
24611
  if (matchedNames.length === 0) return "No matching components to skip";
@@ -25396,8 +26411,8 @@ function FieldEditor({
25396
26411
  return /* @__PURE__ */ jsxs22(Box21, { flexDirection: "column", width, borderStyle: "single", borderColor: PALETTE3.warning, children: [
25397
26412
  /* @__PURE__ */ jsx27(Text23, { bold: true, color: PALETTE3.warning, children: "FIELD EDITOR \u2014 no fields" }),
25398
26413
  /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.warning, children: "\u26A0 No properties classified for this component. The LLM didn't find anything to classify." }),
25399
- /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "There is nothing to edit here." }),
25400
- /* @__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" })
26414
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "You can add fields manually below or reject this component." }),
26415
+ /* @__PURE__ */ jsx27(Text23, { color: PALETTE3.muted, children: "Enter to save \xB7 Esc to discard" })
25401
26416
  ] });
25402
26417
  }
25403
26418
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
@@ -25612,7 +26627,7 @@ function FieldEditor({
25612
26627
  children: [
25613
26628
  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." }),
25614
26629
  header,
25615
- /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && !inSlots && currentProp ? /* @__PURE__ */ jsx27(
26630
+ /* @__PURE__ */ jsx27(Box21, { flexDirection: "column", width: innerWidth, flexShrink: 0, children: focusLevel === "field" && !inComponentDesc && currentProp ? /* @__PURE__ */ jsx27(
25616
26631
  PropRow,
25617
26632
  {
25618
26633
  prop: currentProp,
@@ -26616,7 +27631,6 @@ function finalizeReviewSession(extractSessionId, components) {
26616
27631
  db.exec("ROLLBACK");
26617
27632
  throw error;
26618
27633
  }
26619
- removeSlotAllowedComponents(db, extractSessionId, [], toReject);
26620
27634
  } finally {
26621
27635
  db.close();
26622
27636
  }
@@ -26696,7 +27710,7 @@ var init_history = __esm({
26696
27710
  // packages/experience-design-system-cli/src/tui/import/steps/09-review/run-live-preview.ts
26697
27711
  async function runLivePreview(opts) {
26698
27712
  const { sessionId, tokensPath, spaceId, environmentId, cmaToken, host, generation } = opts;
26699
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS5;
27713
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS6;
26700
27714
  if (!spaceId || !environmentId || !cmaToken) {
26701
27715
  return { generation, response: null };
26702
27716
  }
@@ -26739,7 +27753,7 @@ async function runLivePreview(opts) {
26739
27753
  if (timeoutHandle) clearTimeout(timeoutHandle);
26740
27754
  }
26741
27755
  }
26742
- var TimeoutError, DEFAULT_TIMEOUT_MS5;
27756
+ var TimeoutError, DEFAULT_TIMEOUT_MS6;
26743
27757
  var init_run_live_preview = __esm({
26744
27758
  "packages/experience-design-system-cli/src/tui/import/steps/09-review/run-live-preview.ts"() {
26745
27759
  "use strict";
@@ -26754,7 +27768,7 @@ var init_run_live_preview = __esm({
26754
27768
  this.name = "TimeoutError";
26755
27769
  }
26756
27770
  };
26757
- DEFAULT_TIMEOUT_MS5 = 15e3;
27771
+ DEFAULT_TIMEOUT_MS6 = 15e3;
26758
27772
  }
26759
27773
  });
26760
27774
 
@@ -28395,50 +29409,33 @@ function GenerateReviewStepView({
28395
29409
  const cycle = cycleRows[cyclesCursor];
28396
29410
  return cycle ? enumerateCycleBreaks(cycle, components) : [];
28397
29411
  }, [cycleRows, cyclesCursor, components]);
28398
- const saveSlotChange = (parentKey, nextEntry, historyLabel) => {
29412
+ const handleBreakEdge = (edge) => {
29413
+ const target = components.find((component) => component.key === edge.fromComponent);
29414
+ const slot = target?.entry.$slots?.[edge.slotName];
29415
+ if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
29416
+ const nextEntry = {
29417
+ ...target.entry,
29418
+ $slots: {
29419
+ ...target.entry.$slots,
29420
+ [edge.slotName]: {
29421
+ ...slot,
29422
+ $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
29423
+ }
29424
+ }
29425
+ };
28399
29426
  const next = components.map(
28400
- (component) => component.key === parentKey ? { ...component, entry: nextEntry } : component
29427
+ (component) => component.key === target.key ? { ...component, entry: nextEntry } : component
28401
29428
  );
28402
29429
  setComponents(next);
28403
29430
  const db = openPipelineDb();
28404
29431
  try {
28405
- storeCDFComponents(db, extractSessionId, [{ key: parentKey, entry: nextEntry }]);
29432
+ storeCDFComponents(db, extractSessionId, [{ key: target.key, entry: nextEntry }]);
28406
29433
  } finally {
28407
29434
  db.close();
28408
29435
  }
28409
29436
  recomputeCycles(next);
28410
29437
  livePreviewHook.trigger();
28411
- pushHistorySnapshot(next, historyLabel);
28412
- };
28413
- const handleBreakEdge = (edge) => {
28414
- const target = components.find((component) => component.key === edge.fromComponent);
28415
- const slot = target?.entry.$slots?.[edge.slotName];
28416
- if (!target || !slot || !Array.isArray(slot.$allowedComponents)) return;
28417
- saveSlotChange(
28418
- target.key,
28419
- {
28420
- ...target.entry,
28421
- $slots: {
28422
- ...target.entry.$slots,
28423
- [edge.slotName]: {
28424
- ...slot,
28425
- $allowedComponents: slot.$allowedComponents.filter((value) => value !== edge.toComponent)
28426
- }
28427
- }
28428
- },
28429
- "break-cycle-edge"
28430
- );
28431
- };
28432
- const handleRemoveSlotChild = (parentKey, childKey) => {
28433
- const parent = components.find((component) => component.key === parentKey);
28434
- if (!parent?.entry.$slots) return;
28435
- const slots = Object.fromEntries(
28436
- Object.entries(parent.entry.$slots).map(([slotName, slot]) => [
28437
- slotName,
28438
- Array.isArray(slot.$allowedComponents) ? { ...slot, $allowedComponents: slot.$allowedComponents.filter((value) => value !== childKey) } : slot
28439
- ])
28440
- );
28441
- saveSlotChange(parentKey, { ...parent.entry, $slots: slots }, "remove-slot-child");
29438
+ pushHistorySnapshot(next, "break-cycle-edge");
28442
29439
  };
28443
29440
  const handleRejectComponent = (key) => {
28444
29441
  const rejectCascade2 = computeRejectCascade(key, componentGraph);
@@ -28768,11 +29765,6 @@ function GenerateReviewStepView({
28768
29765
  if (input === "r") {
28769
29766
  const current = components[selectedIdx];
28770
29767
  if (!current) return;
28771
- const row = visibleRowsMemo[cursorRowIdx];
28772
- if (row?.kind === "group-child" && row.parentName) {
28773
- handleRemoveSlotChild(row.parentName, current.key);
28774
- return;
28775
- }
28776
29768
  handleRejectComponent(current.key);
28777
29769
  return;
28778
29770
  }
@@ -29387,7 +30379,7 @@ var init_DoneStep = __esm({
29387
30379
  });
29388
30380
 
29389
30381
  // packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts
29390
- import { resolve as resolve21 } from "node:path";
30382
+ import { resolve as resolve24 } from "node:path";
29391
30383
  import { homedir as homedir4 } from "node:os";
29392
30384
  function expandTilde(input) {
29393
30385
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -29401,7 +30393,7 @@ function normalizePath(input) {
29401
30393
  p = p.slice(1, -1);
29402
30394
  }
29403
30395
  p = expandTilde(p);
29404
- return resolve21(p);
30396
+ return resolve24(p);
29405
30397
  }
29406
30398
  var init_path_utils = __esm({
29407
30399
  "packages/experience-design-system-cli/src/tui/import/steps/10-flow/support/path-utils.ts"() {
@@ -30554,19 +31546,19 @@ function resultOf(operation, preview) {
30554
31546
  const items = operation.items ?? [];
30555
31547
  if (items.length > 0) {
30556
31548
  const count = (entityType, action) => items.filter((i) => i.entityType === entityType && i.action === action && i.status === "succeeded").length;
30557
- const failed = (entityType) => items.filter((i) => i.entityType === entityType && i.status === "failed").length;
31549
+ const failed2 = (entityType) => items.filter((i) => i.entityType === entityType && i.status === "failed").length;
30558
31550
  return {
30559
31551
  componentTypes: {
30560
31552
  created: count("ComponentType", "create"),
30561
31553
  updated: count("ComponentType", "update"),
30562
31554
  removed: count("ComponentType", "delete"),
30563
- failed: failed("ComponentType")
31555
+ failed: failed2("ComponentType")
30564
31556
  },
30565
31557
  designTokens: {
30566
31558
  created: count("DesignToken", "create"),
30567
31559
  updated: count("DesignToken", "update"),
30568
31560
  removed: count("DesignToken", "delete"),
30569
- failed: failed("DesignToken")
31561
+ failed: failed2("DesignToken")
30570
31562
  },
30571
31563
  summary: operation.summary,
30572
31564
  failures: items.filter((item) => item.status === "failed").map((item) => ({
@@ -30744,7 +31736,7 @@ var init_save = __esm({
30744
31736
  writeFile: (path5, contents) => writeFile7(path5, contents),
30745
31737
  appendRun,
30746
31738
  buildSourceFingerprint,
30747
- sleep: (ms) => new Promise((resolve22) => setTimeout(resolve22, ms)),
31739
+ sleep: (ms) => new Promise((resolve25) => setTimeout(resolve25, ms)),
30748
31740
  warn: (message) => process.stderr.write(message)
30749
31741
  });
30750
31742
  }
@@ -32179,8 +33171,28 @@ import { join as join28 } from "node:path";
32179
33171
  import { Command } from "commander";
32180
33172
 
32181
33173
  // packages/experience-design-system-cli/src/legacy/run-legacy.ts
32182
- init_legacy_cli_path();
32183
33174
  import { spawn } from "node:child_process";
33175
+
33176
+ // packages/experience-design-system-cli/src/legacy/legacy-cli-path.ts
33177
+ init_package_root();
33178
+ import { existsSync as existsSync2 } from "node:fs";
33179
+ import { join as join2 } from "node:path";
33180
+ var PACKAGE_NAME = "@contentful/experience-design-system-cli";
33181
+ function findLegacyCliPath() {
33182
+ const root = findPackageRoot(import.meta.url, PACKAGE_NAME);
33183
+ const candidates = [
33184
+ join2(root, "legacy", "bin", "cli.js"),
33185
+ join2(root, "..", "experience-design-system-cli-legacy", "bin", "cli.js")
33186
+ ];
33187
+ const found = candidates.find((candidate) => existsSync2(candidate));
33188
+ if (!found) {
33189
+ throw new Error(`Legacy CLI not found. Looked in:
33190
+ ${candidates.join("\n")}`);
33191
+ }
33192
+ return found;
33193
+ }
33194
+
33195
+ // packages/experience-design-system-cli/src/legacy/run-legacy.ts
32184
33196
  function runLegacy(args) {
32185
33197
  return new Promise((resolvePromise) => {
32186
33198
  let cliPath;
@@ -32259,14 +33271,14 @@ function runDevWatch(args) {
32259
33271
  process.stderr.write("--watch only works from a checkout of the repo (scripts/dev.mjs is not in the package).\n");
32260
33272
  return Promise.resolve(1);
32261
33273
  }
32262
- return new Promise((resolve22) => {
33274
+ return new Promise((resolve25) => {
32263
33275
  const child = spawn2(process.execPath, [script, ...args], { stdio: "inherit" });
32264
33276
  process.on("SIGINT", () => void 0);
32265
- child.on("exit", (code) => resolve22(code ?? 0));
33277
+ child.on("exit", (code) => resolve25(code ?? 0));
32266
33278
  child.on("error", (err) => {
32267
33279
  process.stderr.write(`${err.message}
32268
33280
  `);
32269
- resolve22(1);
33281
+ resolve25(1);
32270
33282
  });
32271
33283
  });
32272
33284
  }
@@ -32310,12 +33322,12 @@ function createProgram() {
32310
33322
  init_config();
32311
33323
  init_package_root();
32312
33324
  import { existsSync as existsSync12 } from "node:fs";
32313
- import { mkdir as mkdir10, readFile as readFile16, rename as rename3, rmdir, unlink } from "node:fs/promises";
33325
+ import { mkdir as mkdir10, readFile as readFile19, rename as rename3, rmdir, unlink } from "node:fs/promises";
32314
33326
  import { dirname as dirname16, join as join29 } from "node:path";
32315
33327
  var PACKAGE_NAME4 = "@contentful/experience-design-system-cli";
32316
33328
  async function readJson(path5) {
32317
33329
  try {
32318
- return JSON.parse(await readFile16(path5, "utf8"));
33330
+ return JSON.parse(await readFile19(path5, "utf8"));
32319
33331
  } catch {
32320
33332
  return void 0;
32321
33333
  }