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