@contentful/experience-design-system-cli 2.37.1-dev-build-fb8573b6.0 → 2.37.1-dev-build-799db3ac.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/app.js +425 -3695
- package/dist/index.js +1316 -4762
- package/dist/package.json +1 -2
- package/dist/src/tui/import/spawn-v1-import.d.ts +3 -3
- package/dist/src/tui/import/steps/05-token-reuse/logic.d.ts +2 -1
- package/dist/src/tui/import/steps/index.d.ts +0 -1
- package/legacy/dist/src/import/tui/WizardApp.d.ts +8 -0
- package/legacy/dist/src/import/tui/run-selection-agent.d.ts +9 -0
- package/legacy/dist/src/index.js +628 -75
- package/legacy/package.json +1 -2
- package/package.json +3 -4
- package/dist/src/tui/import/steps/06-extraction/logic.d.ts +0 -69
- package/dist/src/tui/import/steps/06-extraction/processes.d.ts +0 -45
- package/dist/src/tui/import/steps/06-extraction/run.d.ts +0 -24
- package/dist/src/tui/import/steps/06-extraction/screen.d.ts +0 -10
- package/dist/src/tui/import/steps/06-extraction/selection.d.ts +0 -18
- package/dist/src/tui/import/steps/06-extraction/types.d.ts +0 -44
- package/dist/src/tui/import/steps/06-extraction/use-extraction.d.ts +0 -14
- package/legacy/dist/src/import/tui/handoff.d.ts +0 -26
package/legacy/dist/src/index.js
CHANGED
|
@@ -4163,6 +4163,34 @@ function lookupCompositionCache(db, inputHash, cliVersion2) {
|
|
|
4163
4163
|
const row = db.prepare(`SELECT agent_output FROM composition_cache WHERE input_hash = ? AND cli_version = ?`).get(inputHash, cliVersion2);
|
|
4164
4164
|
return row ? row.agent_output : null;
|
|
4165
4165
|
}
|
|
4166
|
+
function storeSelectCache(db, componentHash, promptHash, cliVersion2, decision, reason) {
|
|
4167
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4168
|
+
db.prepare(
|
|
4169
|
+
`INSERT INTO select_cache (component_hash, prompt_hash, cli_version, decision, reason, created_at, updated_at)
|
|
4170
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
4171
|
+
ON CONFLICT(component_hash, prompt_hash, cli_version) DO UPDATE SET
|
|
4172
|
+
decision = excluded.decision,
|
|
4173
|
+
reason = excluded.reason,
|
|
4174
|
+
updated_at = excluded.updated_at`
|
|
4175
|
+
).run(componentHash, promptHash, cliVersion2, decision, reason, now, now);
|
|
4176
|
+
}
|
|
4177
|
+
function lookupSelectCache(db, componentHash, promptHash, cliVersion2) {
|
|
4178
|
+
const row = db.prepare(
|
|
4179
|
+
`SELECT component_hash, prompt_hash, cli_version, decision, reason, created_at, updated_at
|
|
4180
|
+
FROM select_cache
|
|
4181
|
+
WHERE component_hash = ? AND prompt_hash = ? AND cli_version = ?`
|
|
4182
|
+
).get(componentHash, promptHash, cliVersion2);
|
|
4183
|
+
if (!row) return null;
|
|
4184
|
+
return {
|
|
4185
|
+
componentHash: row.component_hash,
|
|
4186
|
+
promptHash: row.prompt_hash,
|
|
4187
|
+
cliVersion: row.cli_version,
|
|
4188
|
+
decision: row.decision,
|
|
4189
|
+
reason: row.reason,
|
|
4190
|
+
createdAt: row.created_at,
|
|
4191
|
+
updatedAt: row.updated_at
|
|
4192
|
+
};
|
|
4193
|
+
}
|
|
4166
4194
|
var SCHEMA, MAX_COMPONENT_SOURCE_CHARS, MAX_SIBLING_FILES, MAX_SIBLING_SNIPPET_CHARS, MAX_TYPE_DECLARING_SIBLING_CHARS, MAX_ENLARGED_SIBLINGS, MAX_SIBLING_DEPTH, MAX_SIBLING_CANDIDATES_EXPLORED, RELATIVE_IMPORT_PATTERN, SIBLING_FILE_EXTENSIONS, TS_ESM_EXTENSION_REWRITES, IDENTIFIER_PATTERN, _cliCacheVersionCache;
|
|
4167
4195
|
var init_db = __esm({
|
|
4168
4196
|
"packages/experience-design-system-cli-legacy/src/session/db.ts"() {
|
|
@@ -9891,37 +9919,6 @@ var init_GateStep = __esm({
|
|
|
9891
9919
|
}
|
|
9892
9920
|
});
|
|
9893
9921
|
|
|
9894
|
-
// packages/experience-design-system-cli-legacy/src/import/tui/handoff.ts
|
|
9895
|
-
import { HANDOFF_ENV, parseHandoff } from "@contentful/experience-design-system-types/handoff";
|
|
9896
|
-
function stateFromHandoff(handoff) {
|
|
9897
|
-
const { extraction } = handoff;
|
|
9898
|
-
return {
|
|
9899
|
-
credentialsSkipped: handoff.credentialsSkipped,
|
|
9900
|
-
...extraction ? {
|
|
9901
|
-
tokensPath: extraction.tokensPath,
|
|
9902
|
-
tokenSessionId: extraction.tokenSessionId,
|
|
9903
|
-
tokenCount: extraction.tokenCount,
|
|
9904
|
-
tokenGenerationStatus: "complete",
|
|
9905
|
-
outDir: extraction.outDir,
|
|
9906
|
-
extractSessionId: extraction.sessionId,
|
|
9907
|
-
compositionPhase: extraction.compositionPhase,
|
|
9908
|
-
selectionAgentStatus: "complete",
|
|
9909
|
-
existingEntitiesStatus: extraction.existingEntitiesStatus,
|
|
9910
|
-
existingEntitiesPath: extraction.existingEntitiesPath
|
|
9911
|
-
} : {}
|
|
9912
|
-
};
|
|
9913
|
-
}
|
|
9914
|
-
function readHandoff(env = process.env) {
|
|
9915
|
-
const parsed = parseHandoff(env[HANDOFF_ENV]);
|
|
9916
|
-
if (!parsed.ok) return parsed;
|
|
9917
|
-
return { ok: true, handoff: parsed.handoff, state: stateFromHandoff(parsed.handoff) };
|
|
9918
|
-
}
|
|
9919
|
-
var init_handoff = __esm({
|
|
9920
|
-
"packages/experience-design-system-cli-legacy/src/import/tui/handoff.ts"() {
|
|
9921
|
-
"use strict";
|
|
9922
|
-
}
|
|
9923
|
-
});
|
|
9924
|
-
|
|
9925
9922
|
// packages/experience-design-system-cli-legacy/src/tui/use-terminal-size.ts
|
|
9926
9923
|
import { useStdout } from "ink";
|
|
9927
9924
|
import { useEffect as useEffect4, useState as useState6 } from "react";
|
|
@@ -27244,6 +27241,80 @@ var init_runScopeGate = __esm({
|
|
|
27244
27241
|
}
|
|
27245
27242
|
});
|
|
27246
27243
|
|
|
27244
|
+
// packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts
|
|
27245
|
+
import { createClient as createClient2 } from "contentful-management";
|
|
27246
|
+
function buildContentfulManagementClient(opts) {
|
|
27247
|
+
return createClient2(
|
|
27248
|
+
{
|
|
27249
|
+
accessToken: opts.cmaToken,
|
|
27250
|
+
...opts.host ? { host: toConfiguredHost(opts.host) } : {}
|
|
27251
|
+
},
|
|
27252
|
+
{ type: "plain" }
|
|
27253
|
+
);
|
|
27254
|
+
}
|
|
27255
|
+
var init_build_contentful_management_client = __esm({
|
|
27256
|
+
"packages/experience-design-system-cli-legacy/src/helpers/build-contentful-management-client.ts"() {
|
|
27257
|
+
"use strict";
|
|
27258
|
+
init_host_utils();
|
|
27259
|
+
}
|
|
27260
|
+
});
|
|
27261
|
+
|
|
27262
|
+
// packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-contentful-entities.ts
|
|
27263
|
+
import { fetchAll } from "contentful-management";
|
|
27264
|
+
async function fetchExistingContentfulEntitiesFromContentful(client2, params) {
|
|
27265
|
+
const componentScope = {
|
|
27266
|
+
spaceId: params.spaceId,
|
|
27267
|
+
environmentId: params.environmentId,
|
|
27268
|
+
query: { cursor: true, limit: 1e3 }
|
|
27269
|
+
};
|
|
27270
|
+
const tokenScope = {
|
|
27271
|
+
spaceId: params.spaceId,
|
|
27272
|
+
environmentId: params.environmentId,
|
|
27273
|
+
query: { cursor: true, limit: 1e3 }
|
|
27274
|
+
};
|
|
27275
|
+
const components = await fetchAll(client2.component.getMany, componentScope);
|
|
27276
|
+
const tokens = await fetchAll(client2.designToken.getMany, tokenScope);
|
|
27277
|
+
return { components, tokens };
|
|
27278
|
+
}
|
|
27279
|
+
var init_fetch_existing_contentful_entities = __esm({
|
|
27280
|
+
"packages/experience-design-system-cli-legacy/src/helpers/fetch-existing-contentful-entities.ts"() {
|
|
27281
|
+
"use strict";
|
|
27282
|
+
}
|
|
27283
|
+
});
|
|
27284
|
+
|
|
27285
|
+
// packages/experience-design-system-cli-legacy/src/helpers/fetch-and-persist-existing-contentful-entities.ts
|
|
27286
|
+
import { writeFile as writeFile4 } from "node:fs/promises";
|
|
27287
|
+
import { join as join19 } from "node:path";
|
|
27288
|
+
async function fetchAndPersistExistingContentfulEntities(params) {
|
|
27289
|
+
const t0 = Date.now();
|
|
27290
|
+
try {
|
|
27291
|
+
const client2 = buildContentfulManagementClient({
|
|
27292
|
+
cmaToken: params.cmaToken,
|
|
27293
|
+
...params.host ? { host: params.host } : {}
|
|
27294
|
+
});
|
|
27295
|
+
const entities = await fetchExistingContentfulEntitiesFromContentful(client2, {
|
|
27296
|
+
spaceId: params.spaceId,
|
|
27297
|
+
environmentId: params.environmentId
|
|
27298
|
+
});
|
|
27299
|
+
const path = join19(params.outDir, ".existing-entities.json");
|
|
27300
|
+
await writeFile4(path, JSON.stringify(entities, null, 2), "utf8");
|
|
27301
|
+
return { ok: true, path, durationMs: Date.now() - t0, entities };
|
|
27302
|
+
} catch (error) {
|
|
27303
|
+
return {
|
|
27304
|
+
ok: false,
|
|
27305
|
+
durationMs: Date.now() - t0,
|
|
27306
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27307
|
+
};
|
|
27308
|
+
}
|
|
27309
|
+
}
|
|
27310
|
+
var init_fetch_and_persist_existing_contentful_entities = __esm({
|
|
27311
|
+
"packages/experience-design-system-cli-legacy/src/helpers/fetch-and-persist-existing-contentful-entities.ts"() {
|
|
27312
|
+
"use strict";
|
|
27313
|
+
init_build_contentful_management_client();
|
|
27314
|
+
init_fetch_existing_contentful_entities();
|
|
27315
|
+
}
|
|
27316
|
+
});
|
|
27317
|
+
|
|
27247
27318
|
// packages/experience-design-system-cli-legacy/src/import/tui/wizard-state-transitions.ts
|
|
27248
27319
|
function shouldGenerateAfterScopeGate(opts) {
|
|
27249
27320
|
return opts.acceptedCount > 0;
|
|
@@ -27279,11 +27350,121 @@ var init_wizard_state_transitions = __esm({
|
|
|
27279
27350
|
}
|
|
27280
27351
|
});
|
|
27281
27352
|
|
|
27353
|
+
// packages/experience-design-system-cli-legacy/src/import/tui/run-selection-agent.ts
|
|
27354
|
+
async function runSelectionAgent(options) {
|
|
27355
|
+
const db = openPipelineDb();
|
|
27356
|
+
let components;
|
|
27357
|
+
const cachedDecisions = /* @__PURE__ */ new Map();
|
|
27358
|
+
const cliVersion2 = await getCliCacheVersion();
|
|
27359
|
+
const promptHash = await hashPromptForSkill(
|
|
27360
|
+
"select",
|
|
27361
|
+
options.agent,
|
|
27362
|
+
options.model,
|
|
27363
|
+
options.promptPath,
|
|
27364
|
+
[],
|
|
27365
|
+
options.promptText
|
|
27366
|
+
);
|
|
27367
|
+
try {
|
|
27368
|
+
components = loadRawComponents(db, options.sessionId);
|
|
27369
|
+
if (!options.noCache) {
|
|
27370
|
+
for (const component of components) {
|
|
27371
|
+
const componentHash = hashComponentShape(component);
|
|
27372
|
+
const cached = lookupSelectCache(db, componentHash, promptHash, cliVersion2);
|
|
27373
|
+
if (cached) {
|
|
27374
|
+
cachedDecisions.set(component.name, {
|
|
27375
|
+
decision: cached.decision,
|
|
27376
|
+
reason: cached.reason
|
|
27377
|
+
});
|
|
27378
|
+
}
|
|
27379
|
+
}
|
|
27380
|
+
}
|
|
27381
|
+
} finally {
|
|
27382
|
+
db.close();
|
|
27383
|
+
}
|
|
27384
|
+
if (components.length === 0) return;
|
|
27385
|
+
const componentsToRun = components.filter((component) => !cachedDecisions.has(component.name));
|
|
27386
|
+
let calls = [];
|
|
27387
|
+
if (componentsToRun.length > 0) {
|
|
27388
|
+
const invoker2 = createLocalCliAgentInvoker({
|
|
27389
|
+
onDebugEvent: (name, payload) => getDebugLogger().event("agent", name, payload)
|
|
27390
|
+
});
|
|
27391
|
+
const prompt = await buildPrompt({
|
|
27392
|
+
skill: "select",
|
|
27393
|
+
mode: "autonomous",
|
|
27394
|
+
rawComponentsInline: JSON.stringify(componentsToRun, null, 2),
|
|
27395
|
+
outDir: process.cwd(),
|
|
27396
|
+
...options.promptText !== void 0 ? { skillContentOverride: options.promptText } : {},
|
|
27397
|
+
...options.promptText === void 0 && options.promptPath ? { skillPathOverride: options.promptPath } : {}
|
|
27398
|
+
});
|
|
27399
|
+
const { result } = await invokeAgentWithOutput(
|
|
27400
|
+
invoker2,
|
|
27401
|
+
{ agent: options.agent, model: options.model, prompt, timeoutMs: DEFAULT_TIMEOUT_MS4 },
|
|
27402
|
+
false
|
|
27403
|
+
);
|
|
27404
|
+
if (result.timedOut) throw new Error("selection agent timed out");
|
|
27405
|
+
if (result.exitCode !== 0) throw new Error(`selection agent exited with code ${result.exitCode}`);
|
|
27406
|
+
const parsed = parseSelectToolCallLines(result.stdout);
|
|
27407
|
+
for (const warning of parsed.warnings) process.stderr.write(`Warning: selection agent: ${warning}
|
|
27408
|
+
`);
|
|
27409
|
+
calls = parsed.calls;
|
|
27410
|
+
}
|
|
27411
|
+
const byName = new Map(calls.map((call) => [call.name, call]));
|
|
27412
|
+
const writeDb = openPipelineDb();
|
|
27413
|
+
try {
|
|
27414
|
+
writeDb.exec("BEGIN");
|
|
27415
|
+
const update = writeDb.prepare(
|
|
27416
|
+
`UPDATE raw_components SET status = ?, reject_reason = ? WHERE session_id = ? AND component_id = ?`
|
|
27417
|
+
);
|
|
27418
|
+
for (const component of components) {
|
|
27419
|
+
const cached = cachedDecisions.get(component.name);
|
|
27420
|
+
const call = byName.get(component.name);
|
|
27421
|
+
if (!cached && !call) continue;
|
|
27422
|
+
const rejected = cached ? cached.decision === "rejected" : call.tool === "reject_component";
|
|
27423
|
+
const reason = cached ? cached.reason : call.reason ?? null;
|
|
27424
|
+
update.run(
|
|
27425
|
+
rejected ? "rejected" : "accepted",
|
|
27426
|
+
rejected ? reason : null,
|
|
27427
|
+
options.sessionId,
|
|
27428
|
+
component.component_id
|
|
27429
|
+
);
|
|
27430
|
+
if (!cached) {
|
|
27431
|
+
storeSelectCache(
|
|
27432
|
+
writeDb,
|
|
27433
|
+
hashComponentShape(component),
|
|
27434
|
+
promptHash,
|
|
27435
|
+
cliVersion2,
|
|
27436
|
+
rejected ? "rejected" : "accepted",
|
|
27437
|
+
rejected ? reason : null
|
|
27438
|
+
);
|
|
27439
|
+
}
|
|
27440
|
+
}
|
|
27441
|
+
writeDb.exec("COMMIT");
|
|
27442
|
+
} catch (error) {
|
|
27443
|
+
writeDb.exec("ROLLBACK");
|
|
27444
|
+
throw error;
|
|
27445
|
+
} finally {
|
|
27446
|
+
writeDb.close();
|
|
27447
|
+
}
|
|
27448
|
+
}
|
|
27449
|
+
var DEFAULT_TIMEOUT_MS4;
|
|
27450
|
+
var init_run_selection_agent = __esm({
|
|
27451
|
+
"packages/experience-design-system-cli-legacy/src/import/tui/run-selection-agent.ts"() {
|
|
27452
|
+
"use strict";
|
|
27453
|
+
init_src();
|
|
27454
|
+
init_debug_logger();
|
|
27455
|
+
init_agent_output();
|
|
27456
|
+
init_db();
|
|
27457
|
+
init_cache_keys();
|
|
27458
|
+
DEFAULT_TIMEOUT_MS4 = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 5 * 60 * 1e3);
|
|
27459
|
+
}
|
|
27460
|
+
});
|
|
27461
|
+
|
|
27282
27462
|
// packages/experience-design-system-cli-legacy/src/import/tui/WizardApp.tsx
|
|
27283
27463
|
var WizardApp_exports = {};
|
|
27284
27464
|
__export(WizardApp_exports, {
|
|
27285
27465
|
WizardApp: () => WizardApp,
|
|
27286
27466
|
buildGenerateComponentsArgs: () => buildGenerateComponentsArgs,
|
|
27467
|
+
buildGenerateTokensArgs: () => buildGenerateTokensArgs,
|
|
27287
27468
|
buildMapTokensArgs: () => buildMapTokensArgs,
|
|
27288
27469
|
buildSavedCDF: () => buildSavedCDF,
|
|
27289
27470
|
formatAcceptanceSummary: () => formatAcceptanceSummary,
|
|
@@ -27292,11 +27473,11 @@ __export(WizardApp_exports, {
|
|
|
27292
27473
|
});
|
|
27293
27474
|
import { useEffect as useEffect14, useRef as useRef9, useState as useState19 } from "react";
|
|
27294
27475
|
import { Box as Box38, Text as Text40 } from "ink";
|
|
27295
|
-
import { join as
|
|
27476
|
+
import { join as join20, resolve as resolve18 } from "node:path";
|
|
27296
27477
|
import { appendFileSync as appendFileSync2, writeFileSync } from "node:fs";
|
|
27297
|
-
import { writeFile as
|
|
27478
|
+
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
27298
27479
|
import { tmpdir } from "node:os";
|
|
27299
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
27480
|
+
import { execFile as execFile2, spawn as spawn5 } from "node:child_process";
|
|
27300
27481
|
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
27301
27482
|
import { buildCDF as buildCDF3, validateCDF as validateCDF3, validateSlotReferences as validateSlotReferences2 } from "@contentful/experience-design-system-types";
|
|
27302
27483
|
import { jsx as jsx47, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
@@ -27315,6 +27496,14 @@ function buildGenerateComponentsArgs(opts) {
|
|
|
27315
27496
|
}
|
|
27316
27497
|
return args;
|
|
27317
27498
|
}
|
|
27499
|
+
function buildGenerateTokensArgs(opts) {
|
|
27500
|
+
const args = [findCliPath(), "__generate", "tokens", "--agent", opts.agent, "--raw-tokens", opts.rawTokensPath];
|
|
27501
|
+
if (opts.model) args.push("--model", opts.model);
|
|
27502
|
+
if (opts.bedrock) args.push("--bedrock");
|
|
27503
|
+
if (opts.noCache) args.push("--no-cache");
|
|
27504
|
+
for (const prompt of opts.promptOverrides ?? []) args.push("--prompt", prompt);
|
|
27505
|
+
return args;
|
|
27506
|
+
}
|
|
27318
27507
|
function buildMapTokensArgs(opts) {
|
|
27319
27508
|
const args = ["map", "tokens", "--session", opts.sessionId, "--agent", opts.agent];
|
|
27320
27509
|
if (opts.model) args.push("--model", opts.model);
|
|
@@ -27348,6 +27537,24 @@ function runCli(args) {
|
|
|
27348
27537
|
});
|
|
27349
27538
|
});
|
|
27350
27539
|
}
|
|
27540
|
+
function runSpawnedCli(args, onStderr, onStdout) {
|
|
27541
|
+
return new Promise((res) => {
|
|
27542
|
+
const child = spawn5("node", args);
|
|
27543
|
+
let stdout = "";
|
|
27544
|
+
let stderr = "";
|
|
27545
|
+
child.stdout.on("data", (d) => {
|
|
27546
|
+
const chunk = String(d);
|
|
27547
|
+
stdout += chunk;
|
|
27548
|
+
onStdout?.(chunk);
|
|
27549
|
+
});
|
|
27550
|
+
child.stderr.on("data", (d) => {
|
|
27551
|
+
const chunk = String(d);
|
|
27552
|
+
stderr += chunk;
|
|
27553
|
+
onStderr?.(chunk);
|
|
27554
|
+
});
|
|
27555
|
+
child.on("exit", (code) => res({ exitCode: code ?? 0, stdout, stderr }));
|
|
27556
|
+
});
|
|
27557
|
+
}
|
|
27351
27558
|
function buildGenerateProcessArgs(opts) {
|
|
27352
27559
|
return [findCliPath(), ...buildGenerateComponentsArgs(opts)];
|
|
27353
27560
|
}
|
|
@@ -27417,16 +27624,19 @@ function WizardApp({
|
|
|
27417
27624
|
const allowEmptyDeleteAllRef = useRef9(false);
|
|
27418
27625
|
const generationCachePreflightRef = useRef9(null);
|
|
27419
27626
|
const selectionToReviewStartedAtRef = useRef9(null);
|
|
27627
|
+
const tokenGenerationPromiseRef = useRef9(null);
|
|
27628
|
+
const extractPromiseRef = useRef9(null);
|
|
27629
|
+
const extractStartedRef = useRef9(false);
|
|
27420
27630
|
const credentialsReadyRef = useRef9(false);
|
|
27421
27631
|
const agentAuthVerifiedRef = useRef9(false);
|
|
27422
27632
|
const scopeGateCompletedRef = useRef9(false);
|
|
27423
27633
|
const scopeComponentsRef = useRef9(null);
|
|
27634
|
+
const existingEntitiesPromiseRef = useRef9(null);
|
|
27424
27635
|
const generatePromiseRef = useRef9(null);
|
|
27425
27636
|
const rawTokensEntryReady = !!initialRawTokensPath;
|
|
27426
27637
|
const effectiveNoCache = resolveNoCacheForGenerate({ cliNoCache: noCache });
|
|
27427
|
-
const
|
|
27428
|
-
const
|
|
27429
|
-
const initialOutDir = initialProjectPath ? join19(resolve18(initialProjectPath), ".contentful") : "";
|
|
27638
|
+
const initialStepResolved = "credentials";
|
|
27639
|
+
const initialOutDir = initialProjectPath ? join20(resolve18(initialProjectPath), ".contentful") : "";
|
|
27430
27640
|
const [state, setState] = useState19({
|
|
27431
27641
|
step: initialStepResolved,
|
|
27432
27642
|
agent: initialAgent ?? "claude",
|
|
@@ -27436,6 +27646,7 @@ function WizardApp({
|
|
|
27436
27646
|
outDir: initialOutDir,
|
|
27437
27647
|
rawTokensPath: rawTokensEntryReady ? initialRawTokensPath : "",
|
|
27438
27648
|
tokensPath: "",
|
|
27649
|
+
skipComponents: false,
|
|
27439
27650
|
tokenSessionId: null,
|
|
27440
27651
|
tokenGenerationStatus: "idle",
|
|
27441
27652
|
mapTokensStatus: "idle",
|
|
@@ -27448,6 +27659,7 @@ function WizardApp({
|
|
|
27448
27659
|
generatedAcceptedCount: 0,
|
|
27449
27660
|
generateProgress: null,
|
|
27450
27661
|
selectionAgentStatus: "idle",
|
|
27662
|
+
extractProgress: null,
|
|
27451
27663
|
compositionPhase: null,
|
|
27452
27664
|
componentsPath: "",
|
|
27453
27665
|
spaceId: initialSpaceId,
|
|
@@ -27472,12 +27684,12 @@ function WizardApp({
|
|
|
27472
27684
|
credentialsValidating: false,
|
|
27473
27685
|
credentialsBackgroundValidating: false,
|
|
27474
27686
|
mapTokensEligible: null,
|
|
27687
|
+
credentialsSkipped: false,
|
|
27475
27688
|
existingEntitiesPath: null,
|
|
27476
27689
|
existingEntitiesStatus: "idle",
|
|
27477
27690
|
lastRunId: null,
|
|
27478
27691
|
finalizeErrorBanner: null,
|
|
27479
|
-
finalReviewPassed: false
|
|
27480
|
-
...startedFrom.ok ? startedFrom.state : { credentialsSkipped: false, errorStep: "start import", errorMessage: startedFrom.error }
|
|
27692
|
+
finalReviewPassed: false
|
|
27481
27693
|
});
|
|
27482
27694
|
useEffect14(() => {
|
|
27483
27695
|
sessionRef.current = {
|
|
@@ -27597,6 +27809,58 @@ If you are using AWS Bedrock, run:
|
|
|
27597
27809
|
if (!deferStep) update({ step: nextStep });
|
|
27598
27810
|
return true;
|
|
27599
27811
|
};
|
|
27812
|
+
const runGenerateTokens = async (rawTokensPath, outDir, forceRegenerate = false) => {
|
|
27813
|
+
update({ tokenGenerationStatus: "running" });
|
|
27814
|
+
const tokenArgs = buildGenerateTokensArgs({
|
|
27815
|
+
rawTokensPath,
|
|
27816
|
+
agent: state.agent,
|
|
27817
|
+
...state.agentModel ? { model: state.agentModel } : {},
|
|
27818
|
+
...state.bedrock ? { bedrock: true } : {},
|
|
27819
|
+
noCache: effectiveNoCache || forceRegenerate,
|
|
27820
|
+
promptOverrides
|
|
27821
|
+
});
|
|
27822
|
+
const result = await runSpawnedCli(tokenArgs);
|
|
27823
|
+
if (result.exitCode !== 0) {
|
|
27824
|
+
update({
|
|
27825
|
+
step: "error",
|
|
27826
|
+
tokenGenerationStatus: "failed",
|
|
27827
|
+
errorStep: "generate tokens",
|
|
27828
|
+
errorMessage: result.stderr.trim() || "Unknown error"
|
|
27829
|
+
});
|
|
27830
|
+
return false;
|
|
27831
|
+
}
|
|
27832
|
+
const sessionMatch = /^session=(.+)$/m.exec(result.stdout);
|
|
27833
|
+
const tokenSessionId = sessionMatch ? sessionMatch[1].trim() : null;
|
|
27834
|
+
const tokensPath = join20(outDir, "tokens.json");
|
|
27835
|
+
const printArgs = ["print", "tokens", "--out", tokensPath];
|
|
27836
|
+
if (tokenSessionId) printArgs.push("--session", tokenSessionId);
|
|
27837
|
+
const r = await runCli(printArgs);
|
|
27838
|
+
if (r.exitCode !== 0) {
|
|
27839
|
+
update({
|
|
27840
|
+
step: "error",
|
|
27841
|
+
tokenGenerationStatus: "failed",
|
|
27842
|
+
errorStep: "print tokens",
|
|
27843
|
+
errorMessage: r.stderr.trim() || "Unknown error"
|
|
27844
|
+
});
|
|
27845
|
+
return false;
|
|
27846
|
+
}
|
|
27847
|
+
const tokenCount = parsePrintTokensCount(r.stdout);
|
|
27848
|
+
if (!state.projectPath) {
|
|
27849
|
+
update({
|
|
27850
|
+
tokensPath,
|
|
27851
|
+
tokenSessionId,
|
|
27852
|
+
tokenCount,
|
|
27853
|
+
tokenGenerationStatus: "complete",
|
|
27854
|
+
skipComponents: true,
|
|
27855
|
+
acceptedCount: 0,
|
|
27856
|
+
outDir: state.outDir || join20(process.cwd(), ".contentful")
|
|
27857
|
+
});
|
|
27858
|
+
update({ step: "credentials" });
|
|
27859
|
+
return true;
|
|
27860
|
+
}
|
|
27861
|
+
update({ tokensPath, tokenSessionId, tokenCount, tokenGenerationStatus: "complete" });
|
|
27862
|
+
return true;
|
|
27863
|
+
};
|
|
27600
27864
|
const runMapTokens2 = async (sessionId2, silent = false) => {
|
|
27601
27865
|
const timer = startWizardTimer("token-mapping", {
|
|
27602
27866
|
sessionId: sessionId2,
|
|
@@ -27680,6 +27944,236 @@ If you are using AWS Bedrock, run:
|
|
|
27680
27944
|
});
|
|
27681
27945
|
return true;
|
|
27682
27946
|
};
|
|
27947
|
+
const startExistingEntitiesFetch = (projectPath, outDir) => {
|
|
27948
|
+
if (state.credentialsSkipped || !state.spaceId || !state.environmentId || !state.cmaToken || !projectPath) {
|
|
27949
|
+
return null;
|
|
27950
|
+
}
|
|
27951
|
+
const startedAt = Date.now();
|
|
27952
|
+
getDebugLogger().event("wizard", "existing-entities.fetch.start", {
|
|
27953
|
+
spaceId: state.spaceId,
|
|
27954
|
+
environmentId: state.environmentId,
|
|
27955
|
+
host: state.host,
|
|
27956
|
+
outDir
|
|
27957
|
+
});
|
|
27958
|
+
update({ existingEntitiesStatus: "running" });
|
|
27959
|
+
const promise = (async () => {
|
|
27960
|
+
try {
|
|
27961
|
+
await mkdir4(outDir, { recursive: true });
|
|
27962
|
+
const result = await fetchAndPersistExistingContentfulEntities({
|
|
27963
|
+
spaceId: state.spaceId,
|
|
27964
|
+
environmentId: state.environmentId,
|
|
27965
|
+
cmaToken: state.cmaToken,
|
|
27966
|
+
...state.host ? { host: state.host } : {},
|
|
27967
|
+
outDir
|
|
27968
|
+
});
|
|
27969
|
+
if (result.ok) {
|
|
27970
|
+
getDebugLogger().event("wizard", "existing-entities.fetch.ok", {
|
|
27971
|
+
durationMs: result.durationMs,
|
|
27972
|
+
components: result.entities.components.length,
|
|
27973
|
+
tokens: result.entities.tokens.length
|
|
27974
|
+
});
|
|
27975
|
+
update({ existingEntitiesPath: result.path, existingEntitiesStatus: "complete" });
|
|
27976
|
+
return true;
|
|
27977
|
+
}
|
|
27978
|
+
getDebugLogger().event("wizard", "existing-entities.fetch.error", {
|
|
27979
|
+
durationMs: result.durationMs,
|
|
27980
|
+
error: result.error
|
|
27981
|
+
});
|
|
27982
|
+
update({ existingEntitiesStatus: "failed" });
|
|
27983
|
+
return false;
|
|
27984
|
+
} catch (error) {
|
|
27985
|
+
getDebugLogger().event("wizard", "existing-entities.fetch.error", {
|
|
27986
|
+
durationMs: Date.now() - startedAt,
|
|
27987
|
+
error: error instanceof Error ? error.message : String(error)
|
|
27988
|
+
});
|
|
27989
|
+
update({ existingEntitiesStatus: "failed" });
|
|
27990
|
+
return false;
|
|
27991
|
+
}
|
|
27992
|
+
})();
|
|
27993
|
+
existingEntitiesPromiseRef.current = promise;
|
|
27994
|
+
return promise;
|
|
27995
|
+
};
|
|
27996
|
+
const runExtract = async (projectPath, showProgress = true) => {
|
|
27997
|
+
const outDir = join20(resolve18(projectPath), ".contentful");
|
|
27998
|
+
const existingEntitiesExpected = !state.credentialsSkipped && Boolean(state.spaceId && state.environmentId && state.cmaToken && projectPath);
|
|
27999
|
+
update({
|
|
28000
|
+
...showProgress ? { step: "extracting" } : {},
|
|
28001
|
+
outDir,
|
|
28002
|
+
extractProgress: null,
|
|
28003
|
+
compositionPhase: "resolving",
|
|
28004
|
+
// Put every extraction-stage task on the first frame. The selection
|
|
28005
|
+
// agent cannot start until extraction emits its session, but it is
|
|
28006
|
+
// already part of this stage and should not appear later as a new row.
|
|
28007
|
+
selectionAgentStatus: state.agent ? "running" : "complete",
|
|
28008
|
+
existingEntitiesStatus: existingEntitiesExpected ? "running" : "idle"
|
|
28009
|
+
});
|
|
28010
|
+
const existingEntitiesPromise = startExistingEntitiesFetch(projectPath, outDir);
|
|
28011
|
+
const extractArgs = [findCliPath(), "__extract", "--project", projectPath];
|
|
28012
|
+
if (effectiveNoCache) extractArgs.push("--composition-refresh", "--no-cache");
|
|
28013
|
+
for (const p of promptOverrides ?? []) extractArgs.push("--prompt", p);
|
|
28014
|
+
if (state.agent) extractArgs.push("--agent", state.agent);
|
|
28015
|
+
if (state.bedrock) extractArgs.push("--bedrock");
|
|
28016
|
+
let selectionPromptText;
|
|
28017
|
+
let selectionPromptPath;
|
|
28018
|
+
try {
|
|
28019
|
+
const { overrides, errors } = parsePromptOverrides(promptOverrides ?? []);
|
|
28020
|
+
if (errors.length > 0) throw new Error(errors.join("; "));
|
|
28021
|
+
const selectOverride = overrides.get("select");
|
|
28022
|
+
if (selectOverride?.kind === "text") selectionPromptText = selectOverride.value;
|
|
28023
|
+
if (selectOverride?.kind === "path") {
|
|
28024
|
+
selectionPromptPath = resolve18(selectOverride.value);
|
|
28025
|
+
await resolvePromptOverride(selectOverride);
|
|
28026
|
+
}
|
|
28027
|
+
} catch (error) {
|
|
28028
|
+
update({
|
|
28029
|
+
step: "error",
|
|
28030
|
+
errorStep: "selection agent",
|
|
28031
|
+
errorMessage: error instanceof Error ? error.message : String(error)
|
|
28032
|
+
});
|
|
28033
|
+
return;
|
|
28034
|
+
}
|
|
28035
|
+
let selectionPromise = null;
|
|
28036
|
+
let selectionError;
|
|
28037
|
+
let selectionStarted = false;
|
|
28038
|
+
const startSelection = (sessionId2) => {
|
|
28039
|
+
if (selectionStarted || !state.agent) return;
|
|
28040
|
+
selectionStarted = true;
|
|
28041
|
+
selectionPromise = (async () => {
|
|
28042
|
+
if (existingEntitiesPromise) await existingEntitiesPromise;
|
|
28043
|
+
await runSelectionAgent({
|
|
28044
|
+
sessionId: sessionId2,
|
|
28045
|
+
agent: state.agent,
|
|
28046
|
+
...state.agentModel ? { model: state.agentModel } : {},
|
|
28047
|
+
...selectionPromptText !== void 0 ? { promptText: selectionPromptText } : {},
|
|
28048
|
+
...selectionPromptPath ? { promptPath: selectionPromptPath } : {},
|
|
28049
|
+
noCache: effectiveNoCache
|
|
28050
|
+
});
|
|
28051
|
+
})().catch((error) => {
|
|
28052
|
+
selectionError = error;
|
|
28053
|
+
}).finally(() => update({ selectionAgentStatus: "complete" }));
|
|
28054
|
+
};
|
|
28055
|
+
let stderrBuffer = "";
|
|
28056
|
+
let stdoutBuffer = "";
|
|
28057
|
+
const r = await runSpawnedCli(
|
|
28058
|
+
extractArgs,
|
|
28059
|
+
(chunk) => {
|
|
28060
|
+
stderrBuffer += chunk;
|
|
28061
|
+
const lines = stderrBuffer.split("\n");
|
|
28062
|
+
stderrBuffer = lines.pop() ?? "";
|
|
28063
|
+
for (const line of lines) {
|
|
28064
|
+
const scanMatch = /^progress=scan:(\d+)$/.exec(line.trim());
|
|
28065
|
+
if (scanMatch) {
|
|
28066
|
+
const scanned = Number(scanMatch[1]);
|
|
28067
|
+
setState((prev) => ({
|
|
28068
|
+
...prev,
|
|
28069
|
+
extractProgress: {
|
|
28070
|
+
scanned,
|
|
28071
|
+
filesProcessed: prev.extractProgress?.filesProcessed ?? 0,
|
|
28072
|
+
totalFiles: prev.extractProgress?.totalFiles ?? 0,
|
|
28073
|
+
componentsFound: prev.extractProgress?.componentsFound ?? 0
|
|
28074
|
+
}
|
|
28075
|
+
}));
|
|
28076
|
+
continue;
|
|
28077
|
+
}
|
|
28078
|
+
const scanDoneMatch = /^progress=scan-done:(\d+)$/.exec(line.trim());
|
|
28079
|
+
if (scanDoneMatch) {
|
|
28080
|
+
const scanned = Number(scanDoneMatch[1]);
|
|
28081
|
+
setState((prev) => ({
|
|
28082
|
+
...prev,
|
|
28083
|
+
extractProgress: {
|
|
28084
|
+
scanned,
|
|
28085
|
+
filesProcessed: prev.extractProgress?.filesProcessed ?? 0,
|
|
28086
|
+
totalFiles: scanned,
|
|
28087
|
+
componentsFound: prev.extractProgress?.componentsFound ?? 0
|
|
28088
|
+
}
|
|
28089
|
+
}));
|
|
28090
|
+
continue;
|
|
28091
|
+
}
|
|
28092
|
+
const extractMatch = /^progress=extract:(\d+)\/(\d+):(\d+)$/.exec(line.trim());
|
|
28093
|
+
if (extractMatch) {
|
|
28094
|
+
const filesProcessed = Number(extractMatch[1]);
|
|
28095
|
+
const totalFiles = Number(extractMatch[2]);
|
|
28096
|
+
const componentsFound = Number(extractMatch[3]);
|
|
28097
|
+
setState((prev) => ({
|
|
28098
|
+
...prev,
|
|
28099
|
+
extractProgress: {
|
|
28100
|
+
scanned: prev.extractProgress?.scanned ?? 0,
|
|
28101
|
+
filesProcessed,
|
|
28102
|
+
totalFiles,
|
|
28103
|
+
componentsFound
|
|
28104
|
+
}
|
|
28105
|
+
}));
|
|
28106
|
+
continue;
|
|
28107
|
+
}
|
|
28108
|
+
const compositionMatch = /^progress=composition:(.+)$/.exec(line.trim());
|
|
28109
|
+
if (compositionMatch) {
|
|
28110
|
+
setState((prev) => ({ ...prev, compositionPhase: compositionMatch[1].trim() }));
|
|
28111
|
+
}
|
|
28112
|
+
}
|
|
28113
|
+
},
|
|
28114
|
+
(chunk) => {
|
|
28115
|
+
stdoutBuffer += chunk;
|
|
28116
|
+
const lines = stdoutBuffer.split("\n");
|
|
28117
|
+
stdoutBuffer = lines.pop() ?? "";
|
|
28118
|
+
for (const line of lines) {
|
|
28119
|
+
const sessionMatch2 = /^session=(.+)$/.exec(line.trim());
|
|
28120
|
+
if (sessionMatch2) startSelection(sessionMatch2[1].trim());
|
|
28121
|
+
}
|
|
28122
|
+
}
|
|
28123
|
+
);
|
|
28124
|
+
const sessionMatch = /^session=(.+)$/m.exec(r.stdout);
|
|
28125
|
+
if (!selectionStarted && sessionMatch) startSelection(sessionMatch[1].trim());
|
|
28126
|
+
if (selectionPromise) await selectionPromise;
|
|
28127
|
+
if (!selectionStarted && existingEntitiesPromise) await existingEntitiesPromise;
|
|
28128
|
+
if (r.exitCode !== 0) {
|
|
28129
|
+
update({
|
|
28130
|
+
step: "error",
|
|
28131
|
+
errorStep: "analyze extract",
|
|
28132
|
+
errorMessage: r.stderr.trim() || "Unknown error"
|
|
28133
|
+
});
|
|
28134
|
+
return;
|
|
28135
|
+
}
|
|
28136
|
+
const extractSessionId = sessionMatch ? sessionMatch[1].trim() : null;
|
|
28137
|
+
const countMatch = /Extracted (\d+) components?/.exec(r.stderr);
|
|
28138
|
+
const extractedCount = countMatch ? Number(countMatch[1]) : 0;
|
|
28139
|
+
if (extractedCount === 0) {
|
|
28140
|
+
update({
|
|
28141
|
+
step: "error",
|
|
28142
|
+
errorStep: "analyze extract",
|
|
28143
|
+
errorMessage: `No components found in ${projectPath}.
|
|
28144
|
+
|
|
28145
|
+
Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .vue, etc.).`
|
|
28146
|
+
});
|
|
28147
|
+
return;
|
|
28148
|
+
}
|
|
28149
|
+
if (selectionError) {
|
|
28150
|
+
update({
|
|
28151
|
+
step: "error",
|
|
28152
|
+
errorStep: "selection agent",
|
|
28153
|
+
errorMessage: selectionError instanceof Error ? selectionError.message : String(selectionError)
|
|
28154
|
+
});
|
|
28155
|
+
return;
|
|
28156
|
+
}
|
|
28157
|
+
if (state.rawTokensPath && tokenGenerationPromiseRef.current) {
|
|
28158
|
+
const tokenGenerationSucceeded = await tokenGenerationPromiseRef.current;
|
|
28159
|
+
tokenGenerationPromiseRef.current = null;
|
|
28160
|
+
if (!tokenGenerationSucceeded) return;
|
|
28161
|
+
}
|
|
28162
|
+
update({
|
|
28163
|
+
extractSessionId,
|
|
28164
|
+
selectionAgentStatus: "complete",
|
|
28165
|
+
...credentialsReadyRef.current ? { step: "scope-gate" } : {}
|
|
28166
|
+
});
|
|
28167
|
+
};
|
|
28168
|
+
const startExtract = (projectPath, showProgress = true) => {
|
|
28169
|
+
if (extractStartedRef.current) return;
|
|
28170
|
+
extractStartedRef.current = true;
|
|
28171
|
+
const promise = runExtract(projectPath, showProgress);
|
|
28172
|
+
extractPromiseRef.current = promise;
|
|
28173
|
+
void promise.finally(() => {
|
|
28174
|
+
extractPromiseRef.current = null;
|
|
28175
|
+
});
|
|
28176
|
+
};
|
|
27683
28177
|
const buildGenerateOptions = (extractSessionId, tokensPath, generatePromptPath2, cachedComponents) => ({
|
|
27684
28178
|
sessionId: extractSessionId,
|
|
27685
28179
|
tokensPath,
|
|
@@ -27765,7 +28259,7 @@ If you are using AWS Bedrock, run:
|
|
|
27765
28259
|
}
|
|
27766
28260
|
};
|
|
27767
28261
|
useEffect14(() => {
|
|
27768
|
-
if (state.step !== "scope-gate" || !state.extractSessionId || state.existingEntitiesStatus === "running" || state.existingEntitiesStatus === "idle" || state.selectionAgentStatus !== "complete" || state.compositionPhase !== "done" && state.compositionPhase !== "cache-hit" || state.rawTokensPath && state.tokenGenerationStatus !== "complete" || effectiveNoCache) {
|
|
28262
|
+
if (state.step !== "extracting" && state.step !== "scope-gate" || !state.extractSessionId || state.existingEntitiesStatus === "running" || state.existingEntitiesStatus === "idle" || state.selectionAgentStatus !== "complete" || state.compositionPhase !== "done" && state.compositionPhase !== "cache-hit" || state.rawTokensPath && state.tokenGenerationStatus !== "complete" || effectiveNoCache) {
|
|
27769
28263
|
return;
|
|
27770
28264
|
}
|
|
27771
28265
|
const sessionId2 = state.extractSessionId;
|
|
@@ -27920,16 +28414,14 @@ If you are using AWS Bedrock, run:
|
|
|
27920
28414
|
};
|
|
27921
28415
|
const advanceAfterCredentialsValidated = async () => {
|
|
27922
28416
|
credentialsReadyRef.current = true;
|
|
27923
|
-
if (!sessionRef.current.extractSessionId) {
|
|
27924
|
-
update({
|
|
27925
|
-
|
|
27926
|
-
errorStep: "start import",
|
|
27927
|
-
errorMessage: "Internal error: the CLI did not hand over an extract session."
|
|
27928
|
-
});
|
|
28417
|
+
if (!sessionRef.current.extractSessionId && state.projectPath) {
|
|
28418
|
+
if (extractPromiseRef.current) update({ step: "extracting" });
|
|
28419
|
+
else startExtract(state.projectPath);
|
|
27929
28420
|
return;
|
|
27930
28421
|
}
|
|
27931
|
-
if (!scopeGateCompletedRef.current) {
|
|
27932
|
-
update({ step: "
|
|
28422
|
+
if (!scopeGateCompletedRef.current && sessionRef.current.extractSessionId) {
|
|
28423
|
+
if (extractPromiseRef.current) update({ step: "extracting" });
|
|
28424
|
+
else update({ step: "scope-gate" });
|
|
27933
28425
|
return;
|
|
27934
28426
|
}
|
|
27935
28427
|
if (shouldSkipFinalReviewAfterCredentials({
|
|
@@ -28313,7 +28805,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28313
28805
|
};
|
|
28314
28806
|
const runPrintFiles = async (extractSessionId, outDir, opts = {}) => {
|
|
28315
28807
|
update({ step: "printing" });
|
|
28316
|
-
const componentsPath =
|
|
28808
|
+
const componentsPath = join20(outDir, "components.json");
|
|
28317
28809
|
try {
|
|
28318
28810
|
const db = openPipelineDb();
|
|
28319
28811
|
let components = [];
|
|
@@ -28326,7 +28818,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28326
28818
|
}
|
|
28327
28819
|
if (!opts.tokenSessionId && opts.tokensPath) tokens = await readTokensFromPath("tokens", opts.tokensPath);
|
|
28328
28820
|
const cdf = buildSavedCDF(components, tokens, { deleteAll: opts.allowEmpty });
|
|
28329
|
-
await
|
|
28821
|
+
await writeFile5(componentsPath, `${JSON.stringify(cdf, null, 2)}
|
|
28330
28822
|
`);
|
|
28331
28823
|
process.stderr.write(
|
|
28332
28824
|
`wrote ${componentsPath} (${components.length} component${components.length === 1 ? "" : "s"}, ${tokens.length} token${tokens.length === 1 ? "" : "s"})
|
|
@@ -28410,6 +28902,23 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28410
28902
|
void runPreview(extractSessionId, tokensPath, state.spaceId, state.environmentId, state.cmaToken, state.host);
|
|
28411
28903
|
}
|
|
28412
28904
|
};
|
|
28905
|
+
const tokenStrategyApplied = useRef9(false);
|
|
28906
|
+
useEffect14(() => {
|
|
28907
|
+
if (!state.rawTokensPath || tokenStrategyApplied.current) return;
|
|
28908
|
+
tokenStrategyApplied.current = true;
|
|
28909
|
+
const strategy = process.env["EDS_IMPORT_TOKENS"];
|
|
28910
|
+
if (strategy === "reuse") {
|
|
28911
|
+
update({
|
|
28912
|
+
tokensPath: join20(state.outDir, "tokens.json"),
|
|
28913
|
+
tokenSessionId: null,
|
|
28914
|
+
tokenGenerationStatus: "complete"
|
|
28915
|
+
});
|
|
28916
|
+
return;
|
|
28917
|
+
}
|
|
28918
|
+
tokenGenerationPromiseRef.current = runAgentAuthCheck("credentials").then(
|
|
28919
|
+
(ok2) => ok2 ? runGenerateTokens(state.rawTokensPath, state.outDir, strategy === "regenerate") : false
|
|
28920
|
+
);
|
|
28921
|
+
}, [state.rawTokensPath]);
|
|
28413
28922
|
const credentialsHandedOff = useRef9(false);
|
|
28414
28923
|
useEffect14(() => {
|
|
28415
28924
|
if (state.step !== "credentials" || credentialsHandedOff.current) return;
|
|
@@ -28420,6 +28929,7 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28420
28929
|
const noQuitSteps = [
|
|
28421
28930
|
"checking-claude-auth",
|
|
28422
28931
|
"validating-credentials",
|
|
28932
|
+
"extracting",
|
|
28423
28933
|
"generating",
|
|
28424
28934
|
"mapping-tokens",
|
|
28425
28935
|
"printing",
|
|
@@ -28429,7 +28939,8 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28429
28939
|
const hints = noQuitSteps.includes(state.step) ? [] : [{ key: "q", label: "quit" }];
|
|
28430
28940
|
const hasTokens = !!state.tokensPath;
|
|
28431
28941
|
const hasTokenStage = hasTokens || !!state.rawTokensPath;
|
|
28432
|
-
const
|
|
28942
|
+
const hasComponents = !state.skipComponents;
|
|
28943
|
+
const totalSteps = 3 + (hasTokenStage ? 1 : 0) + (hasComponents ? 2 : 0) + (state.mapTokensEligible === true ? 1 : 0);
|
|
28433
28944
|
const stepContent = (() => {
|
|
28434
28945
|
switch (state.step) {
|
|
28435
28946
|
case "checking-claude-auth":
|
|
@@ -28442,6 +28953,44 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28442
28953
|
description: `Verifying ${state.agent} is installed and authenticated...`
|
|
28443
28954
|
}
|
|
28444
28955
|
);
|
|
28956
|
+
case "extracting": {
|
|
28957
|
+
const ep = state.extractProgress;
|
|
28958
|
+
const compositionComplete = state.compositionPhase === "done" || state.compositionPhase === "cache-hit";
|
|
28959
|
+
const tokenGenerationComplete = !state.rawTokensPath || state.tokenGenerationStatus === "complete";
|
|
28960
|
+
const extractionTasksComplete = ep !== null && ep.totalFiles > 0 && compositionComplete && state.selectionAgentStatus === "complete" && tokenGenerationComplete && state.existingEntitiesStatus !== "running";
|
|
28961
|
+
if (extractionTasksComplete) return null;
|
|
28962
|
+
let extractDetail;
|
|
28963
|
+
let extractComplete = false;
|
|
28964
|
+
if (ep && ep.totalFiles > 0) {
|
|
28965
|
+
extractDetail = `Scanned ${ep.scanned} file${ep.scanned === 1 ? "" : "s"}`;
|
|
28966
|
+
extractComplete = true;
|
|
28967
|
+
} else if (ep) {
|
|
28968
|
+
extractDetail = `Scanning ${ep.scanned} file${ep.scanned === 1 ? "" : "s"}`;
|
|
28969
|
+
} else {
|
|
28970
|
+
extractDetail = "Scanning files...";
|
|
28971
|
+
}
|
|
28972
|
+
const selectionDetail = state.selectionAgentStatus === "complete" ? "Selection agent complete" : `Filtering component selection via ${state.agent}...`;
|
|
28973
|
+
const compositionDetail = state.compositionPhase === "cache-hit" ? "Composition mapping (cached)" : compositionComplete ? "Composition mapping complete" : state.compositionPhase?.startsWith("agent:") ? `Mapping composition via ${state.compositionPhase.slice("agent:".length)}...` : `Mapping composition via ${state.agent}...`;
|
|
28974
|
+
return /* @__PURE__ */ jsx47(
|
|
28975
|
+
RunningStep,
|
|
28976
|
+
{
|
|
28977
|
+
stepNumber: hasTokenStage ? 2 : 1,
|
|
28978
|
+
totalSteps,
|
|
28979
|
+
title: "Extracting context",
|
|
28980
|
+
description: "Extracting context from your source files.",
|
|
28981
|
+
detail: extractDetail,
|
|
28982
|
+
detailComplete: extractComplete,
|
|
28983
|
+
secondaryDetail: compositionDetail,
|
|
28984
|
+
secondaryComplete: compositionComplete,
|
|
28985
|
+
tertiaryDetail: selectionDetail,
|
|
28986
|
+
tertiaryComplete: state.selectionAgentStatus === "complete",
|
|
28987
|
+
quaternaryDetail: state.existingEntitiesStatus === "running" ? "Fetching existing components and tokens..." : state.existingEntitiesStatus === "complete" ? "Existing components and tokens ready" : state.existingEntitiesStatus === "failed" ? "Existing entities unavailable; continuing without them" : void 0,
|
|
28988
|
+
quaternaryComplete: state.existingEntitiesStatus === "complete" || state.existingEntitiesStatus === "failed",
|
|
28989
|
+
quinaryDetail: state.rawTokensPath ? state.tokenGenerationStatus === "running" ? `Generating token definitions via ${state.agent}...` : state.tokenGenerationStatus === "complete" ? "Token definitions ready" : state.tokenGenerationStatus === "failed" ? "Token definition generation failed" : `Generating token definitions via ${state.agent}...` : void 0,
|
|
28990
|
+
quinaryComplete: state.tokenGenerationStatus === "complete"
|
|
28991
|
+
}
|
|
28992
|
+
);
|
|
28993
|
+
}
|
|
28445
28994
|
case "scope-gate": {
|
|
28446
28995
|
if (!state.extractSessionId) {
|
|
28447
28996
|
return /* @__PURE__ */ jsx47(Box38, { paddingX: 2, paddingY: 1, children: /* @__PURE__ */ jsx47(Text40, { color: PALETTE.error, children: "Error: extract session ID missing \u2014 please re-run." }) });
|
|
@@ -28727,7 +29276,9 @@ ${displayAgent} is mapping your selected components to Contentful's Component De
|
|
|
28727
29276
|
GateStep,
|
|
28728
29277
|
{
|
|
28729
29278
|
successMessage: "Files saved",
|
|
28730
|
-
summary: [
|
|
29279
|
+
summary: [
|
|
29280
|
+
(hasComponents || hasTokens) && state.componentsPath ? `components.json \u2192 ${state.componentsPath}` : null
|
|
29281
|
+
].filter(Boolean).join("\n"),
|
|
28731
29282
|
context: teaser ? `Your files are saved to disk. ${teaser}` : "Your files are saved to disk. Run `experiences import` again when you're ready to push to Contentful.",
|
|
28732
29283
|
continueLabel: "Exit",
|
|
28733
29284
|
showSkip: false,
|
|
@@ -28811,7 +29362,6 @@ var init_WizardApp = __esm({
|
|
|
28811
29362
|
init_CustomPromptBanner();
|
|
28812
29363
|
init_RunningStep();
|
|
28813
29364
|
init_GateStep();
|
|
28814
|
-
init_handoff();
|
|
28815
29365
|
init_WizardPreviewStep();
|
|
28816
29366
|
init_DoneStep();
|
|
28817
29367
|
init_ErrorStep();
|
|
@@ -28834,12 +29384,15 @@ var init_WizardApp = __esm({
|
|
|
28834
29384
|
init_runScopeGate();
|
|
28835
29385
|
init_src();
|
|
28836
29386
|
init_host_utils();
|
|
29387
|
+
init_fetch_and_persist_existing_contentful_entities();
|
|
28837
29388
|
init_wizard_state_transitions();
|
|
28838
29389
|
init_cli_path();
|
|
29390
|
+
init_prompt_overrides();
|
|
29391
|
+
init_run_selection_agent();
|
|
28839
29392
|
init_use_terminal_size();
|
|
28840
29393
|
init_render_with_goodbye();
|
|
28841
29394
|
SAVE_CONFIRMATION_DELAY_MS = 1e3;
|
|
28842
|
-
WIZARD_LOG =
|
|
29395
|
+
WIZARD_LOG = join20(tmpdir(), "experiences-import-wizard.log");
|
|
28843
29396
|
}
|
|
28844
29397
|
});
|
|
28845
29398
|
|
|
@@ -28970,7 +29523,7 @@ var init_agent_definitions = __esm({
|
|
|
28970
29523
|
});
|
|
28971
29524
|
|
|
28972
29525
|
// packages/experience-design-system-cli-legacy/src/setup/lib/shell.ts
|
|
28973
|
-
import { execFile as execFile3, spawn as
|
|
29526
|
+
import { execFile as execFile3, spawn as spawn6 } from "node:child_process";
|
|
28974
29527
|
import { access as access7 } from "node:fs/promises";
|
|
28975
29528
|
import { promisify as promisify2 } from "node:util";
|
|
28976
29529
|
async function binaryExists(name) {
|
|
@@ -28986,7 +29539,7 @@ async function pathExists3(path) {
|
|
|
28986
29539
|
}
|
|
28987
29540
|
function runSpawn(cmd, args, opts = {}) {
|
|
28988
29541
|
return new Promise((resolve22) => {
|
|
28989
|
-
const child =
|
|
29542
|
+
const child = spawn6(cmd, args, {
|
|
28990
29543
|
cwd: opts.cwd,
|
|
28991
29544
|
env: opts.env ?? process.env,
|
|
28992
29545
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -29019,7 +29572,7 @@ var init_shell = __esm({
|
|
|
29019
29572
|
});
|
|
29020
29573
|
|
|
29021
29574
|
// packages/experience-design-system-cli-legacy/src/setup/lib/checks.ts
|
|
29022
|
-
import { join as
|
|
29575
|
+
import { join as join21 } from "node:path";
|
|
29023
29576
|
function checkNodeVersion(nodeVersion = process.versions.node) {
|
|
29024
29577
|
const major = Number.parseInt(nodeVersion.split(".")[0], 10);
|
|
29025
29578
|
return {
|
|
@@ -29033,7 +29586,7 @@ async function detectNodeVersionManagers(homeDir, deps = {
|
|
|
29033
29586
|
binaryExists,
|
|
29034
29587
|
pathExists: pathExists3
|
|
29035
29588
|
}) {
|
|
29036
|
-
const nvmScript =
|
|
29589
|
+
const nvmScript = join21(homeDir, ".nvm", "nvm.sh");
|
|
29037
29590
|
return {
|
|
29038
29591
|
nvm: await deps.binaryExists("nvm") || await deps.pathExists(nvmScript),
|
|
29039
29592
|
fnm: await deps.binaryExists("fnm"),
|
|
@@ -29112,7 +29665,7 @@ var init_report = __esm({
|
|
|
29112
29665
|
|
|
29113
29666
|
// packages/experience-design-system-cli-legacy/src/doctor/checks.ts
|
|
29114
29667
|
import { homedir as homedir2 } from "node:os";
|
|
29115
|
-
import { join as
|
|
29668
|
+
import { join as join22 } from "node:path";
|
|
29116
29669
|
async function reportNode() {
|
|
29117
29670
|
section("Checking Node.js version");
|
|
29118
29671
|
const check = checkNodeVersion();
|
|
@@ -29163,12 +29716,12 @@ async function reportPnpm(pkgRoot) {
|
|
|
29163
29716
|
}
|
|
29164
29717
|
async function reportDependencies(pkgRoot) {
|
|
29165
29718
|
section("Checking dependencies (pnpm install)");
|
|
29166
|
-
if (!await pathExists3(
|
|
29719
|
+
if (!await pathExists3(join22(pkgRoot, "node_modules"))) {
|
|
29167
29720
|
info("node_modules not found \u2014 running pnpm install...");
|
|
29168
29721
|
} else {
|
|
29169
29722
|
info("Running pnpm install to ensure dependencies are up to date...");
|
|
29170
29723
|
}
|
|
29171
|
-
const check = await installDependencies(
|
|
29724
|
+
const check = await installDependencies(join22(pkgRoot, "..", ".."));
|
|
29172
29725
|
if (!check.passed) {
|
|
29173
29726
|
fail("pnpm install failed");
|
|
29174
29727
|
info("");
|
|
@@ -29185,7 +29738,7 @@ async function reportDependencies(pkgRoot) {
|
|
|
29185
29738
|
async function reportBuild(pkgRoot) {
|
|
29186
29739
|
section("Building CLI");
|
|
29187
29740
|
info("Running pnpm build...");
|
|
29188
|
-
const check = await buildCli(
|
|
29741
|
+
const check = await buildCli(join22(pkgRoot, "..", ".."));
|
|
29189
29742
|
if (!check.passed) {
|
|
29190
29743
|
fail("Build failed");
|
|
29191
29744
|
info("");
|
|
@@ -30404,9 +30957,9 @@ var init_SetupScreen = __esm({
|
|
|
30404
30957
|
|
|
30405
30958
|
// packages/experience-design-system-cli-legacy/src/setup/command.ts
|
|
30406
30959
|
import { readFileSync as readFileSync9 } from "node:fs";
|
|
30407
|
-
import { join as
|
|
30960
|
+
import { join as join23 } from "node:path";
|
|
30408
30961
|
function getCliVersion() {
|
|
30409
|
-
const pkg4 = JSON.parse(readFileSync9(
|
|
30962
|
+
const pkg4 = JSON.parse(readFileSync9(join23(findPkgRoot(), "package.json"), "utf8"));
|
|
30410
30963
|
return pkg4.version;
|
|
30411
30964
|
}
|
|
30412
30965
|
async function runSetup(opts) {
|
|
@@ -30418,7 +30971,7 @@ async function runSetup(opts) {
|
|
|
30418
30971
|
const { renderWithGoodbye: renderWithGoodbye2 } = await Promise.resolve().then(() => (init_render_with_goodbye(), render_with_goodbye_exports));
|
|
30419
30972
|
const { createElement: createElement6 } = await import("react");
|
|
30420
30973
|
const { SetupScreen: SetupScreen2 } = await Promise.resolve().then(() => (init_SetupScreen(), SetupScreen_exports));
|
|
30421
|
-
const repoRoot =
|
|
30974
|
+
const repoRoot = join23(findPkgRoot(), "..", "..");
|
|
30422
30975
|
const completion = { outcome: null };
|
|
30423
30976
|
let unmountInk = null;
|
|
30424
30977
|
const { waitUntilExit, unmount } = renderWithGoodbye2(
|
|
@@ -30620,14 +31173,14 @@ var init_apply_mapping = __esm({
|
|
|
30620
31173
|
|
|
30621
31174
|
// packages/experience-design-system-cli-legacy/src/analyze/composition/prompt-loader.ts
|
|
30622
31175
|
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "node:fs";
|
|
30623
|
-
import { dirname as dirname18, join as
|
|
31176
|
+
import { dirname as dirname18, join as join24, resolve as resolve19 } from "node:path";
|
|
30624
31177
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
30625
31178
|
function resolvePromptPath(fileName) {
|
|
30626
31179
|
const thisDir = dirname18(fileURLToPath3(import.meta.url));
|
|
30627
31180
|
let dir = thisDir;
|
|
30628
31181
|
for (; ; ) {
|
|
30629
|
-
const candidate =
|
|
30630
|
-
if (existsSync10(candidate)) return
|
|
31182
|
+
const candidate = join24(dir, "prompts");
|
|
31183
|
+
if (existsSync10(candidate)) return join24(candidate, fileName);
|
|
30631
31184
|
const parent = resolve19(dir, "..");
|
|
30632
31185
|
if (parent === dir) {
|
|
30633
31186
|
throw new Error(
|
|
@@ -30895,7 +31448,7 @@ var init_manifest_doc_evidence = __esm({
|
|
|
30895
31448
|
|
|
30896
31449
|
// packages/experience-design-system-cli-legacy/src/analyze/extract-command.ts
|
|
30897
31450
|
import { mkdir as mkdir5, readdir as readdir3, readFile as readFile18, stat as stat5 } from "node:fs/promises";
|
|
30898
|
-
import { isAbsolute as isAbsolute2, join as
|
|
31451
|
+
import { isAbsolute as isAbsolute2, join as join25, relative as relative2, resolve as resolve20 } from "node:path";
|
|
30899
31452
|
function resolveExtractNoCache(opts) {
|
|
30900
31453
|
return opts.noCache === true || opts.cache === false;
|
|
30901
31454
|
}
|
|
@@ -30928,7 +31481,7 @@ async function collectSourceFiles(directory, onProgress) {
|
|
|
30928
31481
|
const entries = await readdir3(currentDirectory, { withFileTypes: true });
|
|
30929
31482
|
const subdirs = [];
|
|
30930
31483
|
for (const entry of entries) {
|
|
30931
|
-
const fullPath =
|
|
31484
|
+
const fullPath = join25(currentDirectory, entry.name);
|
|
30932
31485
|
if (entry.isDirectory()) {
|
|
30933
31486
|
if (!IGNORED_DIRECTORY_NAMES.has(entry.name)) {
|
|
30934
31487
|
subdirs.push(fullPath);
|
|
@@ -31012,7 +31565,7 @@ function registerInternalExtractCommand(program) {
|
|
|
31012
31565
|
}
|
|
31013
31566
|
}
|
|
31014
31567
|
const projectRoot = resolve20(opts.project);
|
|
31015
|
-
const outDir =
|
|
31568
|
+
const outDir = join25(projectRoot, ".contentful");
|
|
31016
31569
|
let sourceDirectory;
|
|
31017
31570
|
if (opts.dir !== void 0) {
|
|
31018
31571
|
sourceDirectory = resolveFromProjectRoot(projectRoot, opts.dir);
|
|
@@ -31375,9 +31928,9 @@ __export(program_exports, {
|
|
|
31375
31928
|
resolveBedrockFromAncestors: () => resolveBedrockFromAncestors,
|
|
31376
31929
|
runBuild: () => runBuild
|
|
31377
31930
|
});
|
|
31378
|
-
import { spawn as
|
|
31931
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
31379
31932
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
31380
|
-
import { dirname as dirname20, join as
|
|
31933
|
+
import { dirname as dirname20, join as join26, resolve as resolve21 } from "node:path";
|
|
31381
31934
|
import { readFileSync as readFileSync11 } from "node:fs";
|
|
31382
31935
|
import { Command } from "commander";
|
|
31383
31936
|
async function runBuild(opts) {
|
|
@@ -31410,7 +31963,7 @@ function registerBuildCommand(program) {
|
|
|
31410
31963
|
const pkgRoot = resolve21(dirname20(fileURLToPath4(import.meta.url)), "..", "..");
|
|
31411
31964
|
process.stderr.write("\u2699 Building from source...\n");
|
|
31412
31965
|
const { exitCode } = await runBuild({
|
|
31413
|
-
spawnFn: () =>
|
|
31966
|
+
spawnFn: () => spawn7("pnpm", ["build"], { cwd: pkgRoot, stdio: "inherit" }),
|
|
31414
31967
|
stderrWrite: (s) => process.stderr.write(s)
|
|
31415
31968
|
});
|
|
31416
31969
|
process.exit(exitCode);
|
|
@@ -31477,7 +32030,7 @@ var init_program = __esm({
|
|
|
31477
32030
|
init_analytics();
|
|
31478
32031
|
init_credentials_store();
|
|
31479
32032
|
init_cli_path();
|
|
31480
|
-
pkg3 = JSON.parse(readFileSync11(
|
|
32033
|
+
pkg3 = JSON.parse(readFileSync11(join26(findPkgRoot(), "package.json"), "utf8"));
|
|
31481
32034
|
}
|
|
31482
32035
|
});
|
|
31483
32036
|
|