@contentful/experience-design-system-cli 2.32.1-dev-build-b7d2d34.0 → 2.32.1-dev-build-b78fe18.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 +1 -1
- 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/import/tui/WizardApp.d.ts +0 -3
- package/dist/src/index.js +221 -481
- package/dist/src/session/cache-keys.d.ts +1 -1
- package/package.json +6 -6
- 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-and-persist-existing-contentful-entities.d.ts +0 -29
- 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"() {
|
|
@@ -16600,74 +16587,9 @@ var init_path_utils = __esm({
|
|
|
16600
16587
|
}
|
|
16601
16588
|
});
|
|
16602
16589
|
|
|
16603
|
-
// packages/experience-design-system-cli/src/helpers/build-contentful-management-client.ts
|
|
16604
|
-
import { createClient as createClient2 } from "contentful-management";
|
|
16605
|
-
function buildContentfulManagementClient(opts) {
|
|
16606
|
-
return createClient2(
|
|
16607
|
-
{
|
|
16608
|
-
accessToken: opts.cmaToken,
|
|
16609
|
-
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
16610
|
-
},
|
|
16611
|
-
{ type: "plain" }
|
|
16612
|
-
);
|
|
16613
|
-
}
|
|
16614
|
-
var init_build_contentful_management_client = __esm({
|
|
16615
|
-
"packages/experience-design-system-cli/src/helpers/build-contentful-management-client.ts"() {
|
|
16616
|
-
"use strict";
|
|
16617
|
-
init_host_utils();
|
|
16618
|
-
}
|
|
16619
|
-
});
|
|
16620
|
-
|
|
16621
|
-
// packages/experience-design-system-cli/src/helpers/fetch-existing-contentful-entities.ts
|
|
16622
|
-
import { fetchAll } from "contentful-management";
|
|
16623
|
-
async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
16624
|
-
const scope = { spaceId: params.spaceId, environmentId: params.environmentId, query: {} };
|
|
16625
|
-
const components = await fetchAll(client2.component.getMany, scope);
|
|
16626
|
-
const tokens = await fetchAll(client2.designToken.getMany, scope);
|
|
16627
|
-
return { components, tokens };
|
|
16628
|
-
}
|
|
16629
|
-
var init_fetch_existing_contentful_entities = __esm({
|
|
16630
|
-
"packages/experience-design-system-cli/src/helpers/fetch-existing-contentful-entities.ts"() {
|
|
16631
|
-
"use strict";
|
|
16632
|
-
}
|
|
16633
|
-
});
|
|
16634
|
-
|
|
16635
|
-
// packages/experience-design-system-cli/src/helpers/fetch-and-persist-existing-contentful-entities.ts
|
|
16636
|
-
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
16637
|
-
import { join as join18 } from "node:path";
|
|
16638
|
-
async function fetchAndPersistExistingContentfulEntities(params) {
|
|
16639
|
-
const t0 = Date.now();
|
|
16640
|
-
try {
|
|
16641
|
-
const client2 = buildContentfulManagementClient({
|
|
16642
|
-
cmaToken: params.cmaToken,
|
|
16643
|
-
...params.host ? { host: params.host } : {}
|
|
16644
|
-
});
|
|
16645
|
-
const entities = await fetchExistingContentfulEntitiesFromContentful(client2, {
|
|
16646
|
-
spaceId: params.spaceId,
|
|
16647
|
-
environmentId: params.environmentId
|
|
16648
|
-
});
|
|
16649
|
-
const path = join18(params.outDir, ".existing-entities.json");
|
|
16650
|
-
await writeFile5(path, JSON.stringify(entities, null, 2), "utf8");
|
|
16651
|
-
return { ok: true, path, durationMs: Date.now() - t0, entities };
|
|
16652
|
-
} catch (error) {
|
|
16653
|
-
return {
|
|
16654
|
-
ok: false,
|
|
16655
|
-
durationMs: Date.now() - t0,
|
|
16656
|
-
error: error instanceof Error ? error.message : String(error)
|
|
16657
|
-
};
|
|
16658
|
-
}
|
|
16659
|
-
}
|
|
16660
|
-
var init_fetch_and_persist_existing_contentful_entities = __esm({
|
|
16661
|
-
"packages/experience-design-system-cli/src/helpers/fetch-and-persist-existing-contentful-entities.ts"() {
|
|
16662
|
-
"use strict";
|
|
16663
|
-
init_build_contentful_management_client();
|
|
16664
|
-
init_fetch_existing_contentful_entities();
|
|
16665
|
-
}
|
|
16666
|
-
});
|
|
16667
|
-
|
|
16668
16590
|
// packages/experience-design-system-cli/src/runs/save-path-resolver.ts
|
|
16669
16591
|
import { access as access8 } from "node:fs/promises";
|
|
16670
|
-
import { join as
|
|
16592
|
+
import { join as join19 } from "node:path";
|
|
16671
16593
|
function isConflictMode(value) {
|
|
16672
16594
|
return CONFLICT_MODES.includes(value);
|
|
16673
16595
|
}
|
|
@@ -16675,7 +16597,7 @@ async function listConflictingFiles(path) {
|
|
|
16675
16597
|
const conflicts = [];
|
|
16676
16598
|
for (const name of SAVE_FILES) {
|
|
16677
16599
|
try {
|
|
16678
|
-
await access8(
|
|
16600
|
+
await access8(join19(path, name));
|
|
16679
16601
|
conflicts.push(name);
|
|
16680
16602
|
} catch {
|
|
16681
16603
|
}
|
|
@@ -16695,7 +16617,7 @@ function buildTimestampedSubdir(base, now = /* @__PURE__ */ new Date()) {
|
|
|
16695
16617
|
const hh = pad2(now.getHours());
|
|
16696
16618
|
const mm = pad2(now.getMinutes());
|
|
16697
16619
|
const ss = pad2(now.getSeconds());
|
|
16698
|
-
return
|
|
16620
|
+
return join19(base, `dsi-${y}${m}${d}-${hh}${mm}${ss}`);
|
|
16699
16621
|
}
|
|
16700
16622
|
async function resolveSavePath(path, options = {}) {
|
|
16701
16623
|
const conflicts = await listConflictingFiles(path);
|
|
@@ -16725,8 +16647,8 @@ var init_save_path_resolver = __esm({
|
|
|
16725
16647
|
});
|
|
16726
16648
|
|
|
16727
16649
|
// packages/experience-design-system-cli/src/runs/store.ts
|
|
16728
|
-
import { readFile as
|
|
16729
|
-
import { join as
|
|
16650
|
+
import { readFile as readFile22, writeFile as writeFile6, mkdir as mkdir6, rename } from "node:fs/promises";
|
|
16651
|
+
import { join as join20 } from "node:path";
|
|
16730
16652
|
import { homedir as homedir7 } from "node:os";
|
|
16731
16653
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
16732
16654
|
function runsFilePath() {
|
|
@@ -16769,7 +16691,7 @@ function migrateRecord(rec) {
|
|
|
16769
16691
|
}
|
|
16770
16692
|
async function readFileMaybe() {
|
|
16771
16693
|
try {
|
|
16772
|
-
const raw = await
|
|
16694
|
+
const raw = await readFile22(RUNS_PATH, "utf8");
|
|
16773
16695
|
const parsed = JSON.parse(raw);
|
|
16774
16696
|
if (!READABLE_VERSIONS.has(parsed.version)) {
|
|
16775
16697
|
throw new Error(
|
|
@@ -16847,8 +16769,8 @@ var init_store = __esm({
|
|
|
16847
16769
|
RUNS_FILE_VERSION = 3;
|
|
16848
16770
|
RUNS_FILE_CAP = 200;
|
|
16849
16771
|
READABLE_VERSIONS = /* @__PURE__ */ new Set([1, 2, 3]);
|
|
16850
|
-
RUNS_DIR =
|
|
16851
|
-
RUNS_PATH =
|
|
16772
|
+
RUNS_DIR = join20(homedir7(), ".config", "experiences");
|
|
16773
|
+
RUNS_PATH = join20(RUNS_DIR, "runs.json");
|
|
16852
16774
|
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
16853
16775
|
}
|
|
16854
16776
|
});
|
|
@@ -16912,7 +16834,7 @@ var init_run_teaser = __esm({
|
|
|
16912
16834
|
import { useState as useState9, useEffect as useEffect3 } from "react";
|
|
16913
16835
|
import { Box as Box20, Text as Text20 } from "ink";
|
|
16914
16836
|
import { readdirSync as readdirSync3 } from "node:fs";
|
|
16915
|
-
import { dirname as dirname13, basename as basename6, join as
|
|
16837
|
+
import { dirname as dirname13, basename as basename6, join as join21 } from "node:path";
|
|
16916
16838
|
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
16917
16839
|
function autocomplete(partial) {
|
|
16918
16840
|
if (!partial) return null;
|
|
@@ -16927,13 +16849,13 @@ function autocomplete(partial) {
|
|
|
16927
16849
|
}
|
|
16928
16850
|
const matches = entries.filter((e) => e.startsWith(base));
|
|
16929
16851
|
if (matches.length === 0) return null;
|
|
16930
|
-
if (matches.length === 1) return
|
|
16852
|
+
if (matches.length === 1) return join21(dir, matches[0]);
|
|
16931
16853
|
let prefix = matches[0];
|
|
16932
16854
|
for (const m of matches) {
|
|
16933
16855
|
while (!m.startsWith(prefix)) prefix = prefix.slice(0, -1);
|
|
16934
16856
|
if (!prefix) break;
|
|
16935
16857
|
}
|
|
16936
|
-
return prefix.length > base.length ?
|
|
16858
|
+
return prefix.length > base.length ? join21(dir, prefix) : null;
|
|
16937
16859
|
}
|
|
16938
16860
|
function PathPrompt({
|
|
16939
16861
|
defaultPath,
|
|
@@ -17365,8 +17287,8 @@ var init_save_conflict = __esm({
|
|
|
17365
17287
|
|
|
17366
17288
|
// packages/experience-design-system-cli/src/runs/fingerprint.ts
|
|
17367
17289
|
import { createHash as createHash4 } from "node:crypto";
|
|
17368
|
-
import { readFile as
|
|
17369
|
-
import { resolve as
|
|
17290
|
+
import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
|
|
17291
|
+
import { resolve as resolve22 } from "node:path";
|
|
17370
17292
|
function rowField(row, key) {
|
|
17371
17293
|
const v = row[key];
|
|
17372
17294
|
return typeof v === "string" ? v : null;
|
|
@@ -17382,7 +17304,7 @@ async function buildSourceFingerprint(opts) {
|
|
|
17382
17304
|
const sourcePath = rowField(row, "source_path");
|
|
17383
17305
|
const name = rowField(row, "name");
|
|
17384
17306
|
if (!sourcePath) continue;
|
|
17385
|
-
const abs =
|
|
17307
|
+
const abs = resolve22(sourcePath);
|
|
17386
17308
|
if (seen.has(abs)) continue;
|
|
17387
17309
|
seen.add(abs);
|
|
17388
17310
|
try {
|
|
@@ -17397,10 +17319,10 @@ async function buildSourceFingerprint(opts) {
|
|
|
17397
17319
|
let rawTokensMtime = null;
|
|
17398
17320
|
let rawTokensContentHash = null;
|
|
17399
17321
|
if (opts.rawTokensPath) {
|
|
17400
|
-
const abs =
|
|
17322
|
+
const abs = resolve22(opts.rawTokensPath);
|
|
17401
17323
|
rawTokensPath = abs;
|
|
17402
17324
|
try {
|
|
17403
|
-
const [st, buf] = await Promise.all([stat5(abs),
|
|
17325
|
+
const [st, buf] = await Promise.all([stat5(abs), readFile23(abs)]);
|
|
17404
17326
|
rawTokensMtime = st.mtime.toISOString();
|
|
17405
17327
|
rawTokensContentHash = sha256Hex(buf);
|
|
17406
17328
|
} catch {
|
|
@@ -17531,7 +17453,7 @@ var init_WelcomeStep = __esm({
|
|
|
17531
17453
|
import { useState as useState13, useEffect as useEffect5 } from "react";
|
|
17532
17454
|
import { Box as Box25, Text as Text25 } from "ink";
|
|
17533
17455
|
import { promises as fs } from "node:fs";
|
|
17534
|
-
import { join as
|
|
17456
|
+
import { join as join22 } from "node:path";
|
|
17535
17457
|
import { jsx as jsx25, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
17536
17458
|
async function countFiles(dir) {
|
|
17537
17459
|
const counts = {
|
|
@@ -17555,7 +17477,7 @@ async function countFiles(dir) {
|
|
|
17555
17477
|
await Promise.all(
|
|
17556
17478
|
entries.map(async (entry) => {
|
|
17557
17479
|
if (IGNORE_DIRS.has(entry)) return;
|
|
17558
|
-
const full =
|
|
17480
|
+
const full = join22(current, entry);
|
|
17559
17481
|
let stat8;
|
|
17560
17482
|
try {
|
|
17561
17483
|
stat8 = await fs.stat(full);
|
|
@@ -18013,11 +17935,8 @@ function CredentialsStep({
|
|
|
18013
17935
|
"\u2713 ",
|
|
18014
17936
|
summary
|
|
18015
17937
|
] }),
|
|
18016
|
-
/* @__PURE__ */
|
|
18017
|
-
|
|
18018
|
-
!(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)." }),
|
|
18019
|
-
!(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." })
|
|
18020
|
-
] }),
|
|
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." }),
|
|
18021
17940
|
/* @__PURE__ */ jsxs28(Box28, { flexDirection: "column", gap: 0, marginTop: 1, children: [
|
|
18022
17941
|
renderField("Space ID", spaceId, "spaceId"),
|
|
18023
17942
|
renderField("Environment", environmentId, "environmentId"),
|
|
@@ -19184,9 +19103,9 @@ function spawnGenerateChild(opts) {
|
|
|
19184
19103
|
stderr += chunk;
|
|
19185
19104
|
opts.onStderr?.(chunk);
|
|
19186
19105
|
});
|
|
19187
|
-
const donePromise = new Promise((
|
|
19106
|
+
const donePromise = new Promise((resolve27) => {
|
|
19188
19107
|
child.on("close", (code, signal) => {
|
|
19189
|
-
|
|
19108
|
+
resolve27({
|
|
19190
19109
|
exitCode: code ?? 0,
|
|
19191
19110
|
signal: signal ?? null,
|
|
19192
19111
|
stdout,
|
|
@@ -19194,7 +19113,7 @@ function spawnGenerateChild(opts) {
|
|
|
19194
19113
|
});
|
|
19195
19114
|
});
|
|
19196
19115
|
child.on("error", (err) => {
|
|
19197
|
-
|
|
19116
|
+
resolve27({
|
|
19198
19117
|
exitCode: 1,
|
|
19199
19118
|
signal: null,
|
|
19200
19119
|
stdout,
|
|
@@ -27737,9 +27656,9 @@ __export(WizardApp_exports, {
|
|
|
27737
27656
|
});
|
|
27738
27657
|
import { useEffect as useEffect15, useRef as useRef9, useState as useState28 } from "react";
|
|
27739
27658
|
import { Box as Box49, Text as Text51, useStdout as useStdout8 } from "ink";
|
|
27740
|
-
import { join as
|
|
27659
|
+
import { join as join23, resolve as resolve23 } from "node:path";
|
|
27741
27660
|
import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
|
|
27742
|
-
import { access as access9, readFile as
|
|
27661
|
+
import { access as access9, readFile as readFile24, stat as stat6 } from "node:fs/promises";
|
|
27743
27662
|
import { tmpdir } from "node:os";
|
|
27744
27663
|
import { execFile as execFile4, spawn as spawn4 } from "node:child_process";
|
|
27745
27664
|
import { mkdir as mkdir7 } from "node:fs/promises";
|
|
@@ -27751,7 +27670,6 @@ function buildSelectAgentArgs(opts) {
|
|
|
27751
27670
|
if (opts.bedrock) args.push("--bedrock");
|
|
27752
27671
|
if (opts.selectPromptPath) args.push("--select-prompt-path", opts.selectPromptPath);
|
|
27753
27672
|
if (opts.noCache) args.push("--no-cache");
|
|
27754
|
-
if (opts.existingEntitiesPath) args.push("--existing-entities-path", opts.existingEntitiesPath);
|
|
27755
27673
|
return args;
|
|
27756
27674
|
}
|
|
27757
27675
|
function parseAutoFilterProgressLine(line) {
|
|
@@ -27788,7 +27706,6 @@ function buildGenerateComponentsArgs(opts) {
|
|
|
27788
27706
|
if (opts.bedrock) args.push("--bedrock");
|
|
27789
27707
|
if (opts.noCache) args.push("--no-cache");
|
|
27790
27708
|
if (opts.generatePromptPath) args.push("--generate-prompt-path", opts.generatePromptPath);
|
|
27791
|
-
if (opts.existingEntitiesPath) args.push("--existing-entities-path", opts.existingEntitiesPath);
|
|
27792
27709
|
return args;
|
|
27793
27710
|
}
|
|
27794
27711
|
function buildMapTokensArgs(opts) {
|
|
@@ -27796,7 +27713,6 @@ function buildMapTokensArgs(opts) {
|
|
|
27796
27713
|
if (opts.model) args.push("--model", opts.model);
|
|
27797
27714
|
if (opts.noCache) args.push("--no-cache");
|
|
27798
27715
|
if (opts.skipAgent) args.push("--skip-agent");
|
|
27799
|
-
if (opts.existingEntitiesPath) args.push("--existing-entities-path", opts.existingEntitiesPath);
|
|
27800
27716
|
return args;
|
|
27801
27717
|
}
|
|
27802
27718
|
function shouldRunMapTokens(opts) {
|
|
@@ -27886,8 +27802,8 @@ function WizardApp({
|
|
|
27886
27802
|
const rawTokensEntryReady = !modifyEntryReady && !pushFromPickerReady && !!initialRawTokensPath;
|
|
27887
27803
|
const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
|
|
27888
27804
|
const initialStepResolved = modifyEntryReady ? "final-review" : pushFromPickerReady ? "push-from-picker" : rawTokensEntryReady ? "generating-tokens" : initialProjectPath ? "token-input" : "welcome";
|
|
27889
|
-
const initialOutDir = initialProjectPath ?
|
|
27890
|
-
const initialTokensPath = (modifyEntryReady || pushFromPickerReady) && initialOutDir && seedTokenSessionId ?
|
|
27805
|
+
const initialOutDir = initialProjectPath ? join23(resolve23(initialProjectPath), ".contentful") : "";
|
|
27806
|
+
const initialTokensPath = (modifyEntryReady || pushFromPickerReady) && initialOutDir && seedTokenSessionId ? join23(initialOutDir, "tokens.json") : "";
|
|
27891
27807
|
const [state, setState] = useState28({
|
|
27892
27808
|
step: modifyEntryReady || rawTokensEntryReady || pushFromPickerReady ? initialStepResolved : initialRuns && initialRuns.length > 0 ? "run-picker" : initialStepResolved,
|
|
27893
27809
|
agent: initialAgent ?? "claude",
|
|
@@ -27940,7 +27856,6 @@ function WizardApp({
|
|
|
27940
27856
|
generatePrefetchError: null,
|
|
27941
27857
|
mapTokensEligible: null,
|
|
27942
27858
|
credentialsSkipped: false,
|
|
27943
|
-
existingEntitiesPath: null,
|
|
27944
27859
|
lastRunId: null,
|
|
27945
27860
|
finalizeErrorBanner: null,
|
|
27946
27861
|
finalReviewPassed: modifyEntryReady || pushFromPickerReady,
|
|
@@ -28055,7 +27970,7 @@ If you are using AWS Bedrock, run:
|
|
|
28055
27970
|
}
|
|
28056
27971
|
const sessionMatch = /^session=(.+)$/m.exec(result.stdout);
|
|
28057
27972
|
const tokenSessionId = sessionMatch ? sessionMatch[1].trim() : null;
|
|
28058
|
-
const tokensPath =
|
|
27973
|
+
const tokensPath = join23(outDir, "tokens.json");
|
|
28059
27974
|
const printArgs = ["print", "tokens", "--out", tokensPath];
|
|
28060
27975
|
if (tokenSessionId) printArgs.push("--session", tokenSessionId);
|
|
28061
27976
|
const r = await runCli2(printArgs);
|
|
@@ -28075,7 +27990,7 @@ If you are using AWS Bedrock, run:
|
|
|
28075
27990
|
tokenCount,
|
|
28076
27991
|
skipComponents: true,
|
|
28077
27992
|
acceptedCount: 0,
|
|
28078
|
-
outDir: state.outDir ||
|
|
27993
|
+
outDir: state.outDir || join23(process.cwd(), ".contentful")
|
|
28079
27994
|
});
|
|
28080
27995
|
if (noPush) {
|
|
28081
27996
|
void startSaveFlow();
|
|
@@ -28127,8 +28042,7 @@ If you are using AWS Bedrock, run:
|
|
|
28127
28042
|
agent: state.agent,
|
|
28128
28043
|
...state.agentModel ? { model: state.agentModel } : {},
|
|
28129
28044
|
noCache: effectiveNoCache,
|
|
28130
|
-
skipAgent: skipMapTokens
|
|
28131
|
-
...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {}
|
|
28045
|
+
skipAgent: skipMapTokens
|
|
28132
28046
|
});
|
|
28133
28047
|
const result = await runCli2(args);
|
|
28134
28048
|
if (result.exitCode !== 0) {
|
|
@@ -28142,7 +28056,7 @@ If you are using AWS Bedrock, run:
|
|
|
28142
28056
|
return true;
|
|
28143
28057
|
};
|
|
28144
28058
|
const runExtract = async (projectPath) => {
|
|
28145
|
-
const outDir =
|
|
28059
|
+
const outDir = join23(resolve23(projectPath), ".contentful");
|
|
28146
28060
|
update({ step: "extracting", outDir, extractProgress: null, compositionPhase: null });
|
|
28147
28061
|
const r = await new Promise((res) => {
|
|
28148
28062
|
const extractArgs = [findCliPath(), "analyze", "extract", "--project", projectPath];
|
|
@@ -28249,8 +28163,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28249
28163
|
...state.agentModel ? { model: state.agentModel } : {},
|
|
28250
28164
|
...state.bedrock ? { bedrock: true } : {},
|
|
28251
28165
|
selectPromptPath,
|
|
28252
|
-
noCache
|
|
28253
|
-
...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {}
|
|
28166
|
+
noCache
|
|
28254
28167
|
});
|
|
28255
28168
|
const child = spawn4("node", [findCliPath(), ...args]);
|
|
28256
28169
|
autoFilterChildRef.current = child;
|
|
@@ -28348,8 +28261,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28348
28261
|
agent: state.agent,
|
|
28349
28262
|
...state.agentModel ? { model: state.agentModel } : {},
|
|
28350
28263
|
...state.bedrock ? { bedrock: true } : {},
|
|
28351
|
-
noCache: effectiveNoCache
|
|
28352
|
-
...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {}
|
|
28264
|
+
noCache: effectiveNoCache
|
|
28353
28265
|
})
|
|
28354
28266
|
];
|
|
28355
28267
|
let progressCursor = null;
|
|
@@ -28420,8 +28332,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28420
28332
|
...state.agentModel ? { model: state.agentModel } : {},
|
|
28421
28333
|
...state.bedrock ? { bedrock: true } : {},
|
|
28422
28334
|
noCache: effectiveNoCache,
|
|
28423
|
-
generatePromptPath
|
|
28424
|
-
...state.existingEntitiesPath ? { existingEntitiesPath: state.existingEntitiesPath } : {}
|
|
28335
|
+
generatePromptPath
|
|
28425
28336
|
})
|
|
28426
28337
|
];
|
|
28427
28338
|
let progressCursor = state.generateProgress;
|
|
@@ -28461,7 +28372,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28461
28372
|
if (await runMapTokens2(mappedSessionId)) update({ step: "final-review" });
|
|
28462
28373
|
};
|
|
28463
28374
|
const advanceToPushFlow = (generatedAcceptedCount) => {
|
|
28464
|
-
update({ generatedAcceptedCount, step: "
|
|
28375
|
+
update({ generatedAcceptedCount, step: "credentials" });
|
|
28465
28376
|
};
|
|
28466
28377
|
const runEditFromPreview = async () => {
|
|
28467
28378
|
update({ step: "final-review" });
|
|
@@ -28532,24 +28443,6 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28532
28443
|
}
|
|
28533
28444
|
};
|
|
28534
28445
|
const advanceAfterCredentialsValidated = async () => {
|
|
28535
|
-
if (!state.credentialsSkipped && state.spaceId && state.environmentId && state.cmaToken && state.projectPath) {
|
|
28536
|
-
const outDir = join24(resolve24(state.projectPath), ".contentful");
|
|
28537
|
-
await mkdir7(outDir, { recursive: true });
|
|
28538
|
-
const result = await fetchAndPersistExistingContentfulEntities({
|
|
28539
|
-
spaceId: state.spaceId,
|
|
28540
|
-
environmentId: state.environmentId,
|
|
28541
|
-
cmaToken: state.cmaToken,
|
|
28542
|
-
...state.host ? { host: state.host } : {},
|
|
28543
|
-
outDir
|
|
28544
|
-
});
|
|
28545
|
-
if (result.ok) {
|
|
28546
|
-
update({ existingEntitiesPath: result.path });
|
|
28547
|
-
}
|
|
28548
|
-
}
|
|
28549
|
-
if (!sessionRef.current.extractSessionId && state.projectPath) {
|
|
28550
|
-
void runExtract(state.projectPath);
|
|
28551
|
-
return;
|
|
28552
|
-
}
|
|
28553
28446
|
if (shouldSkipFinalReviewAfterCredentials(state)) {
|
|
28554
28447
|
update({ step: "push-decision-gate" });
|
|
28555
28448
|
return;
|
|
@@ -28905,7 +28798,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28905
28798
|
};
|
|
28906
28799
|
const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
|
|
28907
28800
|
update({ step: "printing" });
|
|
28908
|
-
const componentsPath =
|
|
28801
|
+
const componentsPath = join23(outDir, "components.json");
|
|
28909
28802
|
const printArgs = ["print", "components", "--out", componentsPath];
|
|
28910
28803
|
if (extractSessionId) printArgs.push("--session", extractSessionId);
|
|
28911
28804
|
if (opts.allowEmpty) printArgs.push("--allow-empty");
|
|
@@ -28921,7 +28814,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28921
28814
|
let emittedTokensPath;
|
|
28922
28815
|
let emittedTokenCount;
|
|
28923
28816
|
if (opts.tokenSessionId) {
|
|
28924
|
-
const tokensOut =
|
|
28817
|
+
const tokensOut = join23(outDir, "tokens.json");
|
|
28925
28818
|
const tokenArgs = ["print", "tokens", "--out", tokensOut, "--session", opts.tokenSessionId];
|
|
28926
28819
|
const tr = await runCli2(tokenArgs);
|
|
28927
28820
|
if (tr.exitCode !== 0) {
|
|
@@ -29008,8 +28901,8 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
29008
28901
|
);
|
|
29009
28902
|
}
|
|
29010
28903
|
try {
|
|
29011
|
-
const componentsBuf = await
|
|
29012
|
-
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;
|
|
29013
28906
|
savedFingerprint = buildSavedFingerprint({
|
|
29014
28907
|
componentsJson: componentsBuf,
|
|
29015
28908
|
tokensJson: tokensBuf
|
|
@@ -29050,7 +28943,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
29050
28943
|
if (state.step === "generating-tokens") {
|
|
29051
28944
|
if (tokenReuseChecked.current) return;
|
|
29052
28945
|
tokenReuseChecked.current = true;
|
|
29053
|
-
const existingTokensPath =
|
|
28946
|
+
const existingTokensPath = join23(state.outDir, "tokens.json");
|
|
29054
28947
|
(async () => {
|
|
29055
28948
|
try {
|
|
29056
28949
|
await access9(existingTokensPath);
|
|
@@ -29126,7 +29019,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
29126
29019
|
{
|
|
29127
29020
|
onContinue: (path) => {
|
|
29128
29021
|
const projectPath = normalizePath(path);
|
|
29129
|
-
const outDir =
|
|
29022
|
+
const outDir = join23(projectPath, ".contentful");
|
|
29130
29023
|
update({ step: "token-input", projectPath, outDir });
|
|
29131
29024
|
},
|
|
29132
29025
|
onQuit: () => process.exit(0)
|
|
@@ -29191,7 +29084,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
29191
29084
|
{
|
|
29192
29085
|
projectPath: state.projectPath,
|
|
29193
29086
|
onConfirm: (path) => {
|
|
29194
|
-
|
|
29087
|
+
void runExtract(path);
|
|
29195
29088
|
},
|
|
29196
29089
|
onSkipComponents: () => {
|
|
29197
29090
|
if (noPush) {
|
|
@@ -29275,7 +29168,12 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
29275
29168
|
}
|
|
29276
29169
|
return;
|
|
29277
29170
|
}
|
|
29278
|
-
|
|
29171
|
+
if (acceptedCount > 0 && !noPush) {
|
|
29172
|
+
if (await runAgentAuthCheck("credentials")) {
|
|
29173
|
+
startGeneratePrefetch(sid, state.tokensPath);
|
|
29174
|
+
}
|
|
29175
|
+
}
|
|
29176
|
+
update({ step: "credentials" });
|
|
29279
29177
|
},
|
|
29280
29178
|
onAdvanceToPushFlow: (count) => {
|
|
29281
29179
|
update({ acceptedCount: count, autoRejectedCount: 0 });
|
|
@@ -29746,11 +29644,10 @@ var init_WizardApp = __esm({
|
|
|
29746
29644
|
init_path_utils();
|
|
29747
29645
|
init_host_utils();
|
|
29748
29646
|
init_credentials_store();
|
|
29749
|
-
init_fetch_and_persist_existing_contentful_entities();
|
|
29750
29647
|
init_wizard_state_transitions();
|
|
29751
29648
|
init_cycle_auto_reject();
|
|
29752
29649
|
init_cli_path();
|
|
29753
|
-
WIZARD_LOG =
|
|
29650
|
+
WIZARD_LOG = join23(tmpdir(), "experiences-import-wizard.log");
|
|
29754
29651
|
}
|
|
29755
29652
|
});
|
|
29756
29653
|
|
|
@@ -29761,8 +29658,8 @@ __export(staleness_exports, {
|
|
|
29761
29658
|
formatStalenessDetail: () => formatStalenessDetail,
|
|
29762
29659
|
shortStalenessSummary: () => shortStalenessSummary
|
|
29763
29660
|
});
|
|
29764
|
-
import { readFile as
|
|
29765
|
-
import { join as
|
|
29661
|
+
import { readFile as readFile25, stat as stat7 } from "node:fs/promises";
|
|
29662
|
+
import { join as join24 } from "node:path";
|
|
29766
29663
|
async function checkRunStaleness(run) {
|
|
29767
29664
|
if (!run.sourceFingerprint) return { ...UNKNOWN };
|
|
29768
29665
|
const result = {
|
|
@@ -29788,7 +29685,7 @@ async function checkRunStaleness(run) {
|
|
|
29788
29685
|
if (run.sourceFingerprint.rawTokensPath) {
|
|
29789
29686
|
const absPath = run.sourceFingerprint.rawTokensPath;
|
|
29790
29687
|
try {
|
|
29791
|
-
const [st, buf] = await Promise.all([stat7(absPath),
|
|
29688
|
+
const [st, buf] = await Promise.all([stat7(absPath), readFile25(absPath)]);
|
|
29792
29689
|
const mtime = st.mtime.toISOString();
|
|
29793
29690
|
const hash = sha256Hex(buf);
|
|
29794
29691
|
const mtimeChanged = run.sourceFingerprint.rawTokensMtime !== null && mtime !== run.sourceFingerprint.rawTokensMtime;
|
|
@@ -29804,9 +29701,9 @@ async function checkRunStaleness(run) {
|
|
|
29804
29701
|
}
|
|
29805
29702
|
if (run.savedFingerprint) {
|
|
29806
29703
|
if (run.savedFingerprint.componentsJsonHash !== null) {
|
|
29807
|
-
const compPath =
|
|
29704
|
+
const compPath = join24(run.savePath, "components.json");
|
|
29808
29705
|
try {
|
|
29809
|
-
const buf = await
|
|
29706
|
+
const buf = await readFile25(compPath);
|
|
29810
29707
|
if (sha256Hex(buf) !== run.savedFingerprint.componentsJsonHash) {
|
|
29811
29708
|
result.savedComponentsEdited = true;
|
|
29812
29709
|
result.stale = true;
|
|
@@ -29817,9 +29714,9 @@ async function checkRunStaleness(run) {
|
|
|
29817
29714
|
}
|
|
29818
29715
|
}
|
|
29819
29716
|
if (run.savedFingerprint.tokensJsonHash !== null) {
|
|
29820
|
-
const tokensPath = run.tokensPath ??
|
|
29717
|
+
const tokensPath = run.tokensPath ?? join24(run.savePath, "tokens.json");
|
|
29821
29718
|
try {
|
|
29822
|
-
const buf = await
|
|
29719
|
+
const buf = await readFile25(tokensPath);
|
|
29823
29720
|
if (sha256Hex(buf) !== run.savedFingerprint.tokensJsonHash) {
|
|
29824
29721
|
result.savedTokensEdited = true;
|
|
29825
29722
|
result.stale = true;
|
|
@@ -29886,7 +29783,7 @@ async function promptForPushCredentials(opts = {}) {
|
|
|
29886
29783
|
const { render: render7, Box: Box50, Text: Text52 } = await import("ink");
|
|
29887
29784
|
const { useState: useState29 } = await import("react");
|
|
29888
29785
|
const { CredentialsStep: CredentialsStep2 } = await Promise.resolve().then(() => (init_CredentialsStep(), CredentialsStep_exports));
|
|
29889
|
-
return new Promise((
|
|
29786
|
+
return new Promise((resolve27, reject) => {
|
|
29890
29787
|
let app = null;
|
|
29891
29788
|
function App2() {
|
|
29892
29789
|
const [done, setDone] = useState29(false);
|
|
@@ -29895,7 +29792,7 @@ async function promptForPushCredentials(opts = {}) {
|
|
|
29895
29792
|
setDone(true);
|
|
29896
29793
|
queueMicrotask(() => {
|
|
29897
29794
|
app?.unmount();
|
|
29898
|
-
|
|
29795
|
+
resolve27({ spaceId, environmentId, cmaToken, host });
|
|
29899
29796
|
});
|
|
29900
29797
|
};
|
|
29901
29798
|
if (done) {
|
|
@@ -29927,14 +29824,14 @@ var init_push_creds_prompt = __esm({
|
|
|
29927
29824
|
// packages/experience-design-system-cli/src/program.ts
|
|
29928
29825
|
import { spawn as spawn6 } from "node:child_process";
|
|
29929
29826
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
29930
|
-
import { dirname as dirname14, join as
|
|
29827
|
+
import { dirname as dirname14, join as join27, resolve as resolve26 } from "node:path";
|
|
29931
29828
|
import { readFileSync as readFileSync10 } from "node:fs";
|
|
29932
29829
|
import { Command } from "commander";
|
|
29933
29830
|
|
|
29934
29831
|
// packages/experience-design-system-cli/src/analyze/command.ts
|
|
29935
29832
|
import { createElement as createElement3 } from "react";
|
|
29936
29833
|
import { render as render3 } from "ink";
|
|
29937
|
-
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";
|
|
29938
29835
|
import { isAbsolute as isAbsolute4, join as join15, relative as relative3, resolve as resolve15 } from "node:path";
|
|
29939
29836
|
|
|
29940
29837
|
// packages/experience-design-system-cli/src/lib/agent-model-options.ts
|
|
@@ -30061,104 +29958,6 @@ init_command2();
|
|
|
30061
29958
|
// packages/experience-design-system-cli/src/analyze/select-agent/command.ts
|
|
30062
29959
|
init_db();
|
|
30063
29960
|
init_cache_keys();
|
|
30064
|
-
|
|
30065
|
-
// packages/experience-design-system-cli/src/helpers/read-existing-contentful-entities-from-session.ts
|
|
30066
|
-
import { readFile as readFile13 } from "node:fs/promises";
|
|
30067
|
-
async function readExistingContentfulEntitiesFromSession(path) {
|
|
30068
|
-
if (!path) return void 0;
|
|
30069
|
-
try {
|
|
30070
|
-
const raw = await readFile13(path, "utf8");
|
|
30071
|
-
const parsed = JSON.parse(raw);
|
|
30072
|
-
if (!Array.isArray(parsed.components) || !Array.isArray(parsed.tokens)) return void 0;
|
|
30073
|
-
return parsed;
|
|
30074
|
-
} catch {
|
|
30075
|
-
return void 0;
|
|
30076
|
-
}
|
|
30077
|
-
}
|
|
30078
|
-
|
|
30079
|
-
// packages/experience-design-system-cli/src/helpers/find-nearly-matching-component.ts
|
|
30080
|
-
var MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH = 2;
|
|
30081
|
-
function findNearlyMatchingComponent(components, codebaseName) {
|
|
30082
|
-
const target = simplifyNameForComparison(codebaseName);
|
|
30083
|
-
if (!target) return void 0;
|
|
30084
|
-
let best;
|
|
30085
|
-
for (const c2 of components) {
|
|
30086
|
-
const edits = countCharacterEdits(target, simplifyNameForComparison(c2.name));
|
|
30087
|
-
if (edits > MAX_CHARACTER_EDITS_FOR_LIKELY_MATCH) continue;
|
|
30088
|
-
if (!best || edits < best.edits) best = { component: c2, edits };
|
|
30089
|
-
if (edits === 0) break;
|
|
30090
|
-
}
|
|
30091
|
-
return best?.component;
|
|
30092
|
-
}
|
|
30093
|
-
function simplifyNameForComparison(name) {
|
|
30094
|
-
const stripped = name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
30095
|
-
return stripped.endsWith("s") && stripped.length > 1 ? stripped.slice(0, -1) : stripped;
|
|
30096
|
-
}
|
|
30097
|
-
function countCharacterEdits(a, b) {
|
|
30098
|
-
if (a === b) return 0;
|
|
30099
|
-
if (a.length === 0) return b.length;
|
|
30100
|
-
if (b.length === 0) return a.length;
|
|
30101
|
-
if (a.length > b.length) [a, b] = [b, a];
|
|
30102
|
-
let prev = new Array(a.length + 1);
|
|
30103
|
-
let curr = new Array(a.length + 1);
|
|
30104
|
-
for (let i = 0; i <= a.length; i++) prev[i] = i;
|
|
30105
|
-
for (let j = 1; j <= b.length; j++) {
|
|
30106
|
-
curr[0] = j;
|
|
30107
|
-
for (let i = 1; i <= a.length; i++) {
|
|
30108
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
30109
|
-
curr[i] = Math.min(curr[i - 1] + 1, prev[i] + 1, prev[i - 1] + cost);
|
|
30110
|
-
}
|
|
30111
|
-
[prev, curr] = [curr, prev];
|
|
30112
|
-
}
|
|
30113
|
-
return prev[a.length];
|
|
30114
|
-
}
|
|
30115
|
-
|
|
30116
|
-
// packages/experience-design-system-cli/src/helpers/summarize-existing-contentful-entities.ts
|
|
30117
|
-
function summarizeForSelectAgent(entities) {
|
|
30118
|
-
return {
|
|
30119
|
-
components: entities.components.map((c2) => ({
|
|
30120
|
-
id: c2.sys.id,
|
|
30121
|
-
name: c2.name,
|
|
30122
|
-
description: c2.description
|
|
30123
|
-
})),
|
|
30124
|
-
tokens: summarizeTokens(entities.tokens)
|
|
30125
|
-
};
|
|
30126
|
-
}
|
|
30127
|
-
function summarizeForGenerateAgent(entities, codebaseComponentName) {
|
|
30128
|
-
const match2 = findNearlyMatchingComponent(entities.components, codebaseComponentName);
|
|
30129
|
-
const otherComponents = entities.components.filter((c2) => c2.sys.id !== match2?.sys.id).map((c2) => ({ id: c2.sys.id, name: c2.name }));
|
|
30130
|
-
return {
|
|
30131
|
-
likelyMatch: match2 ? {
|
|
30132
|
-
id: match2.sys.id,
|
|
30133
|
-
name: match2.name,
|
|
30134
|
-
designProperties: match2.designProperties.map((p) => ({
|
|
30135
|
-
id: p.id,
|
|
30136
|
-
name: p.name,
|
|
30137
|
-
type: p.type
|
|
30138
|
-
})),
|
|
30139
|
-
contentProperties: match2.contentProperties.map((p) => ({
|
|
30140
|
-
id: p.id,
|
|
30141
|
-
name: p.name,
|
|
30142
|
-
type: p.type
|
|
30143
|
-
})),
|
|
30144
|
-
slots: (match2.slots ?? []).map((s) => ({ id: s.id, name: s.name }))
|
|
30145
|
-
} : void 0,
|
|
30146
|
-
otherComponents,
|
|
30147
|
-
tokens: summarizeTokens(entities.tokens)
|
|
30148
|
-
};
|
|
30149
|
-
}
|
|
30150
|
-
function summarizeForMapTokens(entities) {
|
|
30151
|
-
return {
|
|
30152
|
-
tokens: entities.tokens.map((t) => ({ id: t.sys.id, name: t.name, type: t.type }))
|
|
30153
|
-
};
|
|
30154
|
-
}
|
|
30155
|
-
function summarizeTokens(tokens) {
|
|
30156
|
-
const kinds = /* @__PURE__ */ new Set();
|
|
30157
|
-
for (const t of tokens) kinds.add(t.type);
|
|
30158
|
-
return { count: tokens.length, kinds: [...kinds].sort() };
|
|
30159
|
-
}
|
|
30160
|
-
|
|
30161
|
-
// packages/experience-design-system-cli/src/analyze/select-agent/command.ts
|
|
30162
29961
|
init_persistence();
|
|
30163
29962
|
init_parser();
|
|
30164
29963
|
init_src();
|
|
@@ -30260,7 +30059,7 @@ var OutputFormatter = class {
|
|
|
30260
30059
|
};
|
|
30261
30060
|
|
|
30262
30061
|
// packages/experience-design-system-cli/src/analyze/select-agent/context-builder.ts
|
|
30263
|
-
import { readFile as
|
|
30062
|
+
import { readFile as readFile13 } from "node:fs/promises";
|
|
30264
30063
|
import { dirname as dirname10, isAbsolute as isAbsolute2, join as join13, relative as relative2, resolve as resolve11, sep } from "node:path";
|
|
30265
30064
|
var SCANNED_FILE_EXTENSIONS = /* @__PURE__ */ new Set([".astro", ".js", ".jsx", ".svelte", ".ts", ".tsx", ".vue"]);
|
|
30266
30065
|
var IMPORT_PATTERN2 = /import\s+(?:type\s+)?(.+?)\s+from\s+['"]([^'"]+)['"]/g;
|
|
@@ -30389,7 +30188,7 @@ async function buildRepoContextIndex(root, filePaths) {
|
|
|
30389
30188
|
absolutePath,
|
|
30390
30189
|
relativePath: toPosixPath(relative2(resolvedRoot, absolutePath)),
|
|
30391
30190
|
directory: dirname10(absolutePath),
|
|
30392
|
-
text: await
|
|
30191
|
+
text: await readFile13(absolutePath, "utf8").catch(() => "")
|
|
30393
30192
|
})
|
|
30394
30193
|
)
|
|
30395
30194
|
);
|
|
@@ -30602,7 +30401,7 @@ function resolveProjectRoot(sessionId2, projectRootFlag) {
|
|
|
30602
30401
|
db.close();
|
|
30603
30402
|
}
|
|
30604
30403
|
}
|
|
30605
|
-
async function selectBatch(agent, model, batch, total, verbose, skillPathOverride
|
|
30404
|
+
async function selectBatch(agent, model, batch, total, verbose, skillPathOverride) {
|
|
30606
30405
|
const prompt2 = await buildPrompt({
|
|
30607
30406
|
skill: "select",
|
|
30608
30407
|
mode: "autonomous",
|
|
@@ -30612,8 +30411,7 @@ async function selectBatch(agent, model, batch, total, verbose, skillPathOverrid
|
|
|
30612
30411
|
2
|
|
30613
30412
|
),
|
|
30614
30413
|
outDir: process.cwd(),
|
|
30615
|
-
skillPathOverride
|
|
30616
|
-
existingComponentsInline
|
|
30414
|
+
skillPathOverride
|
|
30617
30415
|
});
|
|
30618
30416
|
let outputBuf = "";
|
|
30619
30417
|
const formatter = new OutputFormatter(verbose, (s) => {
|
|
@@ -30708,7 +30506,7 @@ ${outputBuf}`);
|
|
|
30708
30506
|
}
|
|
30709
30507
|
return results;
|
|
30710
30508
|
}
|
|
30711
|
-
async function selectAllComponents(agent, model, components, verbose, skillPathOverride,
|
|
30509
|
+
async function selectAllComponents(agent, model, components, verbose, skillPathOverride, cacheConfig = { noCache: true }) {
|
|
30712
30510
|
const concurrency = Number(process.env.EDS_GENERATE_CONCURRENCY ?? DEFAULT_CONCURRENCY);
|
|
30713
30511
|
const batchSize = resolveBatchSize();
|
|
30714
30512
|
const total = components.length;
|
|
@@ -30717,13 +30515,7 @@ async function selectAllComponents(agent, model, components, verbose, skillPathO
|
|
|
30717
30515
|
let cliVersion2 = "";
|
|
30718
30516
|
if (!cacheConfig.noCache) {
|
|
30719
30517
|
try {
|
|
30720
|
-
promptHash = await hashPromptForSkill(
|
|
30721
|
-
"select",
|
|
30722
|
-
agent,
|
|
30723
|
-
model,
|
|
30724
|
-
skillPathOverride,
|
|
30725
|
-
existingComponentsInline ? [hashContent(existingComponentsInline)] : []
|
|
30726
|
-
);
|
|
30518
|
+
promptHash = await hashPromptForSkill("select", agent, model, skillPathOverride);
|
|
30727
30519
|
cliVersion2 = await getCliCacheVersion();
|
|
30728
30520
|
const db = openPipelineDb(cacheConfig.dbPath);
|
|
30729
30521
|
try {
|
|
@@ -30779,15 +30571,7 @@ async function selectAllComponents(agent, model, components, verbose, skillPathO
|
|
|
30779
30571
|
while (nextBatch < batches.length) {
|
|
30780
30572
|
const b = nextBatch++;
|
|
30781
30573
|
const batch = batches[b];
|
|
30782
|
-
const batchResults = await selectBatch(
|
|
30783
|
-
agent,
|
|
30784
|
-
model,
|
|
30785
|
-
batch,
|
|
30786
|
-
total,
|
|
30787
|
-
verbose,
|
|
30788
|
-
skillPathOverride,
|
|
30789
|
-
existingComponentsInline
|
|
30790
|
-
);
|
|
30574
|
+
const batchResults = await selectBatch(agent, model, batch, total, verbose, skillPathOverride);
|
|
30791
30575
|
for (let k = 0; k < batch.length; k++) {
|
|
30792
30576
|
results[batch[k].index] = batchResults[k];
|
|
30793
30577
|
}
|
|
@@ -30823,9 +30607,6 @@ function registerAnalyzeSelectAgentCommand(program) {
|
|
|
30823
30607
|
"--select-prompt-path <path>",
|
|
30824
30608
|
"Path to a custom .md skill prompt for select-agent (bypasses bundled prompt invariants)"
|
|
30825
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(
|
|
30826
|
-
"--existing-entities-path <path>",
|
|
30827
|
-
"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."
|
|
30828
|
-
).option(
|
|
30829
30610
|
"--show-rationale",
|
|
30830
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."
|
|
30831
30612
|
).option("--json", "When used with --show-rationale, emit a JSON array instead of a human-readable table").action(
|
|
@@ -30934,20 +30715,6 @@ function registerAnalyzeSelectAgentCommand(program) {
|
|
|
30934
30715
|
}));
|
|
30935
30716
|
}
|
|
30936
30717
|
}
|
|
30937
|
-
let existingComponentsInline;
|
|
30938
|
-
if (opts.existingEntitiesPath) {
|
|
30939
|
-
const existingContentfulEntities = await readExistingContentfulEntitiesFromSession(
|
|
30940
|
-
resolve12(opts.existingEntitiesPath)
|
|
30941
|
-
);
|
|
30942
|
-
if (existingContentfulEntities) {
|
|
30943
|
-
existingComponentsInline = JSON.stringify(summarizeForSelectAgent(existingContentfulEntities));
|
|
30944
|
-
} else {
|
|
30945
|
-
process.stderr.write(
|
|
30946
|
-
`warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
|
|
30947
|
-
`
|
|
30948
|
-
);
|
|
30949
|
-
}
|
|
30950
|
-
}
|
|
30951
30718
|
if (opts.dryRun) {
|
|
30952
30719
|
if (selectionCandidates.length === 0) {
|
|
30953
30720
|
process.stderr.write(
|
|
@@ -30962,8 +30729,7 @@ function registerAnalyzeSelectAgentCommand(program) {
|
|
|
30962
30729
|
mode: "autonomous",
|
|
30963
30730
|
rawComponentsInline: JSON.stringify([buildComponentData(first)], null, 2),
|
|
30964
30731
|
outDir: process.cwd(),
|
|
30965
|
-
skillPathOverride: selectPromptPath ? resolve12(selectPromptPath) : void 0
|
|
30966
|
-
existingComponentsInline
|
|
30732
|
+
skillPathOverride: selectPromptPath ? resolve12(selectPromptPath) : void 0
|
|
30967
30733
|
});
|
|
30968
30734
|
process.stdout.write(prompt2 + "\n");
|
|
30969
30735
|
await exitWithAnalytics(0);
|
|
@@ -30976,7 +30742,6 @@ function registerAnalyzeSelectAgentCommand(program) {
|
|
|
30976
30742
|
selectionCandidates,
|
|
30977
30743
|
opts.verbose ?? false,
|
|
30978
30744
|
selectPromptPath ? resolve12(selectPromptPath) : void 0,
|
|
30979
|
-
existingComponentsInline,
|
|
30980
30745
|
{ noCache }
|
|
30981
30746
|
);
|
|
30982
30747
|
const decisions = /* @__PURE__ */ new Map();
|
|
@@ -31364,11 +31129,11 @@ ${f.content}`).join("\n\n");
|
|
|
31364
31129
|
}
|
|
31365
31130
|
|
|
31366
31131
|
// packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts
|
|
31367
|
-
import { readFile as
|
|
31132
|
+
import { readFile as readFile14 } from "node:fs/promises";
|
|
31368
31133
|
async function loadUserMap(path) {
|
|
31369
31134
|
let text;
|
|
31370
31135
|
try {
|
|
31371
|
-
text = await
|
|
31136
|
+
text = await readFile14(path, "utf8");
|
|
31372
31137
|
} catch {
|
|
31373
31138
|
return { ok: false, error: `--composition-map: file not found: ${path}` };
|
|
31374
31139
|
}
|
|
@@ -31604,16 +31369,16 @@ var HEAP_CAP_MB = 128;
|
|
|
31604
31369
|
var MAX_INPUT_BYTES = 8 * 1024 * 1024;
|
|
31605
31370
|
function runParserInSandbox(source, ctx, opts = {}) {
|
|
31606
31371
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
31607
|
-
return new Promise((
|
|
31372
|
+
return new Promise((resolve27) => {
|
|
31608
31373
|
let input;
|
|
31609
31374
|
try {
|
|
31610
31375
|
input = JSON.stringify({ source, ctx, timeoutMs });
|
|
31611
31376
|
} catch {
|
|
31612
|
-
|
|
31377
|
+
resolve27({ edges: [], error: "ctx is not serializable" });
|
|
31613
31378
|
return;
|
|
31614
31379
|
}
|
|
31615
31380
|
if (input.length > MAX_INPUT_BYTES) {
|
|
31616
|
-
|
|
31381
|
+
resolve27({ edges: [], error: "parser input exceeds size limit" });
|
|
31617
31382
|
return;
|
|
31618
31383
|
}
|
|
31619
31384
|
let settled = false;
|
|
@@ -31645,7 +31410,7 @@ function runParserInSandbox(source, ctx, opts = {}) {
|
|
|
31645
31410
|
child.kill("SIGKILL");
|
|
31646
31411
|
} catch {
|
|
31647
31412
|
}
|
|
31648
|
-
|
|
31413
|
+
resolve27(r);
|
|
31649
31414
|
};
|
|
31650
31415
|
const timer = setTimeout(
|
|
31651
31416
|
() => done({ edges: [], error: `parser timed out after ${timeoutMs}ms` }),
|
|
@@ -31857,7 +31622,7 @@ ${loadPrompt("composition-parser-repair-error.md").trim().replace("{{error}}", f
|
|
|
31857
31622
|
}
|
|
31858
31623
|
|
|
31859
31624
|
// packages/experience-design-system-cli/src/lib/prompt-overrides.ts
|
|
31860
|
-
import { readFile as
|
|
31625
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
31861
31626
|
import { resolve as resolve14 } from "node:path";
|
|
31862
31627
|
var PROMPT_FILE_EXTENSIONS = [".md", ".txt", ".prompt"];
|
|
31863
31628
|
function looksLikePath(value) {
|
|
@@ -31893,7 +31658,7 @@ async function resolvePromptOverride(override) {
|
|
|
31893
31658
|
if (override.kind === "text") return override.value;
|
|
31894
31659
|
const abs = resolve14(override.value);
|
|
31895
31660
|
try {
|
|
31896
|
-
return await
|
|
31661
|
+
return await readFile15(abs, "utf8");
|
|
31897
31662
|
} catch {
|
|
31898
31663
|
throw new Error(`--prompt: could not read prompt file: ${abs}`);
|
|
31899
31664
|
}
|
|
@@ -32076,7 +31841,7 @@ async function readCandidateFiles(components, extraFiles = []) {
|
|
|
32076
31841
|
await Promise.all(
|
|
32077
31842
|
[...paths].map(async (p) => {
|
|
32078
31843
|
try {
|
|
32079
|
-
const content = await
|
|
31844
|
+
const content = await readFile16(p, "utf8");
|
|
32080
31845
|
out.push({ path: p, content });
|
|
32081
31846
|
} catch {
|
|
32082
31847
|
}
|
|
@@ -32480,7 +32245,7 @@ function registerAnalyzeCommand(program) {
|
|
|
32480
32245
|
init_src();
|
|
32481
32246
|
import { createElement as createElement4 } from "react";
|
|
32482
32247
|
import { render as render4 } from "ink";
|
|
32483
|
-
import { access as access6, readFile as
|
|
32248
|
+
import { access as access6, readFile as readFile18, readdir as readdir3, stat as stat3 } from "node:fs/promises";
|
|
32484
32249
|
import { join as join16, resolve as resolve17 } from "node:path";
|
|
32485
32250
|
init_debug_logger();
|
|
32486
32251
|
|
|
@@ -32521,7 +32286,7 @@ function GenerateView({ result, onExit }) {
|
|
|
32521
32286
|
}
|
|
32522
32287
|
|
|
32523
32288
|
// packages/experience-design-system-cli/src/generate/edit/command.ts
|
|
32524
|
-
import { readFile as
|
|
32289
|
+
import { readFile as readFile17 } from "node:fs/promises";
|
|
32525
32290
|
import { resolve as resolve16 } from "node:path";
|
|
32526
32291
|
var SAFE_PATH_RE2 = /^[a-zA-Z0-9_.$[\]=]+$/;
|
|
32527
32292
|
var PROTO_KEYS2 = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -32604,7 +32369,7 @@ async function runNonInteractive2(opts, skill) {
|
|
|
32604
32369
|
if (opts.patch) {
|
|
32605
32370
|
let patchOps;
|
|
32606
32371
|
try {
|
|
32607
|
-
const raw = await
|
|
32372
|
+
const raw = await readFile17(resolve16(opts.patch), "utf8");
|
|
32608
32373
|
patchOps = JSON.parse(raw);
|
|
32609
32374
|
} catch {
|
|
32610
32375
|
process.stderr.write(`Error: cannot read or parse --patch file: ${opts.patch}
|
|
@@ -32698,7 +32463,7 @@ async function readFileInline(path) {
|
|
|
32698
32463
|
} catch {
|
|
32699
32464
|
return void 0;
|
|
32700
32465
|
}
|
|
32701
|
-
if (!s.isDirectory()) return
|
|
32466
|
+
if (!s.isDirectory()) return readFile18(resolved, "utf8");
|
|
32702
32467
|
const files = [];
|
|
32703
32468
|
async function walk(dir) {
|
|
32704
32469
|
let entries;
|
|
@@ -32724,7 +32489,7 @@ async function readFileInline(path) {
|
|
|
32724
32489
|
}
|
|
32725
32490
|
await walk(resolved);
|
|
32726
32491
|
if (files.length === 0) return void 0;
|
|
32727
|
-
const parts = await Promise.all(files.map((f) =>
|
|
32492
|
+
const parts = await Promise.all(files.map((f) => readFile18(f, "utf8").catch(() => "")));
|
|
32728
32493
|
return parts.filter(Boolean).join("\n\n");
|
|
32729
32494
|
}
|
|
32730
32495
|
function printFallbackInstructions(options) {
|
|
@@ -32746,7 +32511,7 @@ function printFallbackInstructions(options) {
|
|
|
32746
32511
|
lines.push(` Re-run the generate command with the agent available, or use --dry-run to inspect the prompt.`);
|
|
32747
32512
|
process.stderr.write(lines.join("\n") + "\n");
|
|
32748
32513
|
}
|
|
32749
|
-
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) {
|
|
32750
32515
|
const pos = c.dim(`[${index + 1}/${total}]`);
|
|
32751
32516
|
if (!noCache) {
|
|
32752
32517
|
const inputHash = computeComponentInputHash(component);
|
|
@@ -32816,7 +32581,6 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
|
|
|
32816
32581
|
component.props.map((p) => p.name),
|
|
32817
32582
|
component.props.map((p) => p.type)
|
|
32818
32583
|
);
|
|
32819
|
-
const existingComponentsInline = existingContentfulEntities ? JSON.stringify(summarizeForGenerateAgent(existingContentfulEntities, component.name)) : void 0;
|
|
32820
32584
|
const prompt2 = await buildPrompt({
|
|
32821
32585
|
skill: "components",
|
|
32822
32586
|
mode: "autonomous",
|
|
@@ -32826,9 +32590,7 @@ async function runOneComponent(agent, model, db, sessionId2, component, tokensIn
|
|
|
32826
32590
|
outDir: process.cwd(),
|
|
32827
32591
|
componentName: component.name,
|
|
32828
32592
|
componentSourceRefs: [sourceRef],
|
|
32829
|
-
skillPathOverride
|
|
32830
|
-
existingComponentsInline,
|
|
32831
|
-
existingTokensInline
|
|
32593
|
+
skillPathOverride
|
|
32832
32594
|
});
|
|
32833
32595
|
const maxAttempts = 2;
|
|
32834
32596
|
let lastError = "";
|
|
@@ -32896,7 +32658,7 @@ ${outputBuf}`);
|
|
|
32896
32658
|
renamedSlotsCount: renames.length
|
|
32897
32659
|
};
|
|
32898
32660
|
}
|
|
32899
|
-
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) {
|
|
32900
32662
|
const concurrency = Number(process.env.EDS_GENERATE_CONCURRENCY ?? DEFAULT_COMPONENT_CONCURRENCY);
|
|
32901
32663
|
process.stderr.write(
|
|
32902
32664
|
`Categorizing ${c.bold(String(components.length))} component${components.length === 1 ? "" : "s"}` + c.dim(` (concurrency: ${concurrency})`) + "\n"
|
|
@@ -32920,9 +32682,7 @@ async function runAllComponents(agent, model, db, sessionId2, components, tokens
|
|
|
32920
32682
|
verbose,
|
|
32921
32683
|
noCache,
|
|
32922
32684
|
skillPathOverride,
|
|
32923
|
-
promptHash
|
|
32924
|
-
existingContentfulEntities,
|
|
32925
|
-
existingTokensInline
|
|
32685
|
+
promptHash
|
|
32926
32686
|
);
|
|
32927
32687
|
completed += 1;
|
|
32928
32688
|
process.stderr.write(`${formatGenerateProgressLine(completed, components.length, results[i].componentName)}
|
|
@@ -32960,7 +32720,7 @@ async function loadAcceptedNames(sessionId2) {
|
|
|
32960
32720
|
try {
|
|
32961
32721
|
const artifactsRoot = getRefineArtifactsRoot();
|
|
32962
32722
|
const paths = await getRefineSessionPaths(sessionId2, artifactsRoot);
|
|
32963
|
-
const raw = await
|
|
32723
|
+
const raw = await readFile18(paths.statePath, "utf8");
|
|
32964
32724
|
const snapshot = JSON.parse(raw);
|
|
32965
32725
|
const accepted = snapshot.components.filter((c2) => c2.status === "accepted").map((c2) => c2.name);
|
|
32966
32726
|
if (accepted.length === 0) return null;
|
|
@@ -33006,19 +32766,6 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
33006
32766
|
readFileInline(opts.tokens),
|
|
33007
32767
|
readFileInline(opts.tokenMap)
|
|
33008
32768
|
]);
|
|
33009
|
-
let existingContentfulEntities;
|
|
33010
|
-
let existingTokensInline;
|
|
33011
|
-
if (opts.existingEntitiesPath) {
|
|
33012
|
-
existingContentfulEntities = await readExistingContentfulEntitiesFromSession(resolve17(opts.existingEntitiesPath));
|
|
33013
|
-
if (existingContentfulEntities) {
|
|
33014
|
-
existingTokensInline = JSON.stringify(summarizeForMapTokens(existingContentfulEntities));
|
|
33015
|
-
} else {
|
|
33016
|
-
process.stderr.write(
|
|
33017
|
-
`warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
|
|
33018
|
-
`
|
|
33019
|
-
);
|
|
33020
|
-
}
|
|
33021
|
-
}
|
|
33022
32769
|
let sessionId2;
|
|
33023
32770
|
let allComponents;
|
|
33024
32771
|
if (skill === "components") {
|
|
@@ -33079,7 +32826,6 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
33079
32826
|
sampleComponent.props.map((p) => p.name),
|
|
33080
32827
|
sampleComponent.props.map((p) => p.type)
|
|
33081
32828
|
) : void 0;
|
|
33082
|
-
const dryRunExistingComponentsInline = skill === "components" && existingContentfulEntities && sampleComponent ? JSON.stringify(summarizeForGenerateAgent(existingContentfulEntities, sampleComponent.name)) : void 0;
|
|
33083
32829
|
const prompt2 = await buildPrompt({
|
|
33084
32830
|
skill,
|
|
33085
32831
|
mode: "autonomous",
|
|
@@ -33090,9 +32836,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
33090
32836
|
tokenMapInline,
|
|
33091
32837
|
outDir: process.cwd(),
|
|
33092
32838
|
componentSourceRefs: sampleSourceRef ? [sampleSourceRef] : void 0,
|
|
33093
|
-
skillPathOverride: generatePromptPath
|
|
33094
|
-
existingComponentsInline: dryRunExistingComponentsInline,
|
|
33095
|
-
existingTokensInline: skill === "components" ? existingTokensInline : void 0
|
|
32839
|
+
skillPathOverride: generatePromptPath
|
|
33096
32840
|
});
|
|
33097
32841
|
process.stdout.write(prompt2 + "\n");
|
|
33098
32842
|
await exitWithAnalytics(0);
|
|
@@ -33110,15 +32854,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
33110
32854
|
const db = openPipelineDb();
|
|
33111
32855
|
let componentResults;
|
|
33112
32856
|
try {
|
|
33113
|
-
const
|
|
33114
|
-
if (existingTokensInline) existingContentfulEntitiesHashInputs.push(hashContent(existingTokensInline));
|
|
33115
|
-
const promptHash = await hashPromptForSkill(
|
|
33116
|
-
"components",
|
|
33117
|
-
agent,
|
|
33118
|
-
model,
|
|
33119
|
-
generatePromptPath,
|
|
33120
|
-
existingContentfulEntitiesHashInputs
|
|
33121
|
-
);
|
|
32857
|
+
const promptHash = await hashPromptForSkill("components", agent, model, generatePromptPath);
|
|
33122
32858
|
componentResults = await runAllComponents(
|
|
33123
32859
|
agent,
|
|
33124
32860
|
model,
|
|
@@ -33130,9 +32866,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
33130
32866
|
verbose,
|
|
33131
32867
|
opts.cache === false || process.env.EDS_NO_CACHE === "1",
|
|
33132
32868
|
generatePromptPath,
|
|
33133
|
-
promptHash
|
|
33134
|
-
existingContentfulEntities,
|
|
33135
|
-
existingTokensInline
|
|
32869
|
+
promptHash
|
|
33136
32870
|
);
|
|
33137
32871
|
} finally {
|
|
33138
32872
|
db.close();
|
|
@@ -33309,9 +33043,6 @@ function registerGenerateCommand(program) {
|
|
|
33309
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(
|
|
33310
33044
|
"--generate-prompt-path <path>",
|
|
33311
33045
|
"Path to a custom .md skill prompt for components generation (bypasses bundled prompt invariants)"
|
|
33312
|
-
).option(
|
|
33313
|
-
"--existing-entities-path <path>",
|
|
33314
|
-
"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."
|
|
33315
33046
|
);
|
|
33316
33047
|
addAgentFlags(componentsCmd).action(async (opts) => {
|
|
33317
33048
|
await runGenerateSkill("components", opts, opts.verbose ?? false);
|
|
@@ -33758,9 +33489,9 @@ ${"\u2500".repeat(60)}
|
|
|
33758
33489
|
`);
|
|
33759
33490
|
}
|
|
33760
33491
|
process.stdout.write("\nDelete these sessions? (y/N) ");
|
|
33761
|
-
const answer = await new Promise((
|
|
33492
|
+
const answer = await new Promise((resolve27) => {
|
|
33762
33493
|
process.stdin.setEncoding("utf8");
|
|
33763
|
-
process.stdin.once("data", (chunk) =>
|
|
33494
|
+
process.stdin.once("data", (chunk) => resolve27(String(chunk).trim().toLowerCase()));
|
|
33764
33495
|
});
|
|
33765
33496
|
if (answer !== "y") {
|
|
33766
33497
|
db.close();
|
|
@@ -33795,7 +33526,7 @@ import { access as access7, mkdir as mkdir4, stat as stat4, writeFile as writeFi
|
|
|
33795
33526
|
import { basename as basename5, resolve as resolve19 } from "node:path";
|
|
33796
33527
|
|
|
33797
33528
|
// packages/experience-design-system-cli/src/print/validate/validators/cdf-validator.ts
|
|
33798
|
-
import { readFile as
|
|
33529
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
33799
33530
|
import { validateCDF as validateCDF2 } from "@contentful/experience-design-system-types";
|
|
33800
33531
|
function extractValue(input, path) {
|
|
33801
33532
|
if (path === "/") return void 0;
|
|
@@ -33854,7 +33585,7 @@ function rewriteDiagnostic(error, input) {
|
|
|
33854
33585
|
async function validateCDFFile(filePath) {
|
|
33855
33586
|
let content;
|
|
33856
33587
|
try {
|
|
33857
|
-
content = await
|
|
33588
|
+
content = await readFile19(filePath, "utf-8");
|
|
33858
33589
|
} catch (err) {
|
|
33859
33590
|
return {
|
|
33860
33591
|
valid: false,
|
|
@@ -33889,7 +33620,7 @@ async function validateCDFFile(filePath) {
|
|
|
33889
33620
|
}
|
|
33890
33621
|
|
|
33891
33622
|
// packages/experience-design-system-cli/src/print/validate/validators/dtcg-validator.ts
|
|
33892
|
-
import { readFile as
|
|
33623
|
+
import { readFile as readFile20 } from "node:fs/promises";
|
|
33893
33624
|
import { DESIGN_TOKEN_TYPES } from "@contentful/experience-design-system-types";
|
|
33894
33625
|
function walkDTCG(obj, path, diagnostics, counts) {
|
|
33895
33626
|
for (const [key, value] of Object.entries(obj)) {
|
|
@@ -33934,7 +33665,7 @@ function walkDTCG(obj, path, diagnostics, counts) {
|
|
|
33934
33665
|
async function validateDTCGTokenFile(filePath) {
|
|
33935
33666
|
let content;
|
|
33936
33667
|
try {
|
|
33937
|
-
content = await
|
|
33668
|
+
content = await readFile20(filePath, "utf-8");
|
|
33938
33669
|
} catch (err) {
|
|
33939
33670
|
return {
|
|
33940
33671
|
valid: false,
|
|
@@ -34267,8 +33998,7 @@ init_db();
|
|
|
34267
33998
|
init_cache_keys();
|
|
34268
33999
|
import { createElement as createElement6 } from "react";
|
|
34269
34000
|
import { render as render6 } from "ink";
|
|
34270
|
-
import { readFile as
|
|
34271
|
-
import { resolve as resolve20 } from "node:path";
|
|
34001
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
34272
34002
|
|
|
34273
34003
|
// packages/experience-design-system-cli/src/map-tokens/apply.ts
|
|
34274
34004
|
init_db();
|
|
@@ -34516,7 +34246,7 @@ async function runMapTokens(opts) {
|
|
|
34516
34246
|
const knownTokenPaths = new Set(tokenLeaves.map((t) => t.path));
|
|
34517
34247
|
const tokenMapDiagnostics = [];
|
|
34518
34248
|
if (opts.tokenMap) {
|
|
34519
|
-
const fileMappings = JSON.parse(await
|
|
34249
|
+
const fileMappings = JSON.parse(await readFile21(opts.tokenMap, "utf8"));
|
|
34520
34250
|
const validMappings = {};
|
|
34521
34251
|
for (const [rawName, path] of Object.entries(fileMappings)) {
|
|
34522
34252
|
if (knownTokenPaths.has(path)) {
|
|
@@ -34591,20 +34321,6 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
|
|
|
34591
34321
|
const generatedCdf = Object.fromEntries(cdfEntries.map((c2) => [c2.key, c2.entry]));
|
|
34592
34322
|
const tokenTree = rebuildDTCGTree(groups, tokens);
|
|
34593
34323
|
const componentSourceRefs = await loadComponentSourceRefs(db, sessionId2);
|
|
34594
|
-
let existingTokensInline;
|
|
34595
|
-
if (opts.existingEntitiesPath) {
|
|
34596
|
-
const existingContentfulEntities = await readExistingContentfulEntitiesFromSession(
|
|
34597
|
-
resolve20(opts.existingEntitiesPath)
|
|
34598
|
-
);
|
|
34599
|
-
if (existingContentfulEntities) {
|
|
34600
|
-
existingTokensInline = JSON.stringify(summarizeForMapTokens(existingContentfulEntities));
|
|
34601
|
-
} else {
|
|
34602
|
-
process.stderr.write(
|
|
34603
|
-
`warn: --existing-entities-path ${opts.existingEntitiesPath} could not be read as JSON \u2014 proceeding without space-context enrichment
|
|
34604
|
-
`
|
|
34605
|
-
);
|
|
34606
|
-
}
|
|
34607
|
-
}
|
|
34608
34324
|
if (opts.printPrompt) {
|
|
34609
34325
|
const prompt3 = await buildPrompt({
|
|
34610
34326
|
skill: "map-tokens",
|
|
@@ -34612,8 +34328,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
|
|
|
34612
34328
|
generatedCdf,
|
|
34613
34329
|
tokenTree,
|
|
34614
34330
|
componentSourceRefs,
|
|
34615
|
-
outDir: process.cwd()
|
|
34616
|
-
existingTokensInline
|
|
34331
|
+
outDir: process.cwd()
|
|
34617
34332
|
});
|
|
34618
34333
|
process.stdout.write(prompt3 + "\n");
|
|
34619
34334
|
await exitWithAnalytics(0);
|
|
@@ -34631,13 +34346,7 @@ ${defaultDiagnostics.map((diagnostic) => ` ${diagnostic}`).join("\n")}
|
|
|
34631
34346
|
}
|
|
34632
34347
|
const agent = configuredAgent;
|
|
34633
34348
|
const noCache = opts.cache === false || process.env.EDS_NO_CACHE === "1";
|
|
34634
|
-
const promptHash = await hashPromptForSkill(
|
|
34635
|
-
"map-tokens",
|
|
34636
|
-
agent,
|
|
34637
|
-
model,
|
|
34638
|
-
void 0,
|
|
34639
|
-
existingTokensInline ? [hashContent(existingTokensInline)] : []
|
|
34640
|
-
);
|
|
34349
|
+
const promptHash = await hashPromptForSkill("map-tokens", agent, model);
|
|
34641
34350
|
const inputHash = computeMapTokensInputHash(db, sessionId2, componentSourceRefs);
|
|
34642
34351
|
if (!noCache) {
|
|
34643
34352
|
const cached = lookupCache(db, inputHash, "token_mapping", "__map_tokens__", promptHash);
|
|
@@ -34664,8 +34373,7 @@ Install it, choose another agent with --agent, or use --print-prompt to run the
|
|
|
34664
34373
|
generatedCdf,
|
|
34665
34374
|
tokenTree,
|
|
34666
34375
|
componentSourceRefs,
|
|
34667
|
-
outDir: process.cwd()
|
|
34668
|
-
existingTokensInline
|
|
34376
|
+
outDir: process.cwd()
|
|
34669
34377
|
});
|
|
34670
34378
|
const invoker3 = createLocalCliAgentInvoker();
|
|
34671
34379
|
const result = await invoker3.invoke({ agent, model, prompt: prompt2, timeoutMs: DEFAULT_TIMEOUT_MS4 });
|
|
@@ -34692,10 +34400,7 @@ ${warnings.map((w) => ` ${w}`).join("\n")}
|
|
|
34692
34400
|
}
|
|
34693
34401
|
function registerMapTokensCommand(program) {
|
|
34694
34402
|
const map = program.command("map").description("Suggest token restrictions for generated design-token props");
|
|
34695
|
-
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")
|
|
34696
|
-
"--existing-entities-path <path>",
|
|
34697
|
-
"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."
|
|
34698
|
-
);
|
|
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");
|
|
34699
34404
|
addAgentModelOptions(tokensCmd).action(async (opts) => {
|
|
34700
34405
|
await runMapTokens(opts);
|
|
34701
34406
|
});
|
|
@@ -34704,22 +34409,45 @@ function registerMapTokensCommand(program) {
|
|
|
34704
34409
|
// packages/experience-design-system-cli/src/import/command.ts
|
|
34705
34410
|
init_src();
|
|
34706
34411
|
init_path_utils();
|
|
34707
|
-
import { resolve as
|
|
34412
|
+
import { resolve as resolve25, join as join25 } from "node:path";
|
|
34708
34413
|
|
|
34709
34414
|
// packages/experience-design-system-cli/src/import/orchestrator.ts
|
|
34710
34415
|
init_db();
|
|
34711
34416
|
init_command();
|
|
34712
34417
|
init_manifest();
|
|
34713
34418
|
init_api_client();
|
|
34714
|
-
|
|
34419
|
+
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
34420
|
+
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34421
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
34422
|
+
|
|
34423
|
+
// packages/experience-design-system-cli/src/helpers/fetch-existing-entities.ts
|
|
34424
|
+
import { fetchAll } from "contentful-management";
|
|
34425
|
+
async function fetchExistingEntities(client2, params) {
|
|
34426
|
+
const scope = { spaceId: params.spaceId, environmentId: params.environmentId, query: {} };
|
|
34427
|
+
const components = await fetchAll(client2.component.getMany, scope);
|
|
34428
|
+
const tokens = await fetchAll(client2.designToken.getMany, scope);
|
|
34429
|
+
return { components, tokens };
|
|
34430
|
+
}
|
|
34431
|
+
|
|
34432
|
+
// packages/experience-design-system-cli/src/helpers/cma-client.ts
|
|
34433
|
+
init_host_utils();
|
|
34434
|
+
import { createClient as createClient2 } from "contentful-management";
|
|
34435
|
+
function createCmaClient(opts) {
|
|
34436
|
+
return createClient2(
|
|
34437
|
+
{
|
|
34438
|
+
accessToken: opts.cmaToken,
|
|
34439
|
+
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
34440
|
+
},
|
|
34441
|
+
{ type: "plain" }
|
|
34442
|
+
);
|
|
34443
|
+
}
|
|
34444
|
+
|
|
34445
|
+
// packages/experience-design-system-cli/src/import/orchestrator.ts
|
|
34715
34446
|
init_contentful_urls();
|
|
34716
34447
|
init_debug_logger();
|
|
34717
34448
|
init_analytics();
|
|
34718
34449
|
init_env();
|
|
34719
34450
|
init_cli_path();
|
|
34720
|
-
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
34721
|
-
import { join as join19, resolve as resolve22 } from "node:path";
|
|
34722
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
34723
34451
|
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
34724
34452
|
const debug = getDebugLogger();
|
|
34725
34453
|
const startedAt = Date.now();
|
|
@@ -34804,9 +34532,9 @@ function buildPushStepResult(args) {
|
|
|
34804
34532
|
};
|
|
34805
34533
|
}
|
|
34806
34534
|
async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
34807
|
-
const projectRoot =
|
|
34808
|
-
const outDir =
|
|
34809
|
-
const componentsPath =
|
|
34535
|
+
const projectRoot = resolve21(opts.project);
|
|
34536
|
+
const outDir = resolve21(opts.out);
|
|
34537
|
+
const componentsPath = join18(outDir, "components.json");
|
|
34810
34538
|
const cliPath = cliPathOverride ?? findCliPath();
|
|
34811
34539
|
const db = openPipelineDb();
|
|
34812
34540
|
const { sessionId: sessionId2 } = getOrCreateSession(db, void 0, void 0, {
|
|
@@ -34827,56 +34555,67 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34827
34555
|
await mkdir5(outDir, { recursive: true });
|
|
34828
34556
|
const steps = [];
|
|
34829
34557
|
let stepNum = 0;
|
|
34830
|
-
const
|
|
34831
|
-
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);
|
|
34832
34561
|
function stepLabel(name) {
|
|
34833
34562
|
stepNum++;
|
|
34834
34563
|
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
34835
34564
|
}
|
|
34836
|
-
|
|
34837
|
-
|
|
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) {
|
|
34838
34571
|
const fetchLabel = stepLabel("Fetching existing components + design tokens");
|
|
34839
34572
|
const fetchStepId = createStep(db, sessionId2, "fetch existing entities", {
|
|
34840
34573
|
spaceId: opts.spaceId,
|
|
34841
34574
|
environmentId: opts.environmentId
|
|
34842
34575
|
});
|
|
34843
|
-
const
|
|
34844
|
-
|
|
34845
|
-
|
|
34846
|
-
|
|
34847
|
-
|
|
34848
|
-
|
|
34849
|
-
|
|
34850
|
-
|
|
34851
|
-
|
|
34576
|
+
const t0 = Date.now();
|
|
34577
|
+
try {
|
|
34578
|
+
const cmaClient = createCmaClient({
|
|
34579
|
+
cmaToken: opts.cmaToken,
|
|
34580
|
+
...opts.host ? { host: opts.host } : {}
|
|
34581
|
+
});
|
|
34582
|
+
const existingComponentsAndTokens = await fetchExistingEntities(cmaClient, {
|
|
34583
|
+
spaceId: opts.spaceId,
|
|
34584
|
+
environmentId: opts.environmentId
|
|
34585
|
+
});
|
|
34586
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34587
|
+
const existingEntitiesPath = join18(outDir, ".existing-entities.json");
|
|
34588
|
+
await writeFile5(existingEntitiesPath, JSON.stringify(existingComponentsAndTokens, null, 2), "utf8");
|
|
34852
34589
|
updateStep(db, fetchStepId, "complete", {
|
|
34853
|
-
components: String(
|
|
34854
|
-
tokens: String(
|
|
34855
|
-
path:
|
|
34590
|
+
components: String(existingComponentsAndTokens.components.length),
|
|
34591
|
+
tokens: String(existingComponentsAndTokens.tokens.length),
|
|
34592
|
+
path: existingEntitiesPath
|
|
34856
34593
|
});
|
|
34857
34594
|
progressWriter(
|
|
34858
|
-
`${fetchLabel}\u2713 ${
|
|
34595
|
+
`${fetchLabel}\u2713 ${existingComponentsAndTokens.components.length} component${existingComponentsAndTokens.components.length === 1 ? "" : "s"}, ${existingComponentsAndTokens.tokens.length} token${existingComponentsAndTokens.tokens.length === 1 ? "" : "s"} (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34859
34596
|
);
|
|
34860
34597
|
steps.push({
|
|
34861
34598
|
step: "fetch existing entities",
|
|
34862
34599
|
status: "complete",
|
|
34863
|
-
durationMs:
|
|
34600
|
+
durationMs: fetchDurationMs,
|
|
34864
34601
|
detail: {
|
|
34865
|
-
components:
|
|
34866
|
-
tokens:
|
|
34602
|
+
components: existingComponentsAndTokens.components.length,
|
|
34603
|
+
tokens: existingComponentsAndTokens.tokens.length
|
|
34867
34604
|
}
|
|
34868
34605
|
});
|
|
34869
|
-
}
|
|
34870
|
-
|
|
34606
|
+
} catch (error) {
|
|
34607
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34608
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34609
|
+
updateStep(db, fetchStepId, "complete", {}, message);
|
|
34871
34610
|
progressWriter(
|
|
34872
|
-
`${fetchLabel}\u26A0 fetch failed, continuing without space context (${(
|
|
34611
|
+
`${fetchLabel}\u26A0 fetch failed, continuing without space context (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34873
34612
|
);
|
|
34874
|
-
progressWriter(` ${
|
|
34613
|
+
progressWriter(` ${message.split("\n")[0]}`);
|
|
34875
34614
|
steps.push({
|
|
34876
34615
|
step: "fetch existing entities",
|
|
34877
34616
|
status: "skipped",
|
|
34878
|
-
durationMs:
|
|
34879
|
-
reason: `fetch failed: ${
|
|
34617
|
+
durationMs: fetchDurationMs,
|
|
34618
|
+
reason: `fetch failed: ${message.split("\n")[0]}`
|
|
34880
34619
|
});
|
|
34881
34620
|
}
|
|
34882
34621
|
}
|
|
@@ -34962,7 +34701,6 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34962
34701
|
if (opts.excludeInvalid) editArgs.push("--exclude-invalid");
|
|
34963
34702
|
if (opts.noCache) editArgs.push("--no-cache");
|
|
34964
34703
|
if (opts.selectPromptPath) editArgs.push("--select-prompt-path", opts.selectPromptPath);
|
|
34965
|
-
if (existingEntitiesPath) editArgs.push("--existing-entities-path", existingEntitiesPath);
|
|
34966
34704
|
} else {
|
|
34967
34705
|
editArgs = ["analyze", "select", "--session", extractSessionId];
|
|
34968
34706
|
if (opts.select && opts.select.length > 0) {
|
|
@@ -35025,7 +34763,6 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
35025
34763
|
if (extractSessionId) generateArgs.push("--session", extractSessionId);
|
|
35026
34764
|
if (opts.dryRun) generateArgs.push("--dry-run");
|
|
35027
34765
|
if (opts.verbose) generateArgs.push("--verbose");
|
|
35028
|
-
if (existingEntitiesPath) generateArgs.push("--existing-entities-path", existingEntitiesPath);
|
|
35029
34766
|
const stepId = createStep(db, sessionId2, "generate components", {
|
|
35030
34767
|
extractSession: extractSessionId ?? ""
|
|
35031
34768
|
});
|
|
@@ -35080,7 +34817,6 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
35080
34817
|
if (opts.model) mapTokensArgs.push("--model", opts.model);
|
|
35081
34818
|
if (opts.noCache) mapTokensArgs.push("--no-cache");
|
|
35082
34819
|
if (opts.skipMapTokens) mapTokensArgs.push("--skip-agent");
|
|
35083
|
-
if (existingEntitiesPath) mapTokensArgs.push("--existing-entities-path", existingEntitiesPath);
|
|
35084
34820
|
const mapTokensStepId = createStep(db, sessionId2, "map tokens", {
|
|
35085
34821
|
extractSession: extractSessionId,
|
|
35086
34822
|
skipAgent: String(opts.skipMapTokens === true)
|
|
@@ -35442,7 +35178,7 @@ init_host_utils();
|
|
|
35442
35178
|
// packages/experience-design-system-cli/src/runs/replay-helpers.ts
|
|
35443
35179
|
init_resolve_run_target();
|
|
35444
35180
|
init_store();
|
|
35445
|
-
import { resolve as
|
|
35181
|
+
import { resolve as resolve24 } from "node:path";
|
|
35446
35182
|
|
|
35447
35183
|
// packages/experience-design-system-cli/src/runs/push-helpers.ts
|
|
35448
35184
|
init_cli_path();
|
|
@@ -35632,7 +35368,7 @@ async function modifyRun(opts) {
|
|
|
35632
35368
|
entryStep: "final-review",
|
|
35633
35369
|
saveMode,
|
|
35634
35370
|
...run.compositionMode ? { compositionMode: run.compositionMode } : {},
|
|
35635
|
-
...opts.outDir ? { outDirOverride:
|
|
35371
|
+
...opts.outDir ? { outDirOverride: resolve24(opts.outDir) } : {},
|
|
35636
35372
|
...mergedSpaceId ? { initialSpaceId: mergedSpaceId } : {},
|
|
35637
35373
|
...mergedEnvironmentId ? { initialEnvironmentId: mergedEnvironmentId } : {},
|
|
35638
35374
|
...mergedHost ? { initialHost: mergedHost } : {},
|
|
@@ -35709,7 +35445,7 @@ function resolvePromptFlags(flags) {
|
|
|
35709
35445
|
|
|
35710
35446
|
// packages/experience-design-system-cli/src/runs/run-picker-mount.ts
|
|
35711
35447
|
init_store();
|
|
35712
|
-
import { readFile as
|
|
35448
|
+
import { readFile as readFile26 } from "node:fs/promises";
|
|
35713
35449
|
function migrateRecord2(rec) {
|
|
35714
35450
|
return {
|
|
35715
35451
|
...rec,
|
|
@@ -35732,7 +35468,7 @@ async function shouldShowRunPicker(input) {
|
|
|
35732
35468
|
const path = input.runsJsonPath ?? runsFilePath();
|
|
35733
35469
|
let raw;
|
|
35734
35470
|
try {
|
|
35735
|
-
raw = await
|
|
35471
|
+
raw = await readFile26(path, "utf8");
|
|
35736
35472
|
} catch {
|
|
35737
35473
|
return { shouldShow: false, runs: [] };
|
|
35738
35474
|
}
|
|
@@ -35837,7 +35573,10 @@ function registerImportCommand(program) {
|
|
|
35837
35573
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
35838
35574
|
(v, acc) => [...acc, v],
|
|
35839
35575
|
[]
|
|
35840
|
-
).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(
|
|
35841
35580
|
"--no-auto-filter",
|
|
35842
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)"
|
|
35843
35582
|
).option(
|
|
@@ -36105,7 +35844,7 @@ function registerImportCommand(program) {
|
|
|
36105
35844
|
livePreview: opts.livePreview !== false,
|
|
36106
35845
|
noPush: noPushRequested,
|
|
36107
35846
|
noSave: opts.save === false,
|
|
36108
|
-
...opts.outDir ? { outDirOverride:
|
|
35847
|
+
...opts.outDir ? { outDirOverride: resolve25(opts.outDir) } : {},
|
|
36109
35848
|
...opts.onConflict ? { onConflictMode: opts.onConflict } : {},
|
|
36110
35849
|
selectPromptPath: opts.selectPromptPath ?? creds.selectPromptPath,
|
|
36111
35850
|
generatePromptPath: opts.generatePromptPath ?? creds.generatePromptPath,
|
|
@@ -36146,7 +35885,7 @@ function registerImportCommand(program) {
|
|
|
36146
35885
|
return;
|
|
36147
35886
|
}
|
|
36148
35887
|
const projectRoot = normalizePath(opts.project);
|
|
36149
|
-
const outDir = opts.out ?
|
|
35888
|
+
const outDir = opts.out ? resolve25(opts.out) : join25(projectRoot, ".contentful");
|
|
36150
35889
|
const headlessCreds = await readExperiencesCredentials();
|
|
36151
35890
|
const headlessAgent = resolveAgent(opts.agent, headlessCreds.agent);
|
|
36152
35891
|
const headlessModel = resolveModel(opts.model, headlessCreds.agentModel);
|
|
@@ -36184,6 +35923,7 @@ function registerImportCommand(program) {
|
|
|
36184
35923
|
dryRun: dryRunForward,
|
|
36185
35924
|
selectPromptPath: opts.selectPromptPath,
|
|
36186
35925
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
35926
|
+
withSpaceContext: opts.withSpaceContext ?? false,
|
|
36187
35927
|
allowDeletions: opts.allowDeletions ?? false,
|
|
36188
35928
|
compositionMode: headlessCompositionMode,
|
|
36189
35929
|
...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
|
|
@@ -36208,8 +35948,8 @@ function registerImportCommand(program) {
|
|
|
36208
35948
|
// packages/experience-design-system-cli/src/setup/command.ts
|
|
36209
35949
|
init_credentials_store();
|
|
36210
35950
|
import { execFile as execFile5, spawn as spawn5 } from "node:child_process";
|
|
36211
|
-
import { appendFile as appendFile2, readFile as
|
|
36212
|
-
import { join as
|
|
35951
|
+
import { appendFile as appendFile2, readFile as readFile27, access as access10 } from "node:fs/promises";
|
|
35952
|
+
import { join as join26 } from "node:path";
|
|
36213
35953
|
import { homedir as homedir9 } from "node:os";
|
|
36214
35954
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
36215
35955
|
import { createInterface } from "node:readline";
|
|
@@ -36287,10 +36027,10 @@ function prompt(question) {
|
|
|
36287
36027
|
return Promise.resolve("");
|
|
36288
36028
|
}
|
|
36289
36029
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
36290
|
-
return new Promise((
|
|
36030
|
+
return new Promise((resolve27) => {
|
|
36291
36031
|
rl.question(question, (answer) => {
|
|
36292
36032
|
rl.close();
|
|
36293
|
-
|
|
36033
|
+
resolve27(answer.trim());
|
|
36294
36034
|
});
|
|
36295
36035
|
});
|
|
36296
36036
|
}
|
|
@@ -36298,7 +36038,7 @@ function promptSecret(question) {
|
|
|
36298
36038
|
if (!isInteractivePromptSession()) {
|
|
36299
36039
|
return Promise.resolve("");
|
|
36300
36040
|
}
|
|
36301
|
-
return new Promise((
|
|
36041
|
+
return new Promise((resolve27) => {
|
|
36302
36042
|
const rl = createInterface({
|
|
36303
36043
|
input: process.stdin,
|
|
36304
36044
|
output: process.stdout,
|
|
@@ -36325,7 +36065,7 @@ function promptSecret(question) {
|
|
|
36325
36065
|
}
|
|
36326
36066
|
if (!process.stdin.isTTY) process.stdout.write("\n");
|
|
36327
36067
|
process.stdin.resume();
|
|
36328
|
-
|
|
36068
|
+
resolve27(value);
|
|
36329
36069
|
});
|
|
36330
36070
|
});
|
|
36331
36071
|
}
|
|
@@ -36347,7 +36087,7 @@ async function binaryExists(name) {
|
|
|
36347
36087
|
}
|
|
36348
36088
|
}
|
|
36349
36089
|
function runSpawn(cmd, args, opts = {}) {
|
|
36350
|
-
return new Promise((
|
|
36090
|
+
return new Promise((resolve27) => {
|
|
36351
36091
|
const child = spawn5(cmd, args, {
|
|
36352
36092
|
cwd: opts.cwd,
|
|
36353
36093
|
env: opts.env ?? process.env,
|
|
@@ -36359,7 +36099,7 @@ function runSpawn(cmd, args, opts = {}) {
|
|
|
36359
36099
|
child.on("error", (err) => {
|
|
36360
36100
|
if (!settled) {
|
|
36361
36101
|
settled = true;
|
|
36362
|
-
|
|
36102
|
+
resolve27({ exitCode: 1, stdout: "", stderr: err.message });
|
|
36363
36103
|
}
|
|
36364
36104
|
});
|
|
36365
36105
|
child.stdout.on("data", (d) => {
|
|
@@ -36371,7 +36111,7 @@ function runSpawn(cmd, args, opts = {}) {
|
|
|
36371
36111
|
child.on("exit", (code) => {
|
|
36372
36112
|
if (!settled) {
|
|
36373
36113
|
settled = true;
|
|
36374
|
-
|
|
36114
|
+
resolve27({ exitCode: code ?? 1, stdout, stderr });
|
|
36375
36115
|
}
|
|
36376
36116
|
});
|
|
36377
36117
|
});
|
|
@@ -36380,21 +36120,21 @@ async function detectShellProfile() {
|
|
|
36380
36120
|
const shell = process.env["SHELL"] ?? "";
|
|
36381
36121
|
const home = homedir9();
|
|
36382
36122
|
if (shell.includes("zsh")) {
|
|
36383
|
-
return
|
|
36123
|
+
return join26(home, ".zshrc");
|
|
36384
36124
|
}
|
|
36385
36125
|
if (shell.includes("bash")) {
|
|
36386
|
-
const bashProfile =
|
|
36126
|
+
const bashProfile = join26(home, ".bash_profile");
|
|
36387
36127
|
const exists = await access10(bashProfile).then(() => true).catch(() => false);
|
|
36388
|
-
return exists ? bashProfile :
|
|
36128
|
+
return exists ? bashProfile : join26(home, ".bashrc");
|
|
36389
36129
|
}
|
|
36390
36130
|
if (shell.includes("fish")) {
|
|
36391
|
-
return
|
|
36131
|
+
return join26(home, ".config", "fish", "config.fish");
|
|
36392
36132
|
}
|
|
36393
|
-
return
|
|
36133
|
+
return join26(home, ".profile");
|
|
36394
36134
|
}
|
|
36395
36135
|
async function profileContains(profilePath, str) {
|
|
36396
36136
|
try {
|
|
36397
|
-
const content = await
|
|
36137
|
+
const content = await readFile27(profilePath, "utf8");
|
|
36398
36138
|
return content.includes(str);
|
|
36399
36139
|
} catch {
|
|
36400
36140
|
return false;
|
|
@@ -36415,7 +36155,7 @@ async function setupNode() {
|
|
|
36415
36155
|
}
|
|
36416
36156
|
fail(`Node.js v${current} \u2014 need v${REQUIRED_NODE_MAJOR}+`);
|
|
36417
36157
|
info("");
|
|
36418
|
-
const hasNvm = await binaryExists("nvm") || await access10(
|
|
36158
|
+
const hasNvm = await binaryExists("nvm") || await access10(join26(homedir9(), ".nvm", "nvm.sh")).then(() => true).catch(() => false);
|
|
36419
36159
|
const hasFnm = await binaryExists("fnm");
|
|
36420
36160
|
if (hasNvm) {
|
|
36421
36161
|
info(`nvm detected. Will run: nvm install ${REQUIRED_NODE_MAJOR} && nvm use ${REQUIRED_NODE_MAJOR}`);
|
|
@@ -36424,7 +36164,7 @@ async function setupNode() {
|
|
|
36424
36164
|
warn(`Skipped. Re-run experiences setup after switching to Node ${REQUIRED_NODE_MAJOR}.`);
|
|
36425
36165
|
return false;
|
|
36426
36166
|
}
|
|
36427
|
-
const nvmScript =
|
|
36167
|
+
const nvmScript = join26(homedir9(), ".nvm", "nvm.sh");
|
|
36428
36168
|
const result = await runSpawn("bash", [
|
|
36429
36169
|
"-c",
|
|
36430
36170
|
`source "${nvmScript}" && nvm install ${REQUIRED_NODE_MAJOR} && nvm alias default ${REQUIRED_NODE_MAJOR}`
|
|
@@ -36891,13 +36631,13 @@ async function checkPnpm(pkgRoot) {
|
|
|
36891
36631
|
}
|
|
36892
36632
|
async function checkDependencies(pkgRoot) {
|
|
36893
36633
|
section("Checking dependencies (pnpm install)");
|
|
36894
|
-
const nodeModulesExists = await access10(
|
|
36634
|
+
const nodeModulesExists = await access10(join26(pkgRoot, "node_modules")).then(() => true).catch(() => false);
|
|
36895
36635
|
if (!nodeModulesExists) {
|
|
36896
36636
|
info("node_modules not found \u2014 running pnpm install...");
|
|
36897
36637
|
} else {
|
|
36898
36638
|
info("Running pnpm install to ensure dependencies are up to date...");
|
|
36899
36639
|
}
|
|
36900
|
-
const repoRoot =
|
|
36640
|
+
const repoRoot = join26(pkgRoot, "..", "..");
|
|
36901
36641
|
const result = await runSpawn("pnpm", ["install", "--frozen-lockfile"], { cwd: repoRoot });
|
|
36902
36642
|
if (result.exitCode !== 0) {
|
|
36903
36643
|
fail("pnpm install failed");
|
|
@@ -36916,7 +36656,7 @@ async function checkDependencies(pkgRoot) {
|
|
|
36916
36656
|
async function checkBuild(pkgRoot) {
|
|
36917
36657
|
section("Building CLI");
|
|
36918
36658
|
info("Running pnpm build...");
|
|
36919
|
-
const repoRoot =
|
|
36659
|
+
const repoRoot = join26(pkgRoot, "..", "..");
|
|
36920
36660
|
const result = await runSpawn("pnpm", ["--filter", "@contentful/experience-design-system-cli", "run", "build"], {
|
|
36921
36661
|
cwd: repoRoot
|
|
36922
36662
|
});
|
|
@@ -37032,7 +36772,7 @@ function registerSetupCommand(program) {
|
|
|
37032
36772
|
process.stdout.write("\n\x1B[1mexperiences setup\x1B[0m \u2014 interactive setup wizard\n");
|
|
37033
36773
|
process.stdout.write("Sets up everything you need to run \x1B[1mexperiences import\x1B[0m.\n");
|
|
37034
36774
|
const pkgRoot = findPkgRoot();
|
|
37035
|
-
const repoRoot =
|
|
36775
|
+
const repoRoot = join26(pkgRoot, "..", "..");
|
|
37036
36776
|
const profilePath = await detectShellProfile();
|
|
37037
36777
|
const results = [];
|
|
37038
36778
|
const nodeOk = await setupNode();
|
|
@@ -37272,7 +37012,7 @@ async function beginCommand(command, opts) {
|
|
|
37272
37012
|
init_analytics();
|
|
37273
37013
|
init_credentials_store();
|
|
37274
37014
|
init_cli_path();
|
|
37275
|
-
var pkg3 = JSON.parse(readFileSync10(
|
|
37015
|
+
var pkg3 = JSON.parse(readFileSync10(join27(findPkgRoot(), "package.json"), "utf8"));
|
|
37276
37016
|
async function runBuild(opts) {
|
|
37277
37017
|
return new Promise((resolvePromise) => {
|
|
37278
37018
|
const child = opts.spawnFn();
|
|
@@ -37309,7 +37049,7 @@ function registerImportV2Command(program) {
|
|
|
37309
37049
|
}
|
|
37310
37050
|
function registerBuildCommand(program) {
|
|
37311
37051
|
program.command("build").description("Rebuild from source and re-link exo/experiences binaries to this build").action(async () => {
|
|
37312
|
-
const pkgRoot =
|
|
37052
|
+
const pkgRoot = resolve26(dirname14(fileURLToPath5(import.meta.url)), "..", "..");
|
|
37313
37053
|
process.stderr.write("\u2699 Building from source...\n");
|
|
37314
37054
|
const { exitCode } = await runBuild({
|
|
37315
37055
|
spawnFn: () => spawn6("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
|