@contentful/experience-design-system-cli 2.32.1-dev-build-dc74ac7.0 → 2.32.1-dev-build-e667d41.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/src/index.js CHANGED
@@ -335,7 +335,7 @@ async function runAgent(options) {
335
335
  promptLen: prompt2.length,
336
336
  promptHead: prompt2.slice(0, 500)
337
337
  });
338
- return new Promise((resolve27) => {
338
+ return new Promise((resolve28) => {
339
339
  const bedrockEnv = bedrock ? BEDROCK_ENV_BY_AGENT[agent] : void 0;
340
340
  const child = spawn(binary, args, {
341
341
  stdio: ["pipe", "pipe", "pipe"],
@@ -384,25 +384,25 @@ async function runAgent(options) {
384
384
  stderrLen: stderr.length,
385
385
  stderrTail: stderr.slice(-1e3)
386
386
  });
387
- resolve27(result);
387
+ resolve28(result);
388
388
  });
389
389
  });
390
390
  }
391
391
  async function checkAgentAuth(agent) {
392
392
  const binary = resolveBinary(agent);
393
- const binaryExists2 = await new Promise((resolve27) => {
393
+ const binaryExists2 = await new Promise((resolve28) => {
394
394
  if (binary.startsWith("/")) {
395
- import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve27(true), () => resolve27(false)));
395
+ import("node:fs/promises").then((fs2) => fs2.access(binary).then(() => resolve28(true), () => resolve28(false)));
396
396
  return;
397
397
  }
398
398
  const child = spawn("which", [binary], { stdio: "ignore" });
399
- child.on("close", (code) => resolve27(code === 0));
399
+ child.on("close", (code) => resolve28(code === 0));
400
400
  });
401
401
  if (!binaryExists2)
402
402
  return "not-found";
403
403
  if (agent !== "claude")
404
404
  return "ok";
405
- return new Promise((resolve27) => {
405
+ return new Promise((resolve28) => {
406
406
  const child = spawn(binary, ["auth", "status", "--json"], {
407
407
  stdio: ["ignore", "pipe", "pipe"]
408
408
  });
@@ -412,7 +412,7 @@ async function checkAgentAuth(agent) {
412
412
  if (!done) {
413
413
  done = true;
414
414
  child.kill("SIGTERM");
415
- resolve27("unauthenticated");
415
+ resolve28("unauthenticated");
416
416
  }
417
417
  }, 5e3);
418
418
  child.stdout?.on("data", (chunk) => {
@@ -424,14 +424,14 @@ async function checkAgentAuth(agent) {
424
424
  done = true;
425
425
  clearTimeout(timer);
426
426
  if (code !== 0) {
427
- resolve27("unauthenticated");
427
+ resolve28("unauthenticated");
428
428
  return;
429
429
  }
430
430
  try {
431
431
  const status = JSON.parse(stdout);
432
- resolve27(status.loggedIn ? "ok" : "unauthenticated");
432
+ resolve28(status.loggedIn ? "ok" : "unauthenticated");
433
433
  } catch {
434
- resolve27("unauthenticated");
434
+ resolve28("unauthenticated");
435
435
  }
436
436
  });
437
437
  });
@@ -624,8 +624,20 @@ function renderTokenCandidateSection(kind, entries) {
624
624
  ${formatTokenCandidateLines(entries)}`;
625
625
  }
626
626
  function buildPreamble(options) {
627
- const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs } = options;
627
+ const { skill, rawComponentsInline, rawTokensInline, rawTokensFilename, tokensInline, tokenMapInline, generatedCdf, tokenTree, componentSourceRefs, existingComponentsInline, existingTokensInline } = options;
628
628
  const sections = [];
629
+ if (existingComponentsInline) {
630
+ sections.push(`Existing components in the target Contentful space (JSON) \u2014 use for alignment, not as a hard filter:
631
+ \`\`\`json
632
+ ${existingComponentsInline}
633
+ \`\`\``);
634
+ }
635
+ if (existingTokensInline) {
636
+ sections.push(`Existing design tokens in the target Contentful space (JSON) \u2014 prefer binding to these paths over inventing new ones:
637
+ \`\`\`json
638
+ ${existingTokensInline}
639
+ \`\`\``);
640
+ }
629
641
  if (rawComponentsInline) {
630
642
  sections.push(`Raw component data (JSON):
631
643
  \`\`\`json
@@ -8775,9 +8787,10 @@ async function hashFile(filePath) {
8775
8787
  const content = await readFile6(filePath, "utf8");
8776
8788
  return hashContent(content);
8777
8789
  }
8778
- async function hashPromptForSkill(skill, agent, model, skillPathOverride) {
8790
+ async function hashPromptForSkill(skill, agent, model, skillPathOverride, extraInputs = []) {
8779
8791
  const promptHash = skillPathOverride ? await hashFile(resolve6(skillPathOverride)) : await hashFile(resolveSkillPath(skill));
8780
- return hashContent(`${promptHash}|${agent}|${model ?? ""}`);
8792
+ const extraSegment = extraInputs.length > 0 ? `|${extraInputs.join("|")}` : "";
8793
+ return hashContent(`${promptHash}|${agent}|${model ?? ""}${extraSegment}`);
8781
8794
  }
8782
8795
  var init_cache_keys = __esm({
8783
8796
  "packages/experience-design-system-cli/src/session/cache-keys.ts"() {
@@ -12885,7 +12898,7 @@ var init_user_agent = __esm({
12885
12898
 
12886
12899
  // packages/experience-design-system-cli/src/apply/api-client.ts
12887
12900
  function defaultSleep(delayMs) {
12888
- return new Promise((resolve27) => setTimeout(resolve27, delayMs));
12901
+ return new Promise((resolve28) => setTimeout(resolve28, delayMs));
12889
12902
  }
12890
12903
  function isTransientStatus(status) {
12891
12904
  return status >= 500 && status <= 599;
@@ -13273,7 +13286,7 @@ ${trimmed}`;
13273
13286
  const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
13274
13287
  const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
13275
13288
  const jitter = Math.random() * baseDelay * 0.15;
13276
- await new Promise((resolve27) => setTimeout(resolve27, baseDelay + jitter));
13289
+ await new Promise((resolve28) => setTimeout(resolve28, baseDelay + jitter));
13277
13290
  }
13278
13291
  }
13279
13292
  throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
@@ -16565,7 +16578,7 @@ var init_command2 = __esm({
16565
16578
  });
16566
16579
 
16567
16580
  // packages/experience-design-system-cli/src/import/path-utils.ts
16568
- import { resolve as resolve20 } from "node:path";
16581
+ import { resolve as resolve21 } from "node:path";
16569
16582
  import { homedir as homedir6 } from "node:os";
16570
16583
  function expandTilde(input) {
16571
16584
  if (input === "~" || input.startsWith("~/") || input.startsWith("~\\")) {
@@ -16579,7 +16592,7 @@ function normalizePath(input) {
16579
16592
  p = p.slice(1, -1);
16580
16593
  }
16581
16594
  p = expandTilde(p);
16582
- return resolve20(p);
16595
+ return resolve21(p);
16583
16596
  }
16584
16597
  var init_path_utils = __esm({
16585
16598
  "packages/experience-design-system-cli/src/import/path-utils.ts"() {
@@ -16647,7 +16660,7 @@ var init_save_path_resolver = __esm({
16647
16660
  });
16648
16661
 
16649
16662
  // packages/experience-design-system-cli/src/runs/store.ts
16650
- import { readFile as readFile22, writeFile as writeFile6, mkdir as mkdir6, rename } from "node:fs/promises";
16663
+ import { readFile as readFile23, writeFile as writeFile6, mkdir as mkdir6, rename } from "node:fs/promises";
16651
16664
  import { join as join20 } from "node:path";
16652
16665
  import { homedir as homedir7 } from "node:os";
16653
16666
  import { randomBytes as randomBytes2 } from "node:crypto";
@@ -16691,7 +16704,7 @@ function migrateRecord(rec) {
16691
16704
  }
16692
16705
  async function readFileMaybe() {
16693
16706
  try {
16694
- const raw = await readFile22(RUNS_PATH, "utf8");
16707
+ const raw = await readFile23(RUNS_PATH, "utf8");
16695
16708
  const parsed = JSON.parse(raw);
16696
16709
  if (!READABLE_VERSIONS.has(parsed.version)) {
16697
16710
  throw new Error(
@@ -17287,8 +17300,8 @@ var init_save_conflict = __esm({
17287
17300
 
17288
17301
  // packages/experience-design-system-cli/src/runs/fingerprint.ts
17289
17302
  import { createHash as createHash4 } from "node:crypto";
17290
- import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
17291
- import { resolve as resolve22 } from "node:path";
17303
+ import { readFile as readFile24, stat as stat5 } from "node:fs/promises";
17304
+ import { resolve as resolve23 } from "node:path";
17292
17305
  function rowField(row, key) {
17293
17306
  const v = row[key];
17294
17307
  return typeof v === "string" ? v : null;
@@ -17304,7 +17317,7 @@ async function buildSourceFingerprint(opts) {
17304
17317
  const sourcePath = rowField(row, "source_path");
17305
17318
  const name = rowField(row, "name");
17306
17319
  if (!sourcePath) continue;
17307
- const abs = resolve22(sourcePath);
17320
+ const abs = resolve23(sourcePath);
17308
17321
  if (seen.has(abs)) continue;
17309
17322
  seen.add(abs);
17310
17323
  try {
@@ -17319,10 +17332,10 @@ async function buildSourceFingerprint(opts) {
17319
17332
  let rawTokensMtime = null;
17320
17333
  let rawTokensContentHash = null;
17321
17334
  if (opts.rawTokensPath) {
17322
- const abs = resolve22(opts.rawTokensPath);
17335
+ const abs = resolve23(opts.rawTokensPath);
17323
17336
  rawTokensPath = abs;
17324
17337
  try {
17325
- const [st, buf] = await Promise.all([stat5(abs), readFile23(abs)]);
17338
+ const [st, buf] = await Promise.all([stat5(abs), readFile24(abs)]);
17326
17339
  rawTokensMtime = st.mtime.toISOString();
17327
17340
  rawTokensContentHash = sha256Hex(buf);
17328
17341
  } catch {
@@ -17935,8 +17948,11 @@ function CredentialsStep({
17935
17948
  "\u2713 ",
17936
17949
  summary
17937
17950
  ] }),
17938
- /* @__PURE__ */ jsx28(Box28, { marginTop: 1, children: /* @__PURE__ */ jsx28(Text28, { children: initialSpaceId && initialCmaToken ? "Credentials pre-filled from experiences setup. Press Enter to continue or edit any field to update." : "Enter your Contentful credentials to continue." }) }),
17939
- !(initialSpaceId && initialCmaToken) && /* @__PURE__ */ jsx28(Text28, { dimColor: true, children: "Tip: run experiences setup to save these to ~/.config/experiences/credentials.json so they pre-fill here automatically." }),
17951
+ /* @__PURE__ */ jsxs28(Box28, { flexDirection: "column", marginTop: 1, gap: 0, children: [
17952
+ /* @__PURE__ */ jsx28(Text28, { children: initialSpaceId && initialCmaToken ? "Credentials pre-filled from experiences setup. Press Enter to continue or edit any field to update." : "Enter the Contentful space you want to import into." }),
17953
+ !(initialSpaceId && initialCmaToken) && /* @__PURE__ */ jsx28(Text28, { dimColor: true, children: "These credentials are used both to align agent suggestions with what already exists in the space and to push your import at the end. Press S to skip and run without space context (push will be disabled)." }),
17954
+ !(initialSpaceId && initialCmaToken) && /* @__PURE__ */ jsx28(Text28, { dimColor: true, children: "Tip: run experiences setup to save these to ~/.config/experiences/credentials.json so they pre-fill here automatically." })
17955
+ ] }),
17940
17956
  /* @__PURE__ */ jsxs28(Box28, { flexDirection: "column", gap: 0, marginTop: 1, children: [
17941
17957
  renderField("Space ID", spaceId, "spaceId"),
17942
17958
  renderField("Environment", environmentId, "environmentId"),
@@ -19103,9 +19119,9 @@ function spawnGenerateChild(opts) {
19103
19119
  stderr += chunk;
19104
19120
  opts.onStderr?.(chunk);
19105
19121
  });
19106
- const donePromise = new Promise((resolve27) => {
19122
+ const donePromise = new Promise((resolve28) => {
19107
19123
  child.on("close", (code, signal) => {
19108
- resolve27({
19124
+ resolve28({
19109
19125
  exitCode: code ?? 0,
19110
19126
  signal: signal ?? null,
19111
19127
  stdout,
@@ -19113,7 +19129,7 @@ function spawnGenerateChild(opts) {
19113
19129
  });
19114
19130
  });
19115
19131
  child.on("error", (err) => {
19116
- resolve27({
19132
+ resolve28({
19117
19133
  exitCode: 1,
19118
19134
  signal: null,
19119
19135
  stdout,
@@ -27656,9 +27672,9 @@ __export(WizardApp_exports, {
27656
27672
  });
27657
27673
  import { useEffect as useEffect15, useRef as useRef9, useState as useState28 } from "react";
27658
27674
  import { Box as Box49, Text as Text51, useStdout as useStdout8 } from "ink";
27659
- import { join as join23, resolve as resolve23 } from "node:path";
27675
+ import { join as join23, resolve as resolve24 } from "node:path";
27660
27676
  import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
27661
- import { access as access9, readFile as readFile24, stat as stat6 } from "node:fs/promises";
27677
+ import { access as access9, readFile as readFile25, stat as stat6 } from "node:fs/promises";
27662
27678
  import { tmpdir } from "node:os";
27663
27679
  import { execFile as execFile4, spawn as spawn4 } from "node:child_process";
27664
27680
  import { mkdir as mkdir7 } from "node:fs/promises";
@@ -27802,7 +27818,7 @@ function WizardApp({
27802
27818
  const rawTokensEntryReady = !modifyEntryReady && !pushFromPickerReady && !!initialRawTokensPath;
27803
27819
  const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
27804
27820
  const initialStepResolved = modifyEntryReady ? "final-review" : pushFromPickerReady ? "push-from-picker" : rawTokensEntryReady ? "generating-tokens" : initialProjectPath ? "token-input" : "welcome";
27805
- const initialOutDir = initialProjectPath ? join23(resolve23(initialProjectPath), ".contentful") : "";
27821
+ const initialOutDir = initialProjectPath ? join23(resolve24(initialProjectPath), ".contentful") : "";
27806
27822
  const initialTokensPath = (modifyEntryReady || pushFromPickerReady) && initialOutDir && seedTokenSessionId ? join23(initialOutDir, "tokens.json") : "";
27807
27823
  const [state, setState] = useState28({
27808
27824
  step: modifyEntryReady || rawTokensEntryReady || pushFromPickerReady ? initialStepResolved : initialRuns && initialRuns.length > 0 ? "run-picker" : initialStepResolved,
@@ -28056,7 +28072,7 @@ If you are using AWS Bedrock, run:
28056
28072
  return true;
28057
28073
  };
28058
28074
  const runExtract = async (projectPath) => {
28059
- const outDir = join23(resolve23(projectPath), ".contentful");
28075
+ const outDir = join23(resolve24(projectPath), ".contentful");
28060
28076
  update({ step: "extracting", outDir, extractProgress: null, compositionPhase: null });
28061
28077
  const r = await new Promise((res) => {
28062
28078
  const extractArgs = [findCliPath(), "analyze", "extract", "--project", projectPath];
@@ -28372,7 +28388,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28372
28388
  if (await runMapTokens2(mappedSessionId)) update({ step: "final-review" });
28373
28389
  };
28374
28390
  const advanceToPushFlow = (generatedAcceptedCount) => {
28375
- update({ generatedAcceptedCount, step: "credentials" });
28391
+ update({ generatedAcceptedCount, step: "push-decision-gate" });
28376
28392
  };
28377
28393
  const runEditFromPreview = async () => {
28378
28394
  update({ step: "final-review" });
@@ -28443,6 +28459,10 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
28443
28459
  }
28444
28460
  };
28445
28461
  const advanceAfterCredentialsValidated = async () => {
28462
+ if (!sessionRef.current.extractSessionId && state.projectPath) {
28463
+ void runExtract(state.projectPath);
28464
+ return;
28465
+ }
28446
28466
  if (shouldSkipFinalReviewAfterCredentials(state)) {
28447
28467
  update({ step: "push-decision-gate" });
28448
28468
  return;
@@ -28901,8 +28921,8 @@ If using a custom --host, make sure the space exists on that host.`
28901
28921
  );
28902
28922
  }
28903
28923
  try {
28904
- const componentsBuf = await readFile24(join23(path, "components.json")).catch(() => null);
28905
- const tokensBuf = recordedTokensPath ? await readFile24(recordedTokensPath).catch(() => null) : null;
28924
+ const componentsBuf = await readFile25(join23(path, "components.json")).catch(() => null);
28925
+ const tokensBuf = recordedTokensPath ? await readFile25(recordedTokensPath).catch(() => null) : null;
28906
28926
  savedFingerprint = buildSavedFingerprint({
28907
28927
  componentsJson: componentsBuf,
28908
28928
  tokensJson: tokensBuf
@@ -29084,7 +29104,7 @@ If using a custom --host, make sure the space exists on that host.`
29084
29104
  {
29085
29105
  projectPath: state.projectPath,
29086
29106
  onConfirm: (path) => {
29087
- void runExtract(path);
29107
+ update({ projectPath: path, step: "credentials" });
29088
29108
  },
29089
29109
  onSkipComponents: () => {
29090
29110
  if (noPush) {
@@ -29168,12 +29188,7 @@ If using a custom --host, make sure the space exists on that host.`
29168
29188
  }
29169
29189
  return;
29170
29190
  }
29171
- if (acceptedCount > 0 && !noPush) {
29172
- if (await runAgentAuthCheck("credentials")) {
29173
- startGeneratePrefetch(sid, state.tokensPath);
29174
- }
29175
- }
29176
- update({ step: "credentials" });
29191
+ update({ step: "push-decision-gate" });
29177
29192
  },
29178
29193
  onAdvanceToPushFlow: (count) => {
29179
29194
  update({ acceptedCount: count, autoRejectedCount: 0 });
@@ -29658,7 +29673,7 @@ __export(staleness_exports, {
29658
29673
  formatStalenessDetail: () => formatStalenessDetail,
29659
29674
  shortStalenessSummary: () => shortStalenessSummary
29660
29675
  });
29661
- import { readFile as readFile25, stat as stat7 } from "node:fs/promises";
29676
+ import { readFile as readFile26, stat as stat7 } from "node:fs/promises";
29662
29677
  import { join as join24 } from "node:path";
29663
29678
  async function checkRunStaleness(run) {
29664
29679
  if (!run.sourceFingerprint) return { ...UNKNOWN };
@@ -29685,7 +29700,7 @@ async function checkRunStaleness(run) {
29685
29700
  if (run.sourceFingerprint.rawTokensPath) {
29686
29701
  const absPath = run.sourceFingerprint.rawTokensPath;
29687
29702
  try {
29688
- const [st, buf] = await Promise.all([stat7(absPath), readFile25(absPath)]);
29703
+ const [st, buf] = await Promise.all([stat7(absPath), readFile26(absPath)]);
29689
29704
  const mtime = st.mtime.toISOString();
29690
29705
  const hash = sha256Hex(buf);
29691
29706
  const mtimeChanged = run.sourceFingerprint.rawTokensMtime !== null && mtime !== run.sourceFingerprint.rawTokensMtime;
@@ -29703,7 +29718,7 @@ async function checkRunStaleness(run) {
29703
29718
  if (run.savedFingerprint.componentsJsonHash !== null) {
29704
29719
  const compPath = join24(run.savePath, "components.json");
29705
29720
  try {
29706
- const buf = await readFile25(compPath);
29721
+ const buf = await readFile26(compPath);
29707
29722
  if (sha256Hex(buf) !== run.savedFingerprint.componentsJsonHash) {
29708
29723
  result.savedComponentsEdited = true;
29709
29724
  result.stale = true;
@@ -29716,7 +29731,7 @@ async function checkRunStaleness(run) {
29716
29731
  if (run.savedFingerprint.tokensJsonHash !== null) {
29717
29732
  const tokensPath = run.tokensPath ?? join24(run.savePath, "tokens.json");
29718
29733
  try {
29719
- const buf = await readFile25(tokensPath);
29734
+ const buf = await readFile26(tokensPath);
29720
29735
  if (sha256Hex(buf) !== run.savedFingerprint.tokensJsonHash) {
29721
29736
  result.savedTokensEdited = true;
29722
29737
  result.stale = true;
@@ -29783,7 +29798,7 @@ async function promptForPushCredentials(opts = {}) {
29783
29798
  const { render: render7, Box: Box50, Text: Text52 } = await import("ink");
29784
29799
  const { useState: useState29 } = await import("react");
29785
29800
  const { CredentialsStep: CredentialsStep2 } = await Promise.resolve().then(() => (init_CredentialsStep(), CredentialsStep_exports));
29786
- return new Promise((resolve27, reject) => {
29801
+ return new Promise((resolve28, reject) => {
29787
29802
  let app = null;
29788
29803
  function App2() {
29789
29804
  const [done, setDone] = useState29(false);
@@ -29792,7 +29807,7 @@ async function promptForPushCredentials(opts = {}) {
29792
29807
  setDone(true);
29793
29808
  queueMicrotask(() => {
29794
29809
  app?.unmount();
29795
- resolve27({ spaceId, environmentId, cmaToken, host });
29810
+ resolve28({ spaceId, environmentId, cmaToken, host });
29796
29811
  });
29797
29812
  };
29798
29813
  if (done) {
@@ -29824,14 +29839,14 @@ var init_push_creds_prompt = __esm({
29824
29839
  // packages/experience-design-system-cli/src/program.ts
29825
29840
  import { spawn as spawn6 } from "node:child_process";
29826
29841
  import { fileURLToPath as fileURLToPath5 } from "node:url";
29827
- import { dirname as dirname14, join as join27, resolve as resolve26 } from "node:path";
29842
+ import { dirname as dirname14, join as join27, resolve as resolve27 } from "node:path";
29828
29843
  import { readFileSync as readFileSync10 } from "node:fs";
29829
29844
  import { Command } from "commander";
29830
29845
 
29831
29846
  // packages/experience-design-system-cli/src/analyze/command.ts
29832
29847
  import { createElement as createElement3 } from "react";
29833
29848
  import { render as render3 } from "ink";
29834
- import { mkdir as mkdir3, readdir as readdir2, readFile as readFile16, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
29849
+ import { mkdir as mkdir3, readdir as readdir2, readFile as readFile17, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
29835
29850
  import { isAbsolute as isAbsolute4, join as join15, relative as relative3, resolve as resolve15 } from "node:path";
29836
29851
 
29837
29852
  // packages/experience-design-system-cli/src/lib/agent-model-options.ts
@@ -29958,6 +29973,104 @@ init_command2();
29958
29973
  // packages/experience-design-system-cli/src/analyze/select-agent/command.ts
29959
29974
  init_db();
29960
29975
  init_cache_keys();
29976
+
29977
+ // packages/experience-design-system-cli/src/helpers/read-existing-contentful-entities-from-session.ts
29978
+ import { readFile as readFile13 } from "node:fs/promises";
29979
+ async function readExistingContentfulEntitiesFromSession(path) {
29980
+ if (!path) return void 0;
29981
+ try {
29982
+ const raw = await readFile13(path, "utf8");
29983
+ const parsed = JSON.parse(raw);
29984
+ if (!Array.isArray(parsed.components) || !Array.isArray(parsed.tokens)) return void 0;
29985
+ return parsed;
29986
+ } catch {
29987
+ return void 0;
29988
+ }
29989
+ }
29990
+
29991
+ // packages/experience-design-system-cli/src/helpers/find-nearly-matching-component.ts
29992
+ var MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH = 2;
29993
+ function findNearlyMatchingComponent(components, codebaseName) {
29994
+ const target = simplifyNameForComparison(codebaseName);
29995
+ if (!target) return void 0;
29996
+ let best;
29997
+ for (const c2 of components) {
29998
+ const edits = countCharacterEdits(target, simplifyNameForComparison(c2.name));
29999
+ if (edits > MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH) continue;
30000
+ if (!best || edits < best.edits) best = { component: c2, edits };
30001
+ if (edits === 0) break;
30002
+ }
30003
+ return best?.component;
30004
+ }
30005
+ function simplifyNameForComparison(name) {
30006
+ const stripped = name.toLowerCase().replace(/[^a-z0-9]/g, "");
30007
+ return stripped.endsWith("s") && stripped.length > 1 ? stripped.slice(0, -1) : stripped;
30008
+ }
30009
+ function countCharacterEdits(a, b) {
30010
+ if (a === b) return 0;
30011
+ if (a.length === 0) return b.length;
30012
+ if (b.length === 0) return a.length;
30013
+ if (a.length > b.length) [a, b] = [b, a];
30014
+ let prev = new Array(a.length + 1);
30015
+ let curr = new Array(a.length + 1);
30016
+ for (let i = 0; i <= a.length; i++) prev[i] = i;
30017
+ for (let j = 1; j <= b.length; j++) {
30018
+ curr[0] = j;
30019
+ for (let i = 1; i <= a.length; i++) {
30020
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
30021
+ curr[i] = Math.min(curr[i - 1] + 1, prev[i] + 1, prev[i - 1] + cost);
30022
+ }
30023
+ [prev, curr] = [curr, prev];
30024
+ }
30025
+ return prev[a.length];
30026
+ }
30027
+
30028
+ // packages/experience-design-system-cli/src/helpers/summarize-existing-contentful-entities.ts
30029
+ function summarizeForSelectAgent(entities) {
30030
+ return {
30031
+ components: entities.components.map((c2) => ({
30032
+ id: c2.sys.id,
30033
+ name: c2.name,
30034
+ description: c2.description
30035
+ })),
30036
+ tokens: summarizeTokens(entities.tokens)
30037
+ };
30038
+ }
30039
+ function summarizeForGenerateAgent(entities, codebaseComponentName) {
30040
+ const match2 = findNearlyMatchingComponent(entities.components, codebaseComponentName);
30041
+ const otherComponents = entities.components.filter((c2) => c2.sys.id !== match2?.sys.id).map((c2) => ({ id: c2.sys.id, name: c2.name }));
30042
+ return {
30043
+ likelyMatch: match2 ? {
30044
+ id: match2.sys.id,
30045
+ name: match2.name,
30046
+ designProperties: match2.designProperties.map((p) => ({
30047
+ id: p.id,
30048
+ name: p.name,
30049
+ type: p.type
30050
+ })),
30051
+ contentProperties: match2.contentProperties.map((p) => ({
30052
+ id: p.id,
30053
+ name: p.name,
30054
+ type: p.type
30055
+ })),
30056
+ slots: (match2.slots ?? []).map((s) => ({ id: s.id, name: s.name }))
30057
+ } : void 0,
30058
+ otherComponents,
30059
+ tokens: summarizeTokens(entities.tokens)
30060
+ };
30061
+ }
30062
+ function summarizeForMapTokens(entities) {
30063
+ return {
30064
+ tokens: entities.tokens.map((t) => ({ id: t.sys.id, name: t.name, type: t.type }))
30065
+ };
30066
+ }
30067
+ function summarizeTokens(tokens) {
30068
+ const kinds = /* @__PURE__ */ new Set();
30069
+ for (const t of tokens) kinds.add(t.type);
30070
+ return { count: tokens.length, kinds: [...kinds].sort() };
30071
+ }
30072
+
30073
+ // packages/experience-design-system-cli/src/analyze/select-agent/command.ts
29961
30074
  init_persistence();
29962
30075
  init_parser();
29963
30076
  init_src();
@@ -30059,7 +30172,7 @@ var OutputFormatter = class {
30059
30172
  };
30060
30173
 
30061
30174
  // packages/experience-design-system-cli/src/analyze/select-agent/context-builder.ts
30062
- import { readFile as readFile13 } from "node:fs/promises";
30175
+ import { readFile as readFile14 } from "node:fs/promises";
30063
30176
  import { dirname as dirname10, isAbsolute as isAbsolute2, join as join13, relative as relative2, resolve as resolve11, sep } from "node:path";
30064
30177
  var SCANNED_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".astro", ".js", ".jsx", ".svelte", ".ts", ".tsx", ".vue"]);
30065
30178
  var IMPORT_PATTERN2 = /import\s+(?:type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/g;
@@ -30188,7 +30301,7 @@ async function buildRepoContextIndex(root, filePaths) {
30188
30301
  absolutePath,
30189
30302
  relativePath: toPosixPath(relative2(resolvedRoot, absolutePath)),
30190
30303
  directory: dirname10(absolutePath),
30191
- text: await readFile13(absolutePath, "utf8").catch(() => "")
30304
+ text: await readFile14(absolutePath, "utf8").catch(() => "")
30192
30305
  })
30193
30306
  )
30194
30307
  );
@@ -30401,7 +30514,7 @@ function resolveProjectRoot(sessionId2, projectRootFlag) {
30401
30514
  db.close();
30402
30515
  }
30403
30516
  }
30404
- async function selectBatch(agent, model, batch, total, verbose, skillPathOverride) {
30517
+ async function selectBatch(agent, model, batch, total, verbose, skillPathOverride, existingComponentsInline) {
30405
30518
  const prompt2 = await buildPrompt({
30406
30519
  skill: "select",
30407
30520
  mode: "autonomous",
@@ -30411,7 +30524,8 @@ async function selectBatch(agent, model, batch, total, verbose, skillPathOverrid
30411
30524
  2
30412
30525
  ),
30413
30526
  outDir: process.cwd(),
30414
- skillPathOverride
30527
+ skillPathOverride,
30528
+ existingComponentsInline
30415
30529
  });
30416
30530
  let outputBuf = "";
30417
30531
  const formatter = new OutputFormatter(verbose, (s) => {
@@ -30506,7 +30620,7 @@ ${outputBuf}`);
30506
30620
  }
30507
30621
  return results;
30508
30622
  }
30509
- async function selectAllComponents(agent, model, components, verbose, skillPathOverride, cacheConfig = { noCache: true }) {
30623
+ async function selectAllComponents(agent, model, components, verbose, skillPathOverride, existingComponentsInline, cacheConfig = { noCache: true }) {
30510
30624
  const concurrency = Number(process.env.EDS_GENERATE_CONCURRENCY ?? DEFAULT_CONCURRENCY);
30511
30625
  const batchSize = resolveBatchSize();
30512
30626
  const total = components.length;
@@ -30515,7 +30629,13 @@ async function selectAllComponents(agent, model, components, verbose, skillPathO
30515
30629
  let cliVersion2 = "";
30516
30630
  if (!cacheConfig.noCache) {
30517
30631
  try {
30518
- promptHash = await hashPromptForSkill("select", agent, model, skillPathOverride);
30632
+ promptHash = await hashPromptForSkill(
30633
+ "select",
30634
+ agent,
30635
+ model,
30636
+ skillPathOverride,
30637
+ existingComponentsInline ? [hashContent(existingComponentsInline)] : []
30638
+ );
30519
30639
  cliVersion2 = await getCliCacheVersion();
30520
30640
  const db = openPipelineDb(cacheConfig.dbPath);
30521
30641
  try {
@@ -30571,7 +30691,15 @@ async function selectAllComponents(agent, model, components, verbose, skillPathO
30571
30691
  while (nextBatch < batches.length) {
30572
30692
  const b = nextBatch++;
30573
30693
  const batch = batches[b];
30574
- const batchResults = await selectBatch(agent, model, batch, total, verbose, skillPathOverride);
30694
+ const batchResults = await selectBatch(
30695
+ agent,
30696
+ model,
30697
+ batch,
30698
+ total,
30699
+ verbose,
30700
+ skillPathOverride,
30701
+ existingComponentsInline
30702
+ );
30575
30703
  for (let k = 0; k < batch.length; k++) {
30576
30704
  results[batch[k].index] = batchResults[k];
30577
30705
  }
@@ -30607,6 +30735,9 @@ function registerAnalyzeSelectAgentCommand(program) {
30607
30735
  "--select-prompt-path <path>",
30608
30736
  "Path to a custom .md skill prompt for select-agent (bypasses bundled prompt invariants)"
30609
30737
  ).option("--no-select-cache", "Skip the per-component select cache and re-LLM every component").option("--no-cache", "Skip ALL fine-grained caches (extract, select, generate)").option(
30738
+ "--existing-entities-path <path>",
30739
+ "Path to the .existing-entities.json file written by the orchestrator when CMA credentials are supplied. When present, the agent gets an existing-components summary to align rejection/acceptance reasoning with the target space. Missing/malformed files are treated as no-op."
30740
+ ).option(
30610
30741
  "--show-rationale",
30611
30742
  "Read-only: print the AI rejection rationale persisted by a prior select-agent run and exit. No LLM call. Combine with --json for machine-readable output."
30612
30743
  ).option("--json", "When used with --show-rationale, emit a JSON array instead of a human-readable table").action(
@@ -30715,6 +30846,20 @@ function registerAnalyzeSelectAgentCommand(program) {
30715
30846
  }));
30716
30847
  }
30717
30848
  }
30849
+ let existingComponentsInline;
30850
+ if (opts.existingEntitiesPath) {
30851
+ const existingContentfulEntities = await readExistingContentfulEntitiesFromSession(
30852
+ resolve12(opts.existingEntitiesPath)
30853
+ );
30854
+ if (existingContentfulEntities) {
30855
+ existingComponentsInline = JSON.stringify(summarizeForSelectAgent(existingContentfulEntities));
30856
+ } else {
30857
+ process.stderr.write(
30858
+ `warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
30859
+ `
30860
+ );
30861
+ }
30862
+ }
30718
30863
  if (opts.dryRun) {
30719
30864
  if (selectionCandidates.length === 0) {
30720
30865
  process.stderr.write(
@@ -30729,7 +30874,8 @@ function registerAnalyzeSelectAgentCommand(program) {
30729
30874
  mode: "autonomous",
30730
30875
  rawComponentsInline: JSON.stringify([buildComponentData(first)], null, 2),
30731
30876
  outDir: process.cwd(),
30732
- skillPathOverride: selectPromptPath ? resolve12(selectPromptPath) : void 0
30877
+ skillPathOverride: selectPromptPath ? resolve12(selectPromptPath) : void 0,
30878
+ existingComponentsInline
30733
30879
  });
30734
30880
  process.stdout.write(prompt2 + "\n");
30735
30881
  await exitWithAnalytics(0);
@@ -30742,6 +30888,7 @@ function registerAnalyzeSelectAgentCommand(program) {
30742
30888
  selectionCandidates,
30743
30889
  opts.verbose ?? false,
30744
30890
  selectPromptPath ? resolve12(selectPromptPath) : void 0,
30891
+ existingComponentsInline,
30745
30892
  { noCache }
30746
30893
  );
30747
30894
  const decisions = /* @__PURE__ */ new Map();
@@ -31129,11 +31276,11 @@ ${f.content}`).join("\n\n");
31129
31276
  }
31130
31277
 
31131
31278
  // packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts
31132
- import { readFile as readFile14 } from "node:fs/promises";
31279
+ import { readFile as readFile15 } from "node:fs/promises";
31133
31280
  async function loadUserMap(path) {
31134
31281
  let text;
31135
31282
  try {
31136
- text = await readFile14(path, "utf8");
31283
+ text = await readFile15(path, "utf8");
31137
31284
  } catch {
31138
31285
  return { ok: false, error: `--composition-map: file not found: ${path}` };
31139
31286
  }
@@ -31369,16 +31516,16 @@ var HEAP_CAP_MB = 128;
31369
31516
  var MAX_INPUT_BYTES = 8 * 1024 * 1024;
31370
31517
  function runParserInSandbox(source, ctx, opts = {}) {
31371
31518
  const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
31372
- return new Promise((resolve27) => {
31519
+ return new Promise((resolve28) => {
31373
31520
  let input;
31374
31521
  try {
31375
31522
  input = JSON.stringify({ source, ctx, timeoutMs });
31376
31523
  } catch {
31377
- resolve27({ edges: [], error: "ctx is not serializable" });
31524
+ resolve28({ edges: [], error: "ctx is not serializable" });
31378
31525
  return;
31379
31526
  }
31380
31527
  if (input.length > MAX_INPUT_BYTES) {
31381
- resolve27({ edges: [], error: "parser input exceeds size limit" });
31528
+ resolve28({ edges: [], error: "parser input exceeds size limit" });
31382
31529
  return;
31383
31530
  }
31384
31531
  let settled = false;
@@ -31410,7 +31557,7 @@ function runParserInSandbox(source, ctx, opts = {}) {
31410
31557
  child.kill("SIGKILL");
31411
31558
  } catch {
31412
31559
  }
31413
- resolve27(r);
31560
+ resolve28(r);
31414
31561
  };
31415
31562
  const timer = setTimeout(
31416
31563
  () => done({ edges: [], error: `parser timed out after ${timeoutMs}ms` }),
@@ -31622,7 +31769,7 @@ ${loadPrompt("composition-parser-repair-error.md").trim().replace("{{error}}", f
31622
31769
  }
31623
31770
 
31624
31771
  // packages/experience-design-system-cli/src/lib/prompt-overrides.ts
31625
- import { readFile as readFile15 } from "node:fs/promises";
31772
+ import { readFile as readFile16 } from "node:fs/promises";
31626
31773
  import { resolve as resolve14 } from "node:path";
31627
31774
  var PROMPT_FILE_EXTENSIONS = [".md", ".txt", ".prompt"];
31628
31775
  function looksLikePath(value) {
@@ -31658,7 +31805,7 @@ async function resolvePromptOverride(override) {
31658
31805
  if (override.kind === "text") return override.value;
31659
31806
  const abs = resolve14(override.value);
31660
31807
  try {
31661
- return await readFile15(abs, "utf8");
31808
+ return await readFile16(abs, "utf8");
31662
31809
  } catch {
31663
31810
  throw new Error(`--prompt: could not read prompt file: ${abs}`);
31664
31811
  }
@@ -31841,7 +31988,7 @@ async function readCandidateFiles(components, extraFiles = []) {
31841
31988
  await Promise.all(
31842
31989
  [...paths].map(async (p) => {
31843
31990
  try {
31844
- const content = await readFile16(p, "utf8");
31991
+ const content = await readFile17(p, "utf8");
31845
31992
  out.push({ path: p, content });
31846
31993
  } catch {
31847
31994
  }
@@ -32245,7 +32392,7 @@ function registerAnalyzeCommand(program) {
32245
32392
  init_src();
32246
32393
  import { createElement as createElement4 } from "react";
32247
32394
  import { render as render4 } from "ink";
32248
- import { access as access6, readFile as readFile18, readdir as readdir3, stat as stat3 } from "node:fs/promises";
32395
+ import { access as access6, readFile as readFile19, readdir as readdir3, stat as stat3 } from "node:fs/promises";
32249
32396
  import { join as join16, resolve as resolve17 } from "node:path";
32250
32397
  init_debug_logger();
32251
32398
 
@@ -32286,7 +32433,7 @@ function GenerateView({ result, onExit }) {
32286
32433
  }
32287
32434
 
32288
32435
  // packages/experience-design-system-cli/src/generate/edit/command.ts
32289
- import { readFile as readFile17 } from "node:fs/promises";
32436
+ import { readFile as readFile18 } from "node:fs/promises";
32290
32437
  import { resolve as resolve16 } from "node:path";
32291
32438
  var SAFE_PATH_RE2 = /^[a-zA-Z0-9_.$[\]=]+$/;
32292
32439
  var PROTO_KEYS2 = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
@@ -32369,7 +32516,7 @@ async function runNonInteractive2(opts, skill) {
32369
32516
  if (opts.patch) {
32370
32517
  let patchOps;
32371
32518
  try {
32372
- const raw = await readFile17(resolve16(opts.patch), "utf8");
32519
+ const raw = await readFile18(resolve16(opts.patch), "utf8");
32373
32520
  patchOps = JSON.parse(raw);
32374
32521
  } catch {
32375
32522
  process.stderr.write(`Error: cannot read or parse --patch file: ${opts.patch}
@@ -32463,7 +32610,7 @@ async function readFileInline(path) {
32463
32610
  } catch {
32464
32611
  return void 0;
32465
32612
  }
32466
- if (!s.isDirectory()) return readFile18(resolved, "utf8");
32613
+ if (!s.isDirectory()) return readFile19(resolved, "utf8");
32467
32614
  const files = [];
32468
32615
  async function walk(dir) {
32469
32616
  let entries;
@@ -32489,7 +32636,7 @@ async function readFileInline(path) {
32489
32636
  }
32490
32637
  await walk(resolved);
32491
32638
  if (files.length === 0) return void 0;
32492
- const parts = await Promise.all(files.map((f) => readFile18(f, "utf8").catch(() => "")));
32639
+ const parts = await Promise.all(files.map((f) => readFile19(f, "utf8").catch(() => "")));
32493
32640
  return parts.filter(Boolean).join("\n\n");
32494
32641
  }
32495
32642
  function printFallbackInstructions(options) {
@@ -32511,7 +32658,7 @@ function printFallbackInstructions(options) {
32511
32658
  lines.push(` Re-run the generate command with the agent available, or use --dry-run to inspect the prompt.`);
32512
32659
  process.stderr.write(lines.join("\n") + "\n");
32513
32660
  }
32514
- async function runOneComponent(agent, model, db, sessionId2, component, tokensInline, tokenMapInline, index, total, verbose, noCache, skillPathOverride, promptHash) {
32661
+ async function runOneComponent(agent, model, db, sessionId2, component, tokensInline, tokenMapInline, index, total, verbose, noCache, skillPathOverride, promptHash, existingContentfulEntities, existingTokensInline) {
32515
32662
  const pos = c.dim(`[${index + 1}/${total}]`);
32516
32663
  if (!noCache) {
32517
32664
  const inputHash = computeComponentInputHash(component);
@@ -32581,6 +32728,7 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
32581
32728
  component.props.map((p) => p.name),
32582
32729
  component.props.map((p) => p.type)
32583
32730
  );
32731
+ const existingComponentsInline = existingContentfulEntities ? JSON.stringify(summarizeForGenerateAgent(existingContentfulEntities, component.name)) : void 0;
32584
32732
  const prompt2 = await buildPrompt({
32585
32733
  skill: "components",
32586
32734
  mode: "autonomous",
@@ -32590,7 +32738,9 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
32590
32738
  outDir: process.cwd(),
32591
32739
  componentName: component.name,
32592
32740
  componentSourceRefs: [sourceRef],
32593
- skillPathOverride
32741
+ skillPathOverride,
32742
+ existingComponentsInline,
32743
+ existingTokensInline
32594
32744
  });
32595
32745
  const maxAttempts = 2;
32596
32746
  let lastError = "";
@@ -32658,7 +32808,7 @@ ${outputBuf}`);
32658
32808
  renamedSlotsCount: renames.length
32659
32809
  };
32660
32810
  }
32661
- async function runAllComponents(agent, model, db, sessionId2, components, tokensInline, tokenMapInline, verbose, noCache, skillPathOverride, promptHash) {
32811
+ async function runAllComponents(agent, model, db, sessionId2, components, tokensInline, tokenMapInline, verbose, noCache, skillPathOverride, promptHash, existingContentfulEntities, existingTokensInline) {
32662
32812
  const concurrency = Number(process.env.EDS_GENERATE_CONCURRENCY ?? DEFAULT_COMPONENT_CONCURRENCY);
32663
32813
  process.stderr.write(
32664
32814
  `Categorizing ${c.bold(String(components.length))} component${components.length === 1 ? "" : "s"}` + c.dim(` (concurrency: ${concurrency})`) + "\n"
@@ -32682,7 +32832,9 @@ async function runAllComponents(agent, model, db, sessionId2, components, tokens
32682
32832
  verbose,
32683
32833
  noCache,
32684
32834
  skillPathOverride,
32685
- promptHash
32835
+ promptHash,
32836
+ existingContentfulEntities,
32837
+ existingTokensInline
32686
32838
  );
32687
32839
  completed += 1;
32688
32840
  process.stderr.write(`${formatGenerateProgressLine(completed, components.length, results[i].componentName)}
@@ -32720,7 +32872,7 @@ async function loadAcceptedNames(sessionId2) {
32720
32872
  try {
32721
32873
  const artifactsRoot = getRefineArtifactsRoot();
32722
32874
  const paths = await getRefineSessionPaths(sessionId2, artifactsRoot);
32723
- const raw = await readFile18(paths.statePath, "utf8");
32875
+ const raw = await readFile19(paths.statePath, "utf8");
32724
32876
  const snapshot = JSON.parse(raw);
32725
32877
  const accepted = snapshot.components.filter((c2) => c2.status === "accepted").map((c2) => c2.name);
32726
32878
  if (accepted.length === 0) return null;
@@ -32766,6 +32918,19 @@ async function runGenerateSkill(skill, opts, verbose = false) {
32766
32918
  readFileInline(opts.tokens),
32767
32919
  readFileInline(opts.tokenMap)
32768
32920
  ]);
32921
+ let existingContentfulEntities;
32922
+ let existingTokensInline;
32923
+ if (opts.existingEntitiesPath) {
32924
+ existingContentfulEntities = await readExistingContentfulEntitiesFromSession(resolve17(opts.existingEntitiesPath));
32925
+ if (existingContentfulEntities) {
32926
+ existingTokensInline = JSON.stringify(summarizeForMapTokens(existingContentfulEntities));
32927
+ } else {
32928
+ process.stderr.write(
32929
+ `warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
32930
+ `
32931
+ );
32932
+ }
32933
+ }
32769
32934
  let sessionId2;
32770
32935
  let allComponents;
32771
32936
  if (skill === "components") {
@@ -32826,6 +32991,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
32826
32991
  sampleComponent.props.map((p) => p.name),
32827
32992
  sampleComponent.props.map((p) => p.type)
32828
32993
  ) : void 0;
32994
+ const dryRunExistingComponentsInline = skill === "components" && existingContentfulEntities && sampleComponent ? JSON.stringify(summarizeForGenerateAgent(existingContentfulEntities, sampleComponent.name)) : void 0;
32829
32995
  const prompt2 = await buildPrompt({
32830
32996
  skill,
32831
32997
  mode: "autonomous",
@@ -32836,7 +33002,9 @@ async function runGenerateSkill(skill, opts, verbose = false) {
32836
33002
  tokenMapInline,
32837
33003
  outDir: process.cwd(),
32838
33004
  componentSourceRefs: sampleSourceRef ? [sampleSourceRef] : void 0,
32839
- skillPathOverride: generatePromptPath
33005
+ skillPathOverride: generatePromptPath,
33006
+ existingComponentsInline: dryRunExistingComponentsInline,
33007
+ existingTokensInline: skill === "components" ? existingTokensInline : void 0
32840
33008
  });
32841
33009
  process.stdout.write(prompt2 + "\n");
32842
33010
  await exitWithAnalytics(0);
@@ -32854,7 +33022,15 @@ async function runGenerateSkill(skill, opts, verbose = false) {
32854
33022
  const db = openPipelineDb();
32855
33023
  let componentResults;
32856
33024
  try {
32857
- const promptHash = await hashPromptForSkill("components", agent, model, generatePromptPath);
33025
+ const existingContentfulEntitiesHashInputs = [];
33026
+ if (existingTokensInline) existingContentfulEntitiesHashInputs.push(hashContent(existingTokensInline));
33027
+ const promptHash = await hashPromptForSkill(
33028
+ "components",
33029
+ agent,
33030
+ model,
33031
+ generatePromptPath,
33032
+ existingContentfulEntitiesHashInputs
33033
+ );
32858
33034
  componentResults = await runAllComponents(
32859
33035
  agent,
32860
33036
  model,
@@ -32866,7 +33042,9 @@ async function runGenerateSkill(skill, opts, verbose = false) {
32866
33042
  verbose,
32867
33043
  opts.cache === false || process.env.EDS_NO_CACHE === "1",
32868
33044
  generatePromptPath,
32869
- promptHash
33045
+ promptHash,
33046
+ existingContentfulEntities,
33047
+ existingTokensInline
32870
33048
  );
32871
33049
  } finally {
32872
33050
  db.close();
@@ -33043,6 +33221,9 @@ function registerGenerateCommand(program) {
33043
33221
  const componentsCmd = generate.command("components").description("Invoke a coding agent to produce components.json from raw analysis output").option("--session <id>", "Session ID from analyze extract (defaults to most recent)").option("--tokens <path>", "Path to tokens.json for token-linked prop resolution").option("--token-map <path>", "Path to token-name-map.json sidecar").option(
33044
33222
  "--generate-prompt-path <path>",
33045
33223
  "Path to a custom .md skill prompt for components generation (bypasses bundled prompt invariants)"
33224
+ ).option(
33225
+ "--existing-entities-path <path>",
33226
+ "Path to the .existing-entities.json file written by the orchestrator when CMA credentials are supplied. When present, per-component prompts include a summary of the target space so classifications can align to existing prop names/tokens. Missing/malformed files are treated as no-op."
33046
33227
  );
33047
33228
  addAgentFlags(componentsCmd).action(async (opts) => {
33048
33229
  await runGenerateSkill("components", opts, opts.verbose ?? false);
@@ -33489,9 +33670,9 @@ ${"\u2500".repeat(60)}
33489
33670
  `);
33490
33671
  }
33491
33672
  process.stdout.write("\nDelete these sessions? (y/N) ");
33492
- const answer = await new Promise((resolve27) => {
33673
+ const answer = await new Promise((resolve28) => {
33493
33674
  process.stdin.setEncoding("utf8");
33494
- process.stdin.once("data", (chunk) => resolve27(String(chunk).trim().toLowerCase()));
33675
+ process.stdin.once("data", (chunk) => resolve28(String(chunk).trim().toLowerCase()));
33495
33676
  });
33496
33677
  if (answer !== "y") {
33497
33678
  db.close();
@@ -33526,7 +33707,7 @@ import { access as access7, mkdir as mkdir4, stat as stat4, writeFile as writeFi
33526
33707
  import { basename as basename5, resolve as resolve19 } from "node:path";
33527
33708
 
33528
33709
  // packages/experience-design-system-cli/src/print/validate/validators/cdf-validator.ts
33529
- import { readFile as readFile19 } from "node:fs/promises";
33710
+ import { readFile as readFile20 } from "node:fs/promises";
33530
33711
  import { validateCDF as validateCDF2 } from "@contentful/experience-design-system-types";
33531
33712
  function extractValue(input, path) {
33532
33713
  if (path === "/") return void 0;
@@ -33585,7 +33766,7 @@ function rewriteDiagnostic(error, input) {
33585
33766
  async function validateCDFFile(filePath) {
33586
33767
  let content;
33587
33768
  try {
33588
- content = await readFile19(filePath, "utf-8");
33769
+ content = await readFile20(filePath, "utf-8");
33589
33770
  } catch (err) {
33590
33771
  return {
33591
33772
  valid: false,
@@ -33620,7 +33801,7 @@ async function validateCDFFile(filePath) {
33620
33801
  }
33621
33802
 
33622
33803
  // packages/experience-design-system-cli/src/print/validate/validators/dtcg-validator.ts
33623
- import { readFile as readFile20 } from "node:fs/promises";
33804
+ import { readFile as readFile21 } from "node:fs/promises";
33624
33805
  import { DESIGN_TOKEN_TYPES } from "@contentful/experience-design-system-types";
33625
33806
  function walkDTCG(obj, path, diagnostics, counts) {
33626
33807
  for (const [key, value] of Object.entries(obj)) {
@@ -33665,7 +33846,7 @@ function walkDTCG(obj, path, diagnostics, counts) {
33665
33846
  async function validateDTCGTokenFile(filePath) {
33666
33847
  let content;
33667
33848
  try {
33668
- content = await readFile20(filePath, "utf-8");
33849
+ content = await readFile21(filePath, "utf-8");
33669
33850
  } catch (err) {
33670
33851
  return {
33671
33852
  valid: false,
@@ -33998,7 +34179,8 @@ init_db();
33998
34179
  init_cache_keys();
33999
34180
  import { createElement as createElement6 } from "react";
34000
34181
  import { render as render6 } from "ink";
34001
- import { readFile as readFile21 } from "node:fs/promises";
34182
+ import { readFile as readFile22 } from "node:fs/promises";
34183
+ import { resolve as resolve20 } from "node:path";
34002
34184
 
34003
34185
  // packages/experience-design-system-cli/src/map-tokens/apply.ts
34004
34186
  init_db();
@@ -34246,7 +34428,7 @@ async function runMapTokens(opts) {
34246
34428
  const knownTokenPaths = new Set(tokenLeaves.map((t) => t.path));
34247
34429
  const tokenMapDiagnostics = [];
34248
34430
  if (opts.tokenMap) {
34249
- const fileMappings = JSON.parse(await readFile21(opts.tokenMap, "utf8"));
34431
+ const fileMappings = JSON.parse(await readFile22(opts.tokenMap, "utf8"));
34250
34432
  const validMappings = {};
34251
34433
  for (const [rawName, path] of Object.entries(fileMappings)) {
34252
34434
  if (knownTokenPaths.has(path)) {
@@ -34321,6 +34503,20 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
34321
34503
  const generatedCdf = Object.fromEntries(cdfEntries.map((c2) => [c2.key, c2.entry]));
34322
34504
  const tokenTree = rebuildDTCGTree(groups, tokens);
34323
34505
  const componentSourceRefs = await loadComponentSourceRefs(db, sessionId2);
34506
+ let existingTokensInline;
34507
+ if (opts.existingEntitiesPath) {
34508
+ const existingContentfulEntities = await readExistingContentfulEntitiesFromSession(
34509
+ resolve20(opts.existingEntitiesPath)
34510
+ );
34511
+ if (existingContentfulEntities) {
34512
+ existingTokensInline = JSON.stringify(summarizeForMapTokens(existingContentfulEntities));
34513
+ } else {
34514
+ process.stderr.write(
34515
+ `warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
34516
+ `
34517
+ );
34518
+ }
34519
+ }
34324
34520
  if (opts.printPrompt) {
34325
34521
  const prompt3 = await buildPrompt({
34326
34522
  skill: "map-tokens",
@@ -34328,7 +34524,8 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
34328
34524
  generatedCdf,
34329
34525
  tokenTree,
34330
34526
  componentSourceRefs,
34331
- outDir: process.cwd()
34527
+ outDir: process.cwd(),
34528
+ existingTokensInline
34332
34529
  });
34333
34530
  process.stdout.write(prompt3 + "\n");
34334
34531
  await exitWithAnalytics(0);
@@ -34346,7 +34543,13 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
34346
34543
  }
34347
34544
  const agent = configuredAgent;
34348
34545
  const noCache = opts.cache === false || process.env.EDS_NO_CACHE === "1";
34349
- const promptHash = await hashPromptForSkill("map-tokens", agent, model);
34546
+ const promptHash = await hashPromptForSkill(
34547
+ "map-tokens",
34548
+ agent,
34549
+ model,
34550
+ void 0,
34551
+ existingTokensInline ? [hashContent(existingTokensInline)] : []
34552
+ );
34350
34553
  const inputHash = computeMapTokensInputHash(db, sessionId2, componentSourceRefs);
34351
34554
  if (!noCache) {
34352
34555
  const cached = lookupCache(db, inputHash, "token_mapping", "__map_tokens__", promptHash);
@@ -34373,7 +34576,8 @@ Install it, choose another agent with --agent, or use --print-prompt to run the
34373
34576
  generatedCdf,
34374
34577
  tokenTree,
34375
34578
  componentSourceRefs,
34376
- outDir: process.cwd()
34579
+ outDir: process.cwd(),
34580
+ existingTokensInline
34377
34581
  });
34378
34582
  const invoker3 = createLocalCliAgentInvoker();
34379
34583
  const result = await invoker3.invoke({ agent, model, prompt: prompt2, timeoutMs: DEFAULT_TIMEOUT_MS4 });
@@ -34400,7 +34604,10 @@ ${warnings.map((w) => ` ${w}`).join("\n")}
34400
34604
  }
34401
34605
  function registerMapTokensCommand(program) {
34402
34606
  const map = program.command("map").description("Suggest token restrictions for generated design-token props");
34403
- const tokensCmd = map.command("tokens").description("Invoke a coding agent to suggest $token.allowed for design-category token props").option("--session <id>", "Session ID from generate components (defaults to most recent)").option("--print-prompt", "Print the prompt without invoking the agent").option("--skip-agent", "Resolve token defaults without agentic $token.allowed inference").option("--no-cache", "Bypass the map-tokens cache and force a re-run").option("--token-map <path>", "Path to token-name-map.json sidecar");
34607
+ const tokensCmd = map.command("tokens").description("Invoke a coding agent to suggest $token.allowed for design-category token props").option("--session <id>", "Session ID from generate components (defaults to most recent)").option("--print-prompt", "Print the prompt without invoking the agent").option("--skip-agent", "Resolve token defaults without agentic $token.allowed inference").option("--no-cache", "Bypass the map-tokens cache and force a re-run").option("--token-map <path>", "Path to token-name-map.json sidecar").option(
34608
+ "--existing-entities-path <path>",
34609
+ "Path to the .existing-entities.json file written by the orchestrator when CMA credentials are supplied. When present, the agent gets a list of the space's existing design tokens so it can prefer binding to them. Missing/malformed files are treated as no-op."
34610
+ );
34404
34611
  addAgentModelOptions(tokensCmd).action(async (opts) => {
34405
34612
  await runMapTokens(opts);
34406
34613
  });
@@ -34409,7 +34616,7 @@ function registerMapTokensCommand(program) {
34409
34616
  // packages/experience-design-system-cli/src/import/command.ts
34410
34617
  init_src();
34411
34618
  init_path_utils();
34412
- import { resolve as resolve25, join as join25 } from "node:path";
34619
+ import { resolve as resolve26, join as join25 } from "node:path";
34413
34620
 
34414
34621
  // packages/experience-design-system-cli/src/import/orchestrator.ts
34415
34622
  init_db();
@@ -34417,22 +34624,22 @@ init_command();
34417
34624
  init_manifest();
34418
34625
  init_api_client();
34419
34626
  import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
34420
- import { join as join18, resolve as resolve21 } from "node:path";
34627
+ import { join as join18, resolve as resolve22 } from "node:path";
34421
34628
  import { execFile as execFile2 } from "node:child_process";
34422
34629
 
34423
- // packages/experience-design-system-cli/src/helpers/fetch-existing-entities.ts
34630
+ // packages/experience-design-system-cli/src/helpers/fetch-existing-contentful-entities.ts
34424
34631
  import { fetchAll } from "contentful-management";
34425
- async function fetchExistingEntities(client2, params) {
34632
+ async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
34426
34633
  const scope = { spaceId: params.spaceId, environmentId: params.environmentId, query: {} };
34427
34634
  const components = await fetchAll(client2.component.getMany, scope);
34428
34635
  const tokens = await fetchAll(client2.designToken.getMany, scope);
34429
34636
  return { components, tokens };
34430
34637
  }
34431
34638
 
34432
- // packages/experience-design-system-cli/src/helpers/cma-client.ts
34639
+ // packages/experience-design-system-cli/src/helpers/build-contentful-management-client.ts
34433
34640
  init_host_utils();
34434
34641
  import { createClient as createClient2 } from "contentful-management";
34435
- function createCmaClient(opts) {
34642
+ function buildContentfulManagementClient(opts) {
34436
34643
  return createClient2(
34437
34644
  {
34438
34645
  accessToken: opts.cmaToken,
@@ -34532,8 +34739,8 @@ function buildPushStepResult(args) {
34532
34739
  };
34533
34740
  }
34534
34741
  async function runPipeline(opts, progressWriter, cliPathOverride) {
34535
- const projectRoot = resolve21(opts.project);
34536
- const outDir = resolve21(opts.out);
34742
+ const projectRoot = resolve22(opts.project);
34743
+ const outDir = resolve22(opts.out);
34537
34744
  const componentsPath = join18(outDir, "components.json");
34538
34745
  const cliPath = cliPathOverride ?? findCliPath();
34539
34746
  const db = openPipelineDb();
@@ -34555,19 +34762,14 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
34555
34762
  await mkdir5(outDir, { recursive: true });
34556
34763
  const steps = [];
34557
34764
  let stepNum = 0;
34558
- const wantsSpaceContext = opts.withSpaceContext === true;
34559
- const canFetchSpaceContext = wantsSpaceContext && !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
34560
- const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchSpaceContext ? 1 : 0);
34765
+ const canFetchExistingContentfulEntities = !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
34766
+ const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchExistingContentfulEntities ? 1 : 0);
34561
34767
  function stepLabel(name) {
34562
34768
  stepNum++;
34563
34769
  return ` Step ${stepNum}/${totalSteps} ${name} `;
34564
34770
  }
34565
- if (wantsSpaceContext && !canFetchSpaceContext) {
34566
- progressWriter(
34567
- " Note: --with-space-context requires --space-id, --environment-id, and --cma-token; skipping context fetch."
34568
- );
34569
- }
34570
- if (canFetchSpaceContext) {
34771
+ let existingEntitiesPath;
34772
+ if (canFetchExistingContentfulEntities) {
34571
34773
  const fetchLabel = stepLabel("Fetching existing components + design tokens");
34572
34774
  const fetchStepId = createStep(db, sessionId2, "fetch existing entities", {
34573
34775
  spaceId: opts.spaceId,
@@ -34575,16 +34777,19 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
34575
34777
  });
34576
34778
  const t0 = Date.now();
34577
34779
  try {
34578
- const cmaClient = createCmaClient({
34780
+ const contentfulManagementClient = buildContentfulManagementClient({
34579
34781
  cmaToken: opts.cmaToken,
34580
34782
  ...opts.host ? { host: opts.host } : {}
34581
34783
  });
34582
- const existingComponentsAndTokens = await fetchExistingEntities(cmaClient, {
34583
- spaceId: opts.spaceId,
34584
- environmentId: opts.environmentId
34585
- });
34784
+ const existingComponentsAndTokens = await fetchExistingContentfulEntitiesFromContentful(
34785
+ contentfulManagementClient,
34786
+ {
34787
+ spaceId: opts.spaceId,
34788
+ environmentId: opts.environmentId
34789
+ }
34790
+ );
34586
34791
  const fetchDurationMs = Date.now() - t0;
34587
- const existingEntitiesPath = join18(outDir, ".existing-entities.json");
34792
+ existingEntitiesPath = join18(outDir, ".existing-entities.json");
34588
34793
  await writeFile5(existingEntitiesPath, JSON.stringify(existingComponentsAndTokens, null, 2), "utf8");
34589
34794
  updateStep(db, fetchStepId, "complete", {
34590
34795
  components: String(existingComponentsAndTokens.components.length),
@@ -34701,6 +34906,7 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
34701
34906
  if (opts.excludeInvalid) editArgs.push("--exclude-invalid");
34702
34907
  if (opts.noCache) editArgs.push("--no-cache");
34703
34908
  if (opts.selectPromptPath) editArgs.push("--select-prompt-path", opts.selectPromptPath);
34909
+ if (existingEntitiesPath) editArgs.push("--existing-entities-path", existingEntitiesPath);
34704
34910
  } else {
34705
34911
  editArgs = ["analyze", "select", "--session", extractSessionId];
34706
34912
  if (opts.select && opts.select.length > 0) {
@@ -34763,6 +34969,7 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
34763
34969
  if (extractSessionId) generateArgs.push("--session", extractSessionId);
34764
34970
  if (opts.dryRun) generateArgs.push("--dry-run");
34765
34971
  if (opts.verbose) generateArgs.push("--verbose");
34972
+ if (existingEntitiesPath) generateArgs.push("--existing-entities-path", existingEntitiesPath);
34766
34973
  const stepId = createStep(db, sessionId2, "generate components", {
34767
34974
  extractSession: extractSessionId ?? ""
34768
34975
  });
@@ -34817,6 +35024,7 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
34817
35024
  if (opts.model) mapTokensArgs.push("--model", opts.model);
34818
35025
  if (opts.noCache) mapTokensArgs.push("--no-cache");
34819
35026
  if (opts.skipMapTokens) mapTokensArgs.push("--skip-agent");
35027
+ if (existingEntitiesPath) mapTokensArgs.push("--existing-entities-path", existingEntitiesPath);
34820
35028
  const mapTokensStepId = createStep(db, sessionId2, "map tokens", {
34821
35029
  extractSession: extractSessionId,
34822
35030
  skipAgent: String(opts.skipMapTokens === true)
@@ -35178,7 +35386,7 @@ init_host_utils();
35178
35386
  // packages/experience-design-system-cli/src/runs/replay-helpers.ts
35179
35387
  init_resolve_run_target();
35180
35388
  init_store();
35181
- import { resolve as resolve24 } from "node:path";
35389
+ import { resolve as resolve25 } from "node:path";
35182
35390
 
35183
35391
  // packages/experience-design-system-cli/src/runs/push-helpers.ts
35184
35392
  init_cli_path();
@@ -35368,7 +35576,7 @@ async function modifyRun(opts) {
35368
35576
  entryStep: "final-review",
35369
35577
  saveMode,
35370
35578
  ...run.compositionMode ? { compositionMode: run.compositionMode } : {},
35371
- ...opts.outDir ? { outDirOverride: resolve24(opts.outDir) } : {},
35579
+ ...opts.outDir ? { outDirOverride: resolve25(opts.outDir) } : {},
35372
35580
  ...mergedSpaceId ? { initialSpaceId: mergedSpaceId } : {},
35373
35581
  ...mergedEnvironmentId ? { initialEnvironmentId: mergedEnvironmentId } : {},
35374
35582
  ...mergedHost ? { initialHost: mergedHost } : {},
@@ -35445,7 +35653,7 @@ function resolvePromptFlags(flags) {
35445
35653
 
35446
35654
  // packages/experience-design-system-cli/src/runs/run-picker-mount.ts
35447
35655
  init_store();
35448
- import { readFile as readFile26 } from "node:fs/promises";
35656
+ import { readFile as readFile27 } from "node:fs/promises";
35449
35657
  function migrateRecord2(rec) {
35450
35658
  return {
35451
35659
  ...rec,
@@ -35468,7 +35676,7 @@ async function shouldShowRunPicker(input) {
35468
35676
  const path = input.runsJsonPath ?? runsFilePath();
35469
35677
  let raw;
35470
35678
  try {
35471
- raw = await readFile26(path, "utf8");
35679
+ raw = await readFile27(path, "utf8");
35472
35680
  } catch {
35473
35681
  return { shouldShow: false, runs: [] };
35474
35682
  }
@@ -35573,10 +35781,7 @@ function registerImportCommand(program) {
35573
35781
  "Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
35574
35782
  (v, acc) => [...acc, v],
35575
35783
  []
35576
- ).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
35577
- "--with-space-context",
35578
- "Fetch existing Components + DesignTokens from the target space+env and persist them under <out>/.existing-entities.json for future agent-context enrichment. Requires --space-id, --environment-id, and --cma-token."
35579
- ).option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
35784
+ ).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
35580
35785
  "--no-auto-filter",
35581
35786
  "Skip the automatic AI pre-filter; jump straight to manual scope-gate (overrides the credentials.json autoFilter preference; no-op when paired with --auto-accept-scope)"
35582
35787
  ).option(
@@ -35844,7 +36049,7 @@ function registerImportCommand(program) {
35844
36049
  livePreview: opts.livePreview !== false,
35845
36050
  noPush: noPushRequested,
35846
36051
  noSave: opts.save === false,
35847
- ...opts.outDir ? { outDirOverride: resolve25(opts.outDir) } : {},
36052
+ ...opts.outDir ? { outDirOverride: resolve26(opts.outDir) } : {},
35848
36053
  ...opts.onConflict ? { onConflictMode: opts.onConflict } : {},
35849
36054
  selectPromptPath: opts.selectPromptPath ?? creds.selectPromptPath,
35850
36055
  generatePromptPath: opts.generatePromptPath ?? creds.generatePromptPath,
@@ -35885,7 +36090,7 @@ function registerImportCommand(program) {
35885
36090
  return;
35886
36091
  }
35887
36092
  const projectRoot = normalizePath(opts.project);
35888
- const outDir = opts.out ? resolve25(opts.out) : join25(projectRoot, ".contentful");
36093
+ const outDir = opts.out ? resolve26(opts.out) : join25(projectRoot, ".contentful");
35889
36094
  const headlessCreds = await readExperiencesCredentials();
35890
36095
  const headlessAgent = resolveAgent(opts.agent, headlessCreds.agent);
35891
36096
  const headlessModel = resolveModel(opts.model, headlessCreds.agentModel);
@@ -35923,7 +36128,6 @@ function registerImportCommand(program) {
35923
36128
  dryRun: dryRunForward,
35924
36129
  selectPromptPath: opts.selectPromptPath,
35925
36130
  autoRejectCycles: opts.autoRejectCycles ?? false,
35926
- withSpaceContext: opts.withSpaceContext ?? false,
35927
36131
  allowDeletions: opts.allowDeletions ?? false,
35928
36132
  compositionMode: headlessCompositionMode,
35929
36133
  ...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
@@ -35948,7 +36152,7 @@ function registerImportCommand(program) {
35948
36152
  // packages/experience-design-system-cli/src/setup/command.ts
35949
36153
  init_credentials_store();
35950
36154
  import { execFile as execFile5, spawn as spawn5 } from "node:child_process";
35951
- import { appendFile as appendFile2, readFile as readFile27, access as access10 } from "node:fs/promises";
36155
+ import { appendFile as appendFile2, readFile as readFile28, access as access10 } from "node:fs/promises";
35952
36156
  import { join as join26 } from "node:path";
35953
36157
  import { homedir as homedir9 } from "node:os";
35954
36158
  import { fileURLToPath as fileURLToPath4 } from "node:url";
@@ -36027,10 +36231,10 @@ function prompt(question) {
36027
36231
  return Promise.resolve("");
36028
36232
  }
36029
36233
  const rl = createInterface({ input: process.stdin, output: process.stdout });
36030
- return new Promise((resolve27) => {
36234
+ return new Promise((resolve28) => {
36031
36235
  rl.question(question, (answer) => {
36032
36236
  rl.close();
36033
- resolve27(answer.trim());
36237
+ resolve28(answer.trim());
36034
36238
  });
36035
36239
  });
36036
36240
  }
@@ -36038,7 +36242,7 @@ function promptSecret(question) {
36038
36242
  if (!isInteractivePromptSession()) {
36039
36243
  return Promise.resolve("");
36040
36244
  }
36041
- return new Promise((resolve27) => {
36245
+ return new Promise((resolve28) => {
36042
36246
  const rl = createInterface({
36043
36247
  input: process.stdin,
36044
36248
  output: process.stdout,
@@ -36065,7 +36269,7 @@ function promptSecret(question) {
36065
36269
  }
36066
36270
  if (!process.stdin.isTTY) process.stdout.write("\n");
36067
36271
  process.stdin.resume();
36068
- resolve27(value);
36272
+ resolve28(value);
36069
36273
  });
36070
36274
  });
36071
36275
  }
@@ -36087,7 +36291,7 @@ async function binaryExists(name) {
36087
36291
  }
36088
36292
  }
36089
36293
  function runSpawn(cmd, args, opts = {}) {
36090
- return new Promise((resolve27) => {
36294
+ return new Promise((resolve28) => {
36091
36295
  const child = spawn5(cmd, args, {
36092
36296
  cwd: opts.cwd,
36093
36297
  env: opts.env ?? process.env,
@@ -36099,7 +36303,7 @@ function runSpawn(cmd, args, opts = {}) {
36099
36303
  child.on("error", (err) => {
36100
36304
  if (!settled) {
36101
36305
  settled = true;
36102
- resolve27({ exitCode: 1, stdout: "", stderr: err.message });
36306
+ resolve28({ exitCode: 1, stdout: "", stderr: err.message });
36103
36307
  }
36104
36308
  });
36105
36309
  child.stdout.on("data", (d) => {
@@ -36111,7 +36315,7 @@ function runSpawn(cmd, args, opts = {}) {
36111
36315
  child.on("exit", (code) => {
36112
36316
  if (!settled) {
36113
36317
  settled = true;
36114
- resolve27({ exitCode: code ?? 1, stdout, stderr });
36318
+ resolve28({ exitCode: code ?? 1, stdout, stderr });
36115
36319
  }
36116
36320
  });
36117
36321
  });
@@ -36134,7 +36338,7 @@ async function detectShellProfile() {
36134
36338
  }
36135
36339
  async function profileContains(profilePath, str) {
36136
36340
  try {
36137
- const content = await readFile27(profilePath, "utf8");
36341
+ const content = await readFile28(profilePath, "utf8");
36138
36342
  return content.includes(str);
36139
36343
  } catch {
36140
36344
  return false;
@@ -37049,7 +37253,7 @@ function registerImportV2Command(program) {
37049
37253
  }
37050
37254
  function registerBuildCommand(program) {
37051
37255
  program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").action(async () => {
37052
- const pkgRoot = resolve26(dirname14(fileURLToPath5(import.meta.url)), "..", "..");
37256
+ const pkgRoot = resolve27(dirname14(fileURLToPath5(import.meta.url)), "..", "..");
37053
37257
  process.stderr.write("\u2699 Building from source...\n");
37054
37258
  const { exitCode } = await runBuild({
37055
37259
  spawnFn: () => spawn6("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),