@contentful/experience-design-system-cli 2.34.5-dev-build-13ecfbdc.0 → 2.34.5-dev-build-12a524fb.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
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type CompositionCliOptions = {
|
|
2
2
|
/** `--composition-refresh` — force edge emission to run even over resolved residue. */
|
|
3
3
|
compositionRefresh?: boolean;
|
|
4
|
+
/** `--no-cache` — force the composition agent to rerun with the rest of the pipeline. */
|
|
5
|
+
noCache?: boolean;
|
|
4
6
|
};
|
|
5
7
|
export type ResolvedCompositionSources = {
|
|
6
8
|
forceAgent: boolean;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
+
export declare function resolveExtractNoCache(opts: {
|
|
3
|
+
cache?: boolean;
|
|
4
|
+
noCache?: boolean;
|
|
5
|
+
}): boolean;
|
|
2
6
|
export declare function collectSourceFiles(directory: string, onProgress?: (scannedCount: number) => void): Promise<string[]>;
|
|
3
7
|
export declare function registerInternalExtractCommand(program: Command): void;
|
package/dist/src/index.js
CHANGED
|
@@ -3703,6 +3703,40 @@ async function getCliCacheVersion() {
|
|
|
3703
3703
|
return _cliCacheVersionCache;
|
|
3704
3704
|
}
|
|
3705
3705
|
}
|
|
3706
|
+
function storeExtractCache(db, filePath, fileHash, cliVersion2, components) {
|
|
3707
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3708
|
+
const componentsJson = JSON.stringify(components);
|
|
3709
|
+
db.prepare(
|
|
3710
|
+
`INSERT INTO extract_cache (file_path, file_hash, cli_version, created_at, updated_at, components_json)
|
|
3711
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
3712
|
+
ON CONFLICT(file_hash, cli_version) DO UPDATE SET
|
|
3713
|
+
file_path = excluded.file_path,
|
|
3714
|
+
updated_at = excluded.updated_at,
|
|
3715
|
+
components_json = excluded.components_json`
|
|
3716
|
+
).run(filePath, fileHash, cliVersion2, now, now, componentsJson);
|
|
3717
|
+
}
|
|
3718
|
+
function lookupExtractCache(db, fileHash, cliVersion2) {
|
|
3719
|
+
const row = db.prepare(
|
|
3720
|
+
`SELECT file_path, file_hash, cli_version, created_at, updated_at, components_json
|
|
3721
|
+
FROM extract_cache
|
|
3722
|
+
WHERE file_hash = ? AND cli_version = ?`
|
|
3723
|
+
).get(fileHash, cliVersion2);
|
|
3724
|
+
if (!row) return null;
|
|
3725
|
+
let components = [];
|
|
3726
|
+
try {
|
|
3727
|
+
components = JSON.parse(row.components_json);
|
|
3728
|
+
} catch {
|
|
3729
|
+
return null;
|
|
3730
|
+
}
|
|
3731
|
+
return {
|
|
3732
|
+
filePath: row.file_path,
|
|
3733
|
+
fileHash: row.file_hash,
|
|
3734
|
+
cliVersion: row.cli_version,
|
|
3735
|
+
createdAt: row.created_at,
|
|
3736
|
+
updatedAt: row.updated_at,
|
|
3737
|
+
components
|
|
3738
|
+
};
|
|
3739
|
+
}
|
|
3706
3740
|
function storeCompositionCache(db, inputHash, cliVersion2, agentOutput) {
|
|
3707
3741
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3708
3742
|
db.prepare(
|
|
@@ -30285,7 +30319,7 @@ var init_resolve_mapping = __esm({
|
|
|
30285
30319
|
// packages/experience-design-system-cli/src/analyze/composition/resolve-mapping-cli.ts
|
|
30286
30320
|
function resolveCompositionSources(opts) {
|
|
30287
30321
|
return {
|
|
30288
|
-
forceAgent:
|
|
30322
|
+
forceAgent: opts.compositionRefresh === true || opts.noCache === true
|
|
30289
30323
|
};
|
|
30290
30324
|
}
|
|
30291
30325
|
var init_resolve_mapping_cli = __esm({
|
|
@@ -30454,12 +30488,26 @@ var init_manifest_doc_evidence = __esm({
|
|
|
30454
30488
|
// packages/experience-design-system-cli/src/analyze/extract-command.ts
|
|
30455
30489
|
import { mkdir as mkdir6, readdir as readdir3, readFile as readFile18, stat as stat6 } from "node:fs/promises";
|
|
30456
30490
|
import { isAbsolute as isAbsolute2, join as join25, relative as relative2, resolve as resolve19 } from "node:path";
|
|
30491
|
+
function resolveExtractNoCache(opts) {
|
|
30492
|
+
return opts.noCache === true || opts.cache === false;
|
|
30493
|
+
}
|
|
30457
30494
|
function isDenylistedNoiseFile(name) {
|
|
30458
30495
|
return DENYLISTED_EXACT_FILE_NAMES.has(name) || DENYLISTED_FILE_NAME_PATTERNS.some((pattern) => pattern.test(name));
|
|
30459
30496
|
}
|
|
30460
30497
|
function pluralize(count, singular, plural = `${singular}s`) {
|
|
30461
30498
|
return `${count} ${count === 1 ? singular : plural}`;
|
|
30462
30499
|
}
|
|
30500
|
+
async function retryDatabaseWrite(operation, attempts = 8) {
|
|
30501
|
+
for (let attempt = 1; ; attempt++) {
|
|
30502
|
+
try {
|
|
30503
|
+
return operation();
|
|
30504
|
+
} catch (error) {
|
|
30505
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30506
|
+
if (!/database is locked|database is busy/i.test(message) || attempt >= attempts) throw error;
|
|
30507
|
+
await new Promise((resolve21) => setTimeout(resolve21, Math.min(250 * attempt, 2e3)));
|
|
30508
|
+
}
|
|
30509
|
+
}
|
|
30510
|
+
}
|
|
30463
30511
|
function resolveFromProjectRoot(projectRoot, inputPath) {
|
|
30464
30512
|
return isAbsolute2(inputPath) ? inputPath : resolve19(projectRoot, inputPath);
|
|
30465
30513
|
}
|
|
@@ -30532,7 +30580,7 @@ function registerInternalExtractCommand(program) {
|
|
|
30532
30580
|
"--resolve-unreachable <mode>",
|
|
30533
30581
|
"Retry pass for unresolved Svelte Props types: 'auto' (default), 'always', or 'never'",
|
|
30534
30582
|
"auto"
|
|
30535
|
-
).option("--composition-refresh", "Force the mapping agent to run even where deterministic sources answered").option(
|
|
30583
|
+
).option("--composition-refresh", "Force the mapping agent to run even where deterministic sources answered").option("--no-cache", "Re-run extraction even when all source files are unchanged").option(
|
|
30536
30584
|
"--prompt <stage=value>",
|
|
30537
30585
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
30538
30586
|
(v, acc) => [...acc, v],
|
|
@@ -30542,6 +30590,7 @@ function registerInternalExtractCommand(program) {
|
|
|
30542
30590
|
includeModel: false,
|
|
30543
30591
|
agentDescription: "Coding agent for composition mapping resolution (claude|codex|opencode|cursor)"
|
|
30544
30592
|
}).action(async (opts) => {
|
|
30593
|
+
const noCache = resolveExtractNoCache(opts);
|
|
30545
30594
|
const resolveUnreachable = (() => {
|
|
30546
30595
|
const v = opts.resolveUnreachable ?? "auto";
|
|
30547
30596
|
if (v !== "auto" && v !== "always" && v !== "never") {
|
|
@@ -30579,16 +30628,50 @@ function registerInternalExtractCommand(program) {
|
|
|
30579
30628
|
`);
|
|
30580
30629
|
}
|
|
30581
30630
|
});
|
|
30582
|
-
const
|
|
30583
|
-
|
|
30584
|
-
|
|
30631
|
+
const extractionCacheDb = openPipelineDb();
|
|
30632
|
+
let extraction;
|
|
30633
|
+
let extractionCacheHits = 0;
|
|
30634
|
+
try {
|
|
30635
|
+
const cacheVersion = await getCliCacheVersion();
|
|
30636
|
+
const cachedByPath = /* @__PURE__ */ new Map();
|
|
30637
|
+
if (!noCache && sourceFiles.length > 0) {
|
|
30638
|
+
const hashes = await Promise.all(
|
|
30639
|
+
sourceFiles.map(async (filePath) => [filePath, await hashFile(filePath)])
|
|
30640
|
+
);
|
|
30641
|
+
for (const [filePath, fileHash] of hashes) {
|
|
30642
|
+
cachedByPath.set(filePath, lookupExtractCache(extractionCacheDb, fileHash, cacheVersion));
|
|
30643
|
+
}
|
|
30644
|
+
}
|
|
30645
|
+
const allFilesCached = !noCache && sourceFiles.length > 0 && sourceFiles.every((filePath) => cachedByPath.get(filePath) !== null);
|
|
30646
|
+
if (allFilesCached) {
|
|
30647
|
+
const cachedComponents = sourceFiles.flatMap((filePath) => cachedByPath.get(filePath).components);
|
|
30648
|
+
extractionCacheHits = sourceFiles.length;
|
|
30649
|
+
extraction = { components: cachedComponents, warnings: [] };
|
|
30585
30650
|
if (!process.stdout.isTTY) {
|
|
30586
|
-
process.stderr.write(
|
|
30587
|
-
`
|
|
30651
|
+
process.stderr.write(
|
|
30652
|
+
`progress=extract:${sourceFiles.length}/${sourceFiles.length}:${cachedComponents.length}
|
|
30653
|
+
`
|
|
30654
|
+
);
|
|
30588
30655
|
}
|
|
30589
|
-
|
|
30590
|
-
|
|
30591
|
-
|
|
30656
|
+
getDebugLogger().event("analyze", "extract.cache-hit", {
|
|
30657
|
+
files: sourceFiles.length,
|
|
30658
|
+
components: cachedComponents.length
|
|
30659
|
+
});
|
|
30660
|
+
} else {
|
|
30661
|
+
extraction = await extractComponents2(
|
|
30662
|
+
sourceFiles,
|
|
30663
|
+
({ filesProcessed, componentsFound }) => {
|
|
30664
|
+
if (!process.stdout.isTTY) {
|
|
30665
|
+
process.stderr.write(`progress=extract:${filesProcessed}/${sourceFiles.length}:${componentsFound}
|
|
30666
|
+
`);
|
|
30667
|
+
}
|
|
30668
|
+
},
|
|
30669
|
+
{ resolveUnreachable, projectRoot }
|
|
30670
|
+
);
|
|
30671
|
+
}
|
|
30672
|
+
} finally {
|
|
30673
|
+
extractionCacheDb.close();
|
|
30674
|
+
}
|
|
30592
30675
|
await mkdir6(outDir, { recursive: true });
|
|
30593
30676
|
const db = openPipelineDb();
|
|
30594
30677
|
const { sessionId: sessionId2 } = getOrCreateSession(db, void 0, void 0, {
|
|
@@ -30603,6 +30686,25 @@ function registerInternalExtractCommand(program) {
|
|
|
30603
30686
|
const stepId = createStep(db, sessionId2, "analyze extract", {
|
|
30604
30687
|
project: projectRoot
|
|
30605
30688
|
});
|
|
30689
|
+
if (extractionCacheHits === 0 && !noCache) {
|
|
30690
|
+
const cacheVersion = await getCliCacheVersion();
|
|
30691
|
+
const componentsBySourcePath = /* @__PURE__ */ new Map();
|
|
30692
|
+
for (const component of extraction.components) {
|
|
30693
|
+
if (!component.sourcePath) continue;
|
|
30694
|
+
const components = componentsBySourcePath.get(component.sourcePath) ?? [];
|
|
30695
|
+
components.push(component);
|
|
30696
|
+
componentsBySourcePath.set(component.sourcePath, components);
|
|
30697
|
+
}
|
|
30698
|
+
for (const filePath of sourceFiles) {
|
|
30699
|
+
storeExtractCache(
|
|
30700
|
+
db,
|
|
30701
|
+
filePath,
|
|
30702
|
+
await hashFile(filePath),
|
|
30703
|
+
cacheVersion,
|
|
30704
|
+
componentsBySourcePath.get(filePath) ?? []
|
|
30705
|
+
);
|
|
30706
|
+
}
|
|
30707
|
+
}
|
|
30606
30708
|
const classifiedComponents = extraction.components.map(preClassifyComponent);
|
|
30607
30709
|
const inspectedComponents = await Promise.all(
|
|
30608
30710
|
classifiedComponents.map(async (component) => ({
|
|
@@ -30647,7 +30749,10 @@ function registerInternalExtractCommand(program) {
|
|
|
30647
30749
|
}
|
|
30648
30750
|
let validatedComponents = validateExtractedComponents(filteredComponents);
|
|
30649
30751
|
{
|
|
30650
|
-
const sources = resolveCompositionSources(
|
|
30752
|
+
const sources = resolveCompositionSources({
|
|
30753
|
+
...opts,
|
|
30754
|
+
noCache
|
|
30755
|
+
});
|
|
30651
30756
|
const { overrides: promptOverrides, errors: promptErrors } = parsePromptOverrides(opts.prompt ?? []);
|
|
30652
30757
|
for (const err of promptErrors) {
|
|
30653
30758
|
process.stderr.write(`Error: ${err}
|
|
@@ -30714,7 +30819,7 @@ function registerInternalExtractCommand(program) {
|
|
|
30714
30819
|
files: promptFiles,
|
|
30715
30820
|
...compositionPrompt ? { promptOverride: compositionPrompt } : {},
|
|
30716
30821
|
runAgentFn: async ({ prompt }) => {
|
|
30717
|
-
if (!opts.compositionRefresh) {
|
|
30822
|
+
if (!noCache && !opts.compositionRefresh) {
|
|
30718
30823
|
const cached = lookupCompositionCache(db, agentCacheKey, cacheVersion);
|
|
30719
30824
|
if (cached !== null) {
|
|
30720
30825
|
emitCompositionProgress("cache-hit");
|
|
@@ -30741,7 +30846,7 @@ function registerInternalExtractCommand(program) {
|
|
|
30741
30846
|
validatedComponents = result.components;
|
|
30742
30847
|
}
|
|
30743
30848
|
}
|
|
30744
|
-
storeRawComponents(db, sessionId2, validatedComponents);
|
|
30849
|
+
await retryDatabaseWrite(() => storeRawComponents(db, sessionId2, validatedComponents));
|
|
30745
30850
|
const cycleInput = validatedComponents.map((c2) => ({
|
|
30746
30851
|
name: c2.name,
|
|
30747
30852
|
slots: c2.slots.map((s) => ({ name: s.name, allowedComponents: s.allowedComponents }))
|
|
@@ -30751,13 +30856,13 @@ function registerInternalExtractCommand(program) {
|
|
|
30751
30856
|
...cycle,
|
|
30752
30857
|
suggestedBreak: suggestCycleBreakEdge(cycle, cycles)
|
|
30753
30858
|
}));
|
|
30754
|
-
storeSlotCycles(db, sessionId2, withBreaks);
|
|
30859
|
+
await retryDatabaseWrite(() => storeSlotCycles(db, sessionId2, withBreaks));
|
|
30755
30860
|
storeScannedFiles(
|
|
30756
30861
|
db,
|
|
30757
30862
|
sessionId2,
|
|
30758
30863
|
sourceFiles.map((f) => relative2(projectRoot, f))
|
|
30759
30864
|
);
|
|
30760
|
-
updateStep(db, stepId, "complete", { sessionId: sessionId2 });
|
|
30865
|
+
await retryDatabaseWrite(() => updateStep(db, stepId, "complete", { sessionId: sessionId2 }));
|
|
30761
30866
|
enrichCommandResult({ extracted_component_count: validatedComponents.length });
|
|
30762
30867
|
db.close();
|
|
30763
30868
|
const allWarnings = [...extraction.warnings, ...filterWarnings];
|
|
@@ -30784,6 +30889,7 @@ var init_extract_command = __esm({
|
|
|
30784
30889
|
init_agent_model_options();
|
|
30785
30890
|
init_src3();
|
|
30786
30891
|
init_db();
|
|
30892
|
+
init_cache_keys();
|
|
30787
30893
|
init_cycle_detection();
|
|
30788
30894
|
init_resolve_mapping();
|
|
30789
30895
|
init_resolve_mapping_cli();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.34.5-dev-build-
|
|
3
|
+
"version": "2.34.5-dev-build-12a524fb.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"svelte": "^5.56.4",
|
|
42
42
|
"ts-morph": "^27.0.2",
|
|
43
43
|
"typescript": "^5.9.3",
|
|
44
|
-
"@contentful/experience-design-system-
|
|
45
|
-
"@contentful/experience-design-system-
|
|
44
|
+
"@contentful/experience-design-system-cli-v2": "2.34.5-dev-build-12a524fb.0",
|
|
45
|
+
"@contentful/experience-design-system-types": "2.34.5-dev-build-12a524fb.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"ink-testing-library": "^4.0.0",
|
|
55
55
|
"typescript-eslint": "^8.67.0",
|
|
56
56
|
"vitest": "^4.0.16",
|
|
57
|
-
"@contentful/experience-design-system-
|
|
58
|
-
"@contentful/experience-design-system-generation": "2.34.5-dev-build-
|
|
59
|
-
"@contentful/experience-design-system-
|
|
57
|
+
"@contentful/experience-design-system-client": "2.34.5-dev-build-12a524fb.0",
|
|
58
|
+
"@contentful/experience-design-system-generation": "2.34.5-dev-build-12a524fb.0",
|
|
59
|
+
"@contentful/experience-design-system-extraction": "2.34.5-dev-build-12a524fb.0"
|
|
60
60
|
},
|
|
61
61
|
"repository": {
|
|
62
62
|
"type": "git",
|