@contentful/experience-design-system-cli 2.23.2-dev-build-fb9eedf.0 → 2.23.2-dev-build-753ceef.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/README.md +24 -2
- package/dist/package.json +2 -1
- package/dist/src/analytics/apply.d.ts +6 -0
- package/dist/src/analytics/apply.js +30 -0
- package/dist/src/analytics/client.d.ts +7 -0
- package/dist/src/analytics/client.js +68 -0
- package/dist/src/analytics/constants.d.ts +4 -0
- package/dist/src/analytics/constants.js +4 -0
- package/dist/src/analytics/env.d.ts +4 -0
- package/dist/src/analytics/env.js +14 -0
- package/dist/src/analytics/exit.d.ts +5 -0
- package/dist/src/analytics/exit.js +24 -0
- package/dist/src/analytics/index.d.ts +10 -0
- package/dist/src/analytics/index.js +9 -0
- package/dist/src/analytics/normalize.d.ts +3 -0
- package/dist/src/analytics/normalize.js +18 -0
- package/dist/src/analytics/os.d.ts +2 -0
- package/dist/src/analytics/os.js +13 -0
- package/dist/src/analytics/session.d.ts +3 -0
- package/dist/src/analytics/session.js +15 -0
- package/dist/src/analytics/tracker.d.ts +17 -0
- package/dist/src/analytics/tracker.js +126 -0
- package/dist/src/analytics/types.d.ts +28 -0
- package/dist/src/analytics/types.js +1 -0
- package/dist/src/analyze/command.js +8 -2
- package/dist/src/analyze/select/command.js +13 -9
- package/dist/src/analyze/select/tui/App.js +1 -4
- package/dist/src/analyze/select-agent/command.js +14 -11
- package/dist/src/apply/api-client.d.ts +5 -5
- package/dist/src/apply/api-client.js +18 -8
- package/dist/src/apply/command.d.ts +1 -1
- package/dist/src/apply/command.js +81 -77
- package/dist/src/apply/preview-utils.d.ts +1 -5
- package/dist/src/apply/preview-utils.js +1 -5
- package/dist/src/apply/tui/ServerApplyView.d.ts +3 -6
- package/dist/src/apply/tui/ServerApplyView.js +6 -15
- package/dist/src/apply/tui/ServerPreviewView.d.ts +1 -2
- package/dist/src/apply/tui/ServerPreviewView.js +3 -3
- package/dist/src/generate/command.js +15 -9
- package/dist/src/generate/edit/command.js +1 -0
- package/dist/src/import/command.js +1 -6
- package/dist/src/import/orchestrator.d.ts +0 -1
- package/dist/src/import/orchestrator.js +18 -14
- package/dist/src/import/tui/WizardApp.d.ts +1 -2
- package/dist/src/import/tui/WizardApp.js +8 -8
- package/dist/src/import/tui/final-review-host.d.ts +1 -2
- package/dist/src/import/tui/final-review-host.js +2 -2
- package/dist/src/import/tui/runLivePreview.d.ts +0 -3
- package/dist/src/import/tui/runLivePreview.js +1 -4
- package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +1 -2
- package/dist/src/import/tui/steps/GenerateReviewStep.js +3 -3
- package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +2 -6
- package/dist/src/import/tui/steps/WizardPreviewStep.js +3 -12
- package/dist/src/import/tui/useFinalizePreview.d.ts +0 -2
- package/dist/src/import/tui/useFinalizePreview.js +0 -0
- package/dist/src/import/tui/useLivePreview.d.ts +0 -2
- package/dist/src/import/tui/useLivePreview.js +0 -1
- package/dist/src/index.js +6 -1
- package/dist/src/lib/command-options.d.ts +0 -1
- package/dist/src/lib/command-options.js +0 -3
- package/dist/src/print/command.js +16 -13
- package/dist/src/program.js +8 -1
- package/dist/src/runs/modify-launcher.d.ts +0 -2
- package/dist/src/runs/modify-launcher.js +0 -2
- package/dist/src/runs/push-helpers.d.ts +0 -1
- package/dist/src/runs/push-helpers.js +0 -3
- package/dist/src/runs/replay-helpers.d.ts +0 -4
- package/dist/src/runs/replay-helpers.js +0 -3
- package/package.json +6 -5
|
@@ -14,6 +14,7 @@ import { hashPromptForSkill } from '../session/cache-keys.js';
|
|
|
14
14
|
import { getRefineArtifactsRoot, getRefineSessionPaths } from '../analyze/select/persistence.js';
|
|
15
15
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
16
16
|
import { addAgentModelOptions } from '../lib/agent-model-options.js';
|
|
17
|
+
import { bindAnalyticsSessionId, exitWithAnalytics } from '../analytics/index.js';
|
|
17
18
|
const execFileAsync = promisify(execFile);
|
|
18
19
|
const DEFAULT_TIMEOUT_MS = Number(process.env.EDS_AGENT_TIMEOUT_MS ?? 3 * 60 * 1000);
|
|
19
20
|
const DEFAULT_COMPONENT_CONCURRENCY = 10;
|
|
@@ -23,7 +24,8 @@ const invoker = createLocalCliAgentInvoker({
|
|
|
23
24
|
});
|
|
24
25
|
function die(message) {
|
|
25
26
|
process.stderr.write(`${message}\n`);
|
|
26
|
-
|
|
27
|
+
void exitWithAnalytics(1);
|
|
28
|
+
throw new Error('exit');
|
|
27
29
|
}
|
|
28
30
|
async function pathExists(p) {
|
|
29
31
|
return access(p)
|
|
@@ -276,7 +278,8 @@ function resolveSessionId(sessionFlag) {
|
|
|
276
278
|
.get();
|
|
277
279
|
if (!row) {
|
|
278
280
|
process.stderr.write('Error: no completed analyze extract session found. Run analyze extract first, or pass --session <id>.\n');
|
|
279
|
-
|
|
281
|
+
void exitWithAnalytics(1);
|
|
282
|
+
throw new Error('exit');
|
|
280
283
|
}
|
|
281
284
|
return row.id;
|
|
282
285
|
}
|
|
@@ -340,6 +343,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
340
343
|
let allComponents;
|
|
341
344
|
if (skill === 'components') {
|
|
342
345
|
sessionId = resolveSessionId(opts.session);
|
|
346
|
+
await bindAnalyticsSessionId(sessionId);
|
|
343
347
|
const acceptedNames = await loadAcceptedNames(sessionId);
|
|
344
348
|
const db = openPipelineDb();
|
|
345
349
|
try {
|
|
@@ -396,7 +400,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
396
400
|
skillPathOverride: generatePromptPath,
|
|
397
401
|
});
|
|
398
402
|
process.stdout.write(prompt + '\n');
|
|
399
|
-
|
|
403
|
+
await exitWithAnalytics(0);
|
|
400
404
|
}
|
|
401
405
|
const binary = resolveBinary(agent);
|
|
402
406
|
if (!(await assertBinaryInPath(binary))) {
|
|
@@ -405,7 +409,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
405
409
|
skill,
|
|
406
410
|
sessionId: sessionId ?? '',
|
|
407
411
|
});
|
|
408
|
-
|
|
412
|
+
await exitWithAnalytics(1);
|
|
409
413
|
}
|
|
410
414
|
if (skill === 'components' && allComponents && sessionId) {
|
|
411
415
|
const db = openPipelineDb();
|
|
@@ -471,6 +475,8 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
471
475
|
resolvedSessionId = newId;
|
|
472
476
|
}
|
|
473
477
|
}
|
|
478
|
+
sessionId = resolvedSessionId;
|
|
479
|
+
await bindAnalyticsSessionId(resolvedSessionId);
|
|
474
480
|
const tokenPromptHash = await hashPromptForSkill('tokens');
|
|
475
481
|
// Check cache before invoking agent
|
|
476
482
|
if (!noCache) {
|
|
@@ -483,12 +489,12 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
483
489
|
// Skip agent invocation — jump to view
|
|
484
490
|
const viewResult = { skill, agent, sessionId: sessionId ?? '' };
|
|
485
491
|
if (process.stdout.isTTY) {
|
|
486
|
-
const { waitUntilExit } = render(createElement(GenerateView, { result: viewResult, onExit: () =>
|
|
492
|
+
const { waitUntilExit } = render(createElement(GenerateView, { result: viewResult, onExit: () => void exitWithAnalytics(0) }));
|
|
487
493
|
await waitUntilExit();
|
|
488
494
|
}
|
|
489
495
|
else {
|
|
490
496
|
process.stdout.write(`generate complete\nskill: ${skill}\nagent: ${agent}\nsession=${sessionId ?? ''}\n`);
|
|
491
|
-
|
|
497
|
+
await exitWithAnalytics(0);
|
|
492
498
|
}
|
|
493
499
|
return;
|
|
494
500
|
}
|
|
@@ -523,7 +529,7 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
523
529
|
process.stderr.write(`Error: agent produced no set_token calls.\n` +
|
|
524
530
|
`Run with --dry-run to inspect the prompt.\n\n` +
|
|
525
531
|
`Agent output:\n${result.stdout}\n`);
|
|
526
|
-
|
|
532
|
+
await exitWithAnalytics(1);
|
|
527
533
|
}
|
|
528
534
|
if (tokenWarnings.length > 0) {
|
|
529
535
|
process.stderr.write(`Warnings:\n${tokenWarnings.map((w) => ` ${w}`).join('\n')}\n`);
|
|
@@ -548,13 +554,13 @@ async function runGenerateSkill(skill, opts, verbose = false) {
|
|
|
548
554
|
if (process.stdout.isTTY) {
|
|
549
555
|
const { waitUntilExit } = render(createElement(GenerateView, {
|
|
550
556
|
result: viewResult,
|
|
551
|
-
onExit: () =>
|
|
557
|
+
onExit: () => void exitWithAnalytics(0),
|
|
552
558
|
}));
|
|
553
559
|
await waitUntilExit();
|
|
554
560
|
}
|
|
555
561
|
else {
|
|
556
562
|
process.stdout.write(`generate complete\nskill: ${skill}\nagent: ${agent}\nsession=${sessionId ?? ''}\n`);
|
|
557
|
-
|
|
563
|
+
await exitWithAnalytics(0);
|
|
558
564
|
}
|
|
559
565
|
}
|
|
560
566
|
function addAgentFlags(cmd) {
|
|
@@ -99,6 +99,7 @@ async function runNonInteractive(opts, skill) {
|
|
|
99
99
|
process.stderr.write(`Accepted: ${accepted.length} Rejected: ${rejected.length}\n`);
|
|
100
100
|
}
|
|
101
101
|
export function registerGenerateEditCommand(parent, skill) {
|
|
102
|
+
// TODO(analytics): bindAnalyticsSessionId when generate edit ships — tracked in schema as generate_edit.
|
|
102
103
|
parent
|
|
103
104
|
.command('edit')
|
|
104
105
|
.description(`Review and correct generate ${skill} output before pushing`)
|
|
@@ -4,7 +4,7 @@ import { resolveAutoFilter } from './auto-filter-resolve.js';
|
|
|
4
4
|
import { resolveAgent, resolveModel } from './agent-model-resolve.js';
|
|
5
5
|
import { addAgentModelOptions } from '../lib/agent-model-options.js';
|
|
6
6
|
import { resolveCompositionMode } from '../lib/composition-mode.js';
|
|
7
|
-
import {
|
|
7
|
+
import { addCompositionOptions } from '../lib/command-options.js';
|
|
8
8
|
import { isConflictMode } from '../runs/save-path-resolver.js';
|
|
9
9
|
import { readExperiencesCredentials } from '../credentials-store.js';
|
|
10
10
|
import { DEFAULT_CONFIGURED_HOST, toConfiguredHost } from '../host-utils.js';
|
|
@@ -46,7 +46,6 @@ export function registerImportCommand(program) {
|
|
|
46
46
|
.option('--print-prompt', 'Print the generate components prompt without invoking the agent. Replaces the legacy --dry-run prompt-print behaviour on this command.')
|
|
47
47
|
.option('--auto-accept-scope', 'Accept all extracted components without prompting (for scripted/non-TTY callers)');
|
|
48
48
|
addCompositionOptions(cmd);
|
|
49
|
-
addAllowDeletionsOption(cmd);
|
|
50
49
|
cmd
|
|
51
50
|
.option('--composition-map <path>', 'Consume a hand-authored parent→children interchange map (implies --composite)')
|
|
52
51
|
.option('--composition-agent', 'Opt into agentic mapping resolution when deterministic sources find no groups (implies --composite)')
|
|
@@ -137,7 +136,6 @@ export function registerImportCommand(program) {
|
|
|
137
136
|
...(opts.host ? { host: opts.host } : {}),
|
|
138
137
|
interactive: interactiveTerminalSupported,
|
|
139
138
|
...(opts.force ? { force: true } : {}),
|
|
140
|
-
...(opts.allowDeletions ? { allowDeletions: true } : {}),
|
|
141
139
|
});
|
|
142
140
|
return;
|
|
143
141
|
}
|
|
@@ -168,7 +166,6 @@ export function registerImportCommand(program) {
|
|
|
168
166
|
...(opts.saveAsNew ? { saveAsNew: true } : {}),
|
|
169
167
|
...(opts.outDir ? { outDir: opts.outDir } : {}),
|
|
170
168
|
...(opts.force ? { force: true } : {}),
|
|
171
|
-
...(opts.allowDeletions ? { allowDeletions: true } : {}),
|
|
172
169
|
});
|
|
173
170
|
return;
|
|
174
171
|
}
|
|
@@ -300,7 +297,6 @@ export function registerImportCommand(program) {
|
|
|
300
297
|
selectPromptPath: opts.selectPromptPath ?? creds.selectPromptPath,
|
|
301
298
|
generatePromptPath: opts.generatePromptPath ?? creds.generatePromptPath,
|
|
302
299
|
...(opts.rawTokens ? { initialRawTokensPath: resolve(opts.rawTokens) } : {}),
|
|
303
|
-
allowDeletions: opts.allowDeletions === true,
|
|
304
300
|
...pickerProps,
|
|
305
301
|
}));
|
|
306
302
|
unmountInk = unmount;
|
|
@@ -361,7 +357,6 @@ export function registerImportCommand(program) {
|
|
|
361
357
|
dryRun: dryRunForward,
|
|
362
358
|
selectPromptPath: opts.selectPromptPath,
|
|
363
359
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
364
|
-
allowDeletions: opts.allowDeletions ?? false,
|
|
365
360
|
compositionMode: headlessCompositionMode,
|
|
366
361
|
...(opts.compositionMap ? { compositionMap: opts.compositionMap } : {}),
|
|
367
362
|
...(opts.compositionAgent ? { compositionAgent: true } : {}),
|
|
@@ -26,7 +26,6 @@ export interface PipelineOptions {
|
|
|
26
26
|
selectPromptPath?: string;
|
|
27
27
|
/** When true, auto-reject cycle participants and retry push instead of surfacing an error. */
|
|
28
28
|
autoRejectCycles?: boolean;
|
|
29
|
-
allowDeletions?: boolean;
|
|
30
29
|
compositionMode?: CompositionMode;
|
|
31
30
|
compositionMap?: string;
|
|
32
31
|
compositionAgent?: boolean;
|
|
@@ -6,17 +6,19 @@ import { openPipelineDb, getOrCreateSession, createStep, updateStep, findLatestS
|
|
|
6
6
|
import { detectSlotCycles, formatSlotCycleReport } from '../apply/command.js';
|
|
7
7
|
import { PREVIEW_ERROR_PREFIX, VALIDATION_FAILED_CODE, parsePreviewValidationErrors } from '../apply/api-client.js';
|
|
8
8
|
import { buildPostPushUrl } from '../lib/contentful-urls.js';
|
|
9
|
-
import { getDebugLogger
|
|
9
|
+
import { getDebugLogger } from '../lib/debug-logger.js';
|
|
10
|
+
import { bindAnalyticsSession, emitSessionStarted } from '../analytics/index.js';
|
|
11
|
+
import { pipelineSubprocessEnv } from '../analytics/env.js';
|
|
10
12
|
function findCliPath() {
|
|
11
13
|
return join(fileURLToPath(import.meta.url), '..', '..', '..', '..', 'bin', 'cli.js');
|
|
12
14
|
}
|
|
13
|
-
async function runStep(args, cliPath, env = {}, streamStderr = false) {
|
|
15
|
+
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
14
16
|
const debug = getDebugLogger();
|
|
15
17
|
const startedAt = Date.now();
|
|
16
18
|
debug.event('import', 'subprocess.spawn', { cliPath, args });
|
|
17
19
|
return new Promise((res) => {
|
|
18
20
|
const child = execFile('node', [cliPath, ...args], {
|
|
19
|
-
env:
|
|
21
|
+
env: pipelineSubprocessEnv({ ...process.env, ...env }, analyticsSessionId),
|
|
20
22
|
});
|
|
21
23
|
let stdout = '';
|
|
22
24
|
let stderr = '';
|
|
@@ -108,6 +110,10 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
108
110
|
inputPath: projectRoot,
|
|
109
111
|
outDir,
|
|
110
112
|
});
|
|
113
|
+
await bindAnalyticsSession(sessionId, {
|
|
114
|
+
...(opts.spaceId ? { space_key: opts.spaceId, environment_key: opts.environmentId } : {}),
|
|
115
|
+
});
|
|
116
|
+
await emitSessionStarted('import');
|
|
111
117
|
progressWriter(`Experience Design System CLI — Pipeline Import`);
|
|
112
118
|
progressWriter(`Project: ${projectRoot}`);
|
|
113
119
|
progressWriter(`Output: ${outDir}`);
|
|
@@ -159,7 +165,7 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
159
165
|
if (opts.agent)
|
|
160
166
|
analyzeArgs.push('--agent', opts.agent);
|
|
161
167
|
}
|
|
162
|
-
const r = await runStep(analyzeArgs, cliPath);
|
|
168
|
+
const r = await runStep(analyzeArgs, cliPath, sessionId);
|
|
163
169
|
const durationMs = Date.now() - t0;
|
|
164
170
|
if (r.exitCode !== 0) {
|
|
165
171
|
if (r.stderr)
|
|
@@ -231,7 +237,7 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
231
237
|
editArgs.push('--select-all');
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
|
-
const rEdit = await runStep(editArgs, cliPath, { FORCE_COLOR: '1' }, useAgentSelect);
|
|
240
|
+
const rEdit = await runStep(editArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, useAgentSelect);
|
|
235
241
|
const editDurationMs = Date.now() - t0Edit;
|
|
236
242
|
if (rEdit.exitCode !== 0) {
|
|
237
243
|
if (rEdit.stderr && !useAgentSelect)
|
|
@@ -292,7 +298,7 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
292
298
|
extractSession: extractSessionId ?? '',
|
|
293
299
|
});
|
|
294
300
|
const t0 = Date.now();
|
|
295
|
-
const r = await runStep(generateArgs, cliPath, { FORCE_COLOR: '1' }, true);
|
|
301
|
+
const r = await runStep(generateArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
296
302
|
const durationMs = Date.now() - t0;
|
|
297
303
|
if (r.exitCode !== 0) {
|
|
298
304
|
updateStep(db, stepId, 'failed', {}, r.stderr);
|
|
@@ -355,7 +361,7 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
355
361
|
out: componentsPath,
|
|
356
362
|
});
|
|
357
363
|
const t0 = Date.now();
|
|
358
|
-
const r = await runStep(printArgs, cliPath);
|
|
364
|
+
const r = await runStep(printArgs, cliPath, sessionId);
|
|
359
365
|
const durationMs = Date.now() - t0;
|
|
360
366
|
if (r.exitCode !== 0) {
|
|
361
367
|
if (r.stderr)
|
|
@@ -418,14 +424,12 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
418
424
|
pushArgs.push('--host', opts.host);
|
|
419
425
|
if (opts.verbose)
|
|
420
426
|
pushArgs.push('--verbose');
|
|
421
|
-
if (opts.allowDeletions)
|
|
422
|
-
pushArgs.push('--allow-deletions');
|
|
423
427
|
pushArgs.push('--yes');
|
|
424
428
|
const pushStepId = createStep(db, sessionId, 'apply push', {
|
|
425
429
|
components: componentsPath,
|
|
426
430
|
});
|
|
427
431
|
const t0 = Date.now();
|
|
428
|
-
let r = await runStep(pushArgs, cliPath, { FORCE_COLOR: '1' }, true);
|
|
432
|
+
let r = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
429
433
|
const excludedByRetry = [];
|
|
430
434
|
let validationRetryCount = 0;
|
|
431
435
|
while (validationRetryCount < MAX_VALIDATION_RETRIES && isPreviewValidationError(r) && extractSessionId) {
|
|
@@ -442,10 +446,10 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
442
446
|
'--exclude-components',
|
|
443
447
|
offenders.join(','),
|
|
444
448
|
];
|
|
445
|
-
const rejectResult = await runStep(rejectArgs, cliPath);
|
|
449
|
+
const rejectResult = await runStep(rejectArgs, cliPath, sessionId);
|
|
446
450
|
if (rejectResult.exitCode !== 0)
|
|
447
451
|
break;
|
|
448
|
-
r = await runStep(pushArgs, cliPath, { FORCE_COLOR: '1' }, true);
|
|
452
|
+
r = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
449
453
|
validationRetryCount++;
|
|
450
454
|
}
|
|
451
455
|
const durationMs = Date.now() - t0;
|
|
@@ -480,10 +484,10 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
480
484
|
'--exclude-components',
|
|
481
485
|
cycleNames.join(','),
|
|
482
486
|
];
|
|
483
|
-
const rejectResult = await runStep(rejectArgs, cliPath);
|
|
487
|
+
const rejectResult = await runStep(rejectArgs, cliPath, sessionId);
|
|
484
488
|
if (rejectResult.exitCode === 0) {
|
|
485
489
|
const retryT0 = Date.now();
|
|
486
|
-
const retryR = await runStep(pushArgs, cliPath, { FORCE_COLOR: '1' }, true);
|
|
490
|
+
const retryR = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
487
491
|
const retryDurationMs = Date.now() - t0 + (Date.now() - retryT0);
|
|
488
492
|
if (isSlotCycleError(retryR)) {
|
|
489
493
|
const retryReport = extractCycleReport(retryR.stderr);
|
|
@@ -66,6 +66,5 @@ export type WizardAppProps = {
|
|
|
66
66
|
initialRawTokensPath?: string;
|
|
67
67
|
initialRuns?: RunRecord[];
|
|
68
68
|
onRunPicked?: (selection: RunPickerSelection) => void;
|
|
69
|
-
allowDeletions?: boolean;
|
|
70
69
|
};
|
|
71
|
-
export declare function WizardApp({ initialSpaceId, initialEnvironmentId, initialCmaToken, initialHost, initialAgent, initialModel, initialProjectPath, host, autoAcceptScope, autoRejectCycles, compositionMode, compositionMap, compositionAgent, compositionAgentMode, compositionRefresh, generateMap, promptOverrides, noCache, autoFilter, livePreview, noPush, noSave, outDirOverride, onConflictMode, selectPromptPath, generatePromptPath, seedExtractSessionId, seedGenerateSessionId, seedTokenSessionId, seedTokensPath, initialStep, initialRawTokensPath, initialRuns, onRunPicked,
|
|
70
|
+
export declare function WizardApp({ initialSpaceId, initialEnvironmentId, initialCmaToken, initialHost, initialAgent, initialModel, initialProjectPath, host, autoAcceptScope, autoRejectCycles, compositionMode, compositionMap, compositionAgent, compositionAgentMode, compositionRefresh, generateMap, promptOverrides, noCache, autoFilter, livePreview, noPush, noSave, outDirOverride, onConflictMode, selectPromptPath, generatePromptPath, seedExtractSessionId, seedGenerateSessionId, seedTokenSessionId, seedTokensPath, initialStep, initialRawTokensPath, initialRuns, onRunPicked, }?: WizardAppProps): React.ReactElement;
|
|
@@ -138,7 +138,7 @@ function logStep(entry) {
|
|
|
138
138
|
appendFileSync(WIZARD_LOG, line);
|
|
139
139
|
getDebugLogger().event('wizard', 'step', entry);
|
|
140
140
|
}
|
|
141
|
-
export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master', initialCmaToken = '', initialHost, initialAgent, initialModel, initialProjectPath, host, autoAcceptScope = false, autoRejectCycles = false, compositionMode = 'atomic', compositionMap, compositionAgent = false, compositionAgentMode, compositionRefresh = false, generateMap, promptOverrides, noCache = false, autoFilter = true, livePreview = true, noPush = false, noSave = false, outDirOverride, onConflictMode, selectPromptPath, generatePromptPath, seedExtractSessionId, seedGenerateSessionId, seedTokenSessionId, seedTokensPath, initialStep, initialRawTokensPath, initialRuns, onRunPicked,
|
|
141
|
+
export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master', initialCmaToken = '', initialHost, initialAgent, initialModel, initialProjectPath, host, autoAcceptScope = false, autoRejectCycles = false, compositionMode = 'atomic', compositionMap, compositionAgent = false, compositionAgentMode, compositionRefresh = false, generateMap, promptOverrides, noCache = false, autoFilter = true, livePreview = true, noPush = false, noSave = false, outDirOverride, onConflictMode, selectPromptPath, generatePromptPath, seedExtractSessionId, seedGenerateSessionId, seedTokenSessionId, seedTokensPath, initialStep, initialRawTokensPath, initialRuns, onRunPicked, } = {}) {
|
|
142
142
|
const defaultConfiguredHost = toConfiguredHost(host || process.env['EDS_HOST']) ?? DEFAULT_CONFIGURED_HOST;
|
|
143
143
|
const resolveWizardHost = (hostValue) => hostValue || defaultConfiguredHost;
|
|
144
144
|
const { stdout } = useStdout();
|
|
@@ -830,7 +830,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
830
830
|
tokens = await readTokensFromPath('tokens', tokensPath);
|
|
831
831
|
}
|
|
832
832
|
let manifest = buildManifest(components, tokens, { deleteAllComponents: allowEmptyDeleteAllRef.current });
|
|
833
|
-
let preview = await client.previewImport(manifest
|
|
833
|
+
let preview = await client.previewImport(manifest);
|
|
834
834
|
if (extractSessionId) {
|
|
835
835
|
let needsRepreview = false;
|
|
836
836
|
const db = openPipelineDb();
|
|
@@ -852,7 +852,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
852
852
|
if (needsRepreview) {
|
|
853
853
|
components = loadCDFComponents(db, extractSessionId);
|
|
854
854
|
manifest = buildManifest(components, tokens, { deleteAllComponents: allowEmptyDeleteAllRef.current });
|
|
855
|
-
preview = await client.previewImport(manifest
|
|
855
|
+
preview = await client.previewImport(manifest);
|
|
856
856
|
}
|
|
857
857
|
}
|
|
858
858
|
finally {
|
|
@@ -946,7 +946,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
946
946
|
});
|
|
947
947
|
}
|
|
948
948
|
};
|
|
949
|
-
const runPush = async (manifest, spaceId, environmentId, cmaToken, host, acknowledgeBreakingChanges,
|
|
949
|
+
const runPush = async (manifest, spaceId, environmentId, cmaToken, host, acknowledgeBreakingChanges, preview) => {
|
|
950
950
|
if (shouldRefusePush(state)) {
|
|
951
951
|
update(buildSkippedPushTransition());
|
|
952
952
|
return;
|
|
@@ -986,7 +986,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
986
986
|
environmentId,
|
|
987
987
|
host: resolvedHost,
|
|
988
988
|
});
|
|
989
|
-
let operation = await client.applyImport(manifest,
|
|
989
|
+
let operation = await client.applyImport(manifest, acknowledgeBreakingChanges);
|
|
990
990
|
try {
|
|
991
991
|
logStep({
|
|
992
992
|
applyResponse: {
|
|
@@ -1437,7 +1437,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
1437
1437
|
return (_jsx(RunningStep, { stepNumber: stepNum, totalSteps: totalSteps, title: "Generating definitions", description: `${formatAcceptanceSummary({ accepted: state.acceptedCount, autoRejected: state.autoRejectedCount })} ${state.agent} is mapping your TypeScript types to Contentful's CDF format.${hasTokens ? ' Using your design tokens for prop resolution.' : ''}`, detail: progressDetail }));
|
|
1438
1438
|
}
|
|
1439
1439
|
case 'final-review': {
|
|
1440
|
-
return (_jsx(FinalReviewHost, { extractSessionId: state.extractSessionId, generatedCount: state.generatedCount, autoAccept: autoAcceptScope, compositionMode: compositionMode, livePreview: livePreview, spaceId: state.spaceId, environmentId: state.environmentId, cmaToken: state.cmaToken, host: state.host, tokensPath: state.tokensPath, initialFinalizeError: state.finalizeErrorBanner,
|
|
1440
|
+
return (_jsx(FinalReviewHost, { extractSessionId: state.extractSessionId, generatedCount: state.generatedCount, autoAccept: autoAcceptScope, compositionMode: compositionMode, livePreview: livePreview, spaceId: state.spaceId, environmentId: state.environmentId, cmaToken: state.cmaToken, host: state.host, tokensPath: state.tokensPath, initialFinalizeError: state.finalizeErrorBanner, onFinalize: (accepted, rejected, unresolved) => {
|
|
1441
1441
|
process.stderr.write(`Accepted: ${accepted} Rejected: ${rejected} Unresolved: ${unresolved}\n`);
|
|
1442
1442
|
let acceptedCount = accepted;
|
|
1443
1443
|
const detectAcceptedCycles = () => {
|
|
@@ -1605,8 +1605,8 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
1605
1605
|
// present-but-empty (only $schema), so editing would dead-end on the
|
|
1606
1606
|
// "No generated definitions found" screen.
|
|
1607
1607
|
const editableComponentCount = Object.keys(state.manifest?.componentsManifest ?? {}).filter((k) => k !== '$schema').length;
|
|
1608
|
-
return (_jsx(WizardPreviewStep, { preview: state.serverPreview, spaceId: state.spaceId, environmentId: state.environmentId, stepNumber: totalSteps, totalSteps: totalSteps,
|
|
1609
|
-
void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge,
|
|
1608
|
+
return (_jsx(WizardPreviewStep, { preview: state.serverPreview, spaceId: state.spaceId, environmentId: state.environmentId, stepNumber: totalSteps, totalSteps: totalSteps, onConfirm: (acknowledge) => {
|
|
1609
|
+
void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge, state.serverPreview);
|
|
1610
1610
|
}, ...(editableComponentCount > 0 ? { onEdit: () => void runEditFromPreview() } : {}), onSaveFiles: () => {
|
|
1611
1611
|
void startSaveFlow();
|
|
1612
1612
|
}, onQuit: () => process.exit(0) }));
|
|
@@ -14,6 +14,5 @@ export type FinalReviewHostProps = {
|
|
|
14
14
|
host?: string;
|
|
15
15
|
tokensPath?: string;
|
|
16
16
|
initialFinalizeError?: string | null;
|
|
17
|
-
allowDeletions?: boolean;
|
|
18
17
|
};
|
|
19
|
-
export declare function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError,
|
|
18
|
+
export declare function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, }: FinalReviewHostProps): React.ReactElement;
|
|
@@ -4,7 +4,7 @@ import { PALETTE } from '../../analyze/select/tui/theme.js';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { GenerateReviewStep } from './steps/GenerateReviewStep.js';
|
|
6
6
|
import { AtomicGenerateReviewStep } from './steps/AtomicGenerateReviewStep.js';
|
|
7
|
-
export function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode = 'atomic', onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError,
|
|
7
|
+
export function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode = 'atomic', onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, }) {
|
|
8
8
|
if (!extractSessionId) {
|
|
9
9
|
return (_jsx(Box, { paddingX: 2, paddingY: 1, children: _jsx(Text, { color: PALETTE.error, children: "Error: no session ID \u2014 cannot load generated definitions." }) }));
|
|
10
10
|
}
|
|
@@ -15,7 +15,7 @@ export function FinalReviewHost({ extractSessionId, generatedCount, autoAccept,
|
|
|
15
15
|
// passes projectSlotGraph to FieldEditor and never walks closures/cycles, so
|
|
16
16
|
// slot-composition editing and every hierarchy affordance stay absent.
|
|
17
17
|
const StepComponent = compositionMode === 'atomic' ? AtomicGenerateReviewStep : GenerateReviewStep;
|
|
18
|
-
return (_jsx(StepComponent, { extractSessionId: extractSessionId, onFinalize: onFinalize, onQuit: onQuit, livePreview: livePreview, spaceId: spaceId, environmentId: environmentId, cmaToken: cmaToken, host: host, tokensPath: tokensPath, initialFinalizeError: initialFinalizeError
|
|
18
|
+
return (_jsx(StepComponent, { extractSessionId: extractSessionId, onFinalize: onFinalize, onQuit: onQuit, livePreview: livePreview, spaceId: spaceId, environmentId: environmentId, cmaToken: cmaToken, host: host, tokensPath: tokensPath, initialFinalizeError: initialFinalizeError }));
|
|
19
19
|
}
|
|
20
20
|
function FinalReviewAutoAccept({ generatedCount, onFinalize, }) {
|
|
21
21
|
React.useEffect(() => {
|
|
@@ -26,9 +26,6 @@ export type RunLivePreviewOptions = {
|
|
|
26
26
|
* full delete. Lets the Finalize dialog show exactly what the accepted push
|
|
27
27
|
* would delete, independent of the session's on-disk generated rows. */
|
|
28
28
|
acceptedKeys?: ReadonlySet<string>;
|
|
29
|
-
/** Forwarded verbatim to `previewImport`. Governs whether the response
|
|
30
|
-
* includes removed entities or a suppressed-count summary instead. */
|
|
31
|
-
allowDeletions?: boolean;
|
|
32
29
|
};
|
|
33
30
|
/**
|
|
34
31
|
* Pure async helper used by `useLivePreview` to re-fire `previewImport` after a
|
|
@@ -60,10 +60,7 @@ export async function runLivePreview(opts) {
|
|
|
60
60
|
timeoutHandle = setTimeout(() => reject(new TimeoutError()), timeoutMs);
|
|
61
61
|
});
|
|
62
62
|
try {
|
|
63
|
-
const response = (await Promise.race([
|
|
64
|
-
client.previewImport(manifest, opts.allowDeletions === true),
|
|
65
|
-
timeoutPromise,
|
|
66
|
-
]));
|
|
63
|
+
const response = (await Promise.race([client.previewImport(manifest), timeoutPromise]));
|
|
67
64
|
if (process.env['EDS_VERBOSE']) {
|
|
68
65
|
const durationMs = Date.now() - startedAt;
|
|
69
66
|
try {
|
|
@@ -11,7 +11,6 @@ type GenerateReviewStepProps = {
|
|
|
11
11
|
host?: string;
|
|
12
12
|
tokensPath?: string;
|
|
13
13
|
initialFinalizeError?: string | null;
|
|
14
|
-
allowDeletions?: boolean;
|
|
15
14
|
};
|
|
16
15
|
export declare function sortComponentsForSidebar<T extends {
|
|
17
16
|
key: string;
|
|
@@ -34,4 +33,4 @@ export interface BreakingRow {
|
|
|
34
33
|
}
|
|
35
34
|
export declare function buildBreakingRows(breakingChanges: BreakingComponent[]): BreakingRow[];
|
|
36
35
|
export declare function deriveBreakingChanges(response: ServerPreviewResponse): BreakingComponent[];
|
|
37
|
-
export declare function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError,
|
|
36
|
+
export declare function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, }: GenerateReviewStepProps): React.ReactElement;
|
|
@@ -174,7 +174,7 @@ export function deriveBreakingChanges(response) {
|
|
|
174
174
|
}
|
|
175
175
|
return out;
|
|
176
176
|
}
|
|
177
|
-
export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview = true, spaceId = '', environmentId = '', cmaToken = '', host = '', tokensPath = '', initialFinalizeError = null,
|
|
177
|
+
export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview = true, spaceId = '', environmentId = '', cmaToken = '', host = '', tokensPath = '', initialFinalizeError = null, }) {
|
|
178
178
|
const { stdout } = useStdout();
|
|
179
179
|
const terminalWidth = stdout?.columns ?? 80;
|
|
180
180
|
const [components, setComponents] = useState([]);
|
|
@@ -271,8 +271,9 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
271
271
|
cmaToken,
|
|
272
272
|
host,
|
|
273
273
|
onResult: handleLivePreviewResult,
|
|
274
|
+
// With nothing accepted, preview the delete-all diff so the review UI shows
|
|
275
|
+
// which existing components a push would remove (instead of an empty preview).
|
|
274
276
|
deleteAllComponents: acceptedCountForPreview === 0,
|
|
275
|
-
allowDeletions,
|
|
276
277
|
});
|
|
277
278
|
const SPINNER_FRAMES = '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏';
|
|
278
279
|
const [spinnerTick, setSpinnerTick] = useState(0);
|
|
@@ -351,7 +352,6 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
351
352
|
cmaToken,
|
|
352
353
|
host,
|
|
353
354
|
acceptedKeys: new Set(components.filter((c) => c.status === 'accepted').map((c) => c.key)),
|
|
354
|
-
allowDeletions,
|
|
355
355
|
});
|
|
356
356
|
const handleFinalizeConfirm = () => {
|
|
357
357
|
const acceptedCount = components.filter((c) => c.status === 'accepted').length;
|
|
@@ -12,14 +12,10 @@ type WizardPreviewStepProps = {
|
|
|
12
12
|
environmentId: string;
|
|
13
13
|
stepNumber: number;
|
|
14
14
|
totalSteps: number;
|
|
15
|
-
|
|
16
|
-
* `false`, the server never returned removed entities, so there is
|
|
17
|
-
* nothing to render item-by-item or toggle over. */
|
|
18
|
-
allowDeletions?: boolean;
|
|
19
|
-
onConfirm: (acknowledge: boolean, allowDeletions: boolean) => void;
|
|
15
|
+
onConfirm: (acknowledge: boolean) => void;
|
|
20
16
|
onEdit?: () => void;
|
|
21
17
|
onSaveFiles?: () => void;
|
|
22
18
|
onQuit: () => void;
|
|
23
19
|
};
|
|
24
|
-
export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps,
|
|
20
|
+
export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }: WizardPreviewStepProps): React.ReactElement;
|
|
25
21
|
export {};
|
|
@@ -89,14 +89,10 @@ export function buildPreviewDiffLines(preview) {
|
|
|
89
89
|
}
|
|
90
90
|
return lines;
|
|
91
91
|
}
|
|
92
|
-
export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps,
|
|
92
|
+
export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }) {
|
|
93
93
|
const breakingWithImpact = hasBreakingChangesWithImpact(preview);
|
|
94
94
|
const [diffExpanded, setDiffExpanded] = useState(false);
|
|
95
95
|
const [scrollOffset, setScrollOffset] = useState(0);
|
|
96
|
-
// Local state exists only to let the user opt OUT of a deletion the fetch
|
|
97
|
-
// already surfaced — it can never turn true when the fetch used false,
|
|
98
|
-
// because there's nothing in `preview` to reveal in that case.
|
|
99
|
-
const [allowDeletions, setAllowDeletions] = useState(fetchedAllowDeletions);
|
|
100
96
|
const { stdout } = useStdout();
|
|
101
97
|
const terminalRows = stdout?.rows ?? 40;
|
|
102
98
|
const viewportHeight = Math.max(terminalRows - 14, 10);
|
|
@@ -109,14 +105,9 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
|
|
|
109
105
|
}));
|
|
110
106
|
}, [diffExpanded, preview]);
|
|
111
107
|
const maxScroll = Math.max(0, allDiffLines.length - viewportHeight);
|
|
112
|
-
const removedCount = preview.components.removed.length + preview.tokens.removed.length;
|
|
113
108
|
useImmediateInput((input, key) => {
|
|
114
109
|
if (key.return) {
|
|
115
|
-
onConfirm(breakingWithImpact
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
if ((input === 'x' || input === 'X') && fetchedAllowDeletions && removedCount > 0) {
|
|
119
|
-
setAllowDeletions((prev) => !prev);
|
|
110
|
+
onConfirm(breakingWithImpact);
|
|
120
111
|
return;
|
|
121
112
|
}
|
|
122
113
|
if (input === 'd' || input === 'D') {
|
|
@@ -165,5 +156,5 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
|
|
|
165
156
|
})] })), components.changed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.warning, children: " \uFF5E" }), _jsxs(Text, { children: [components.changed.length, " will be updated"] })] }), components.changed.map((item, i) => {
|
|
166
157
|
const isBreaking = item.changeClassification?.classification === 'breaking';
|
|
167
158
|
return (_jsxs(Text, { color: isBreaking ? PALETTE.error : PALETTE.warning, children: [' ', isBreaking ? '⚠' : '~', " ", item.current.name] }, `chg-${i}`));
|
|
168
|
-
})] })), components.removed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color:
|
|
159
|
+
})] })), components.removed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.error, children: " \u2717" }), _jsxs(Text, { children: [components.removed.length, " will be removed"] })] }), components.removed.map((item, i) => (_jsxs(Text, { color: PALETTE.error, children: [' ', "\u2717 ", item.name] }, `rm-${i}`)))] })), components.unchanged.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: " \u00B7" }), _jsxs(Text, { dimColor: true, children: [components.unchanged.length, " unchanged"] })] }))] })), hasTokens && (_jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(Box, { gap: 1, marginTop: 1, children: _jsx(Text, { bold: true, dimColor: true, children: "Design Tokens" }) }), tokens.new.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.success, children: " \uFF0B" }), _jsxs(Text, { children: [tokens.new.length, " will be created"] })] })), tokens.changed.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.warning, children: " \uFF5E" }), _jsxs(Text, { children: [tokens.changed.length, " will be updated"] })] })), tokens.removed.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.error, children: " \u2717" }), _jsxs(Text, { children: [tokens.removed.length, " will be removed"] })] })), tokens.unchanged.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: " \u00B7" }), _jsxs(Text, { dimColor: true, children: [tokens.unchanged.length, " unchanged"] })] }))] })), diffExpanded && allDiffLines.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, children: '─'.repeat(40) }), _jsxs(Text, { dimColor: true, children: [' ', "Diff (", allDiffLines.length, " lines) \u2014 line ", scrollOffset + 1, "\u2013", Math.min(scrollOffset + viewportHeight, allDiffLines.length), " of ", allDiffLines.length] }), _jsx(Box, { flexDirection: "column", children: allDiffLines.slice(scrollOffset, scrollOffset + viewportHeight).map((line) => (_jsx(Box, { children: line.element }, line.key))) }), maxScroll > 0 && _jsx(Text, { dimColor: true, children: " \u2195 j/k to scroll, f/b to page" })] }))] })) : (_jsx(Text, { dimColor: true, children: "Nothing to push \u2014 everything is already up to date." })), _jsxs(Box, { gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Space:" }), _jsx(Text, { children: spaceId }), _jsx(Text, { dimColor: true, children: "/" }), _jsx(Text, { dimColor: true, children: "Environment:" }), _jsx(Text, { children: environmentId })] }), breakingWithImpact && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: PALETTE.error, bold: true, children: "\u26A0 Breaking changes will affect downstream entities. Press Enter to acknowledge and apply." }) })), _jsxs(Box, { gap: 3, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "[Enter] Push to Contentful" }), _jsxs(Text, { dimColor: true, children: ["[d] ", diffExpanded ? 'Hide' : 'Show', " diff"] }), diffExpanded && _jsx(Text, { dimColor: true, children: "[j/k] Scroll [f/b] Page" }), onEdit && _jsx(Text, { dimColor: true, children: "[e] Edit definitions" }), onSaveFiles && _jsx(Text, { dimColor: true, children: "[s] Save files instead" }), _jsx(Text, { dimColor: true, children: "[q] Cancel" })] })] }));
|
|
169
160
|
}
|
|
@@ -11,8 +11,6 @@ export type UseFinalizePreviewOptions = {
|
|
|
11
11
|
host: string;
|
|
12
12
|
/** Component keys the operator has accepted; drives the scoped preview. */
|
|
13
13
|
acceptedKeys: ReadonlySet<string>;
|
|
14
|
-
/** Forwarded verbatim to `runLivePreview`/`previewImport`. */
|
|
15
|
-
allowDeletions?: boolean;
|
|
16
14
|
};
|
|
17
15
|
export type UseFinalizePreviewReturn = {
|
|
18
16
|
status: FinalizePreviewStatus;
|
|
Binary file
|
|
@@ -12,8 +12,6 @@ export type UseLivePreviewOptions = {
|
|
|
12
12
|
/** Preview an empty-but-present manifest (delete-all diff) when nothing is
|
|
13
13
|
* accepted, so the final-review UI can show what a push would delete. */
|
|
14
14
|
deleteAllComponents?: boolean;
|
|
15
|
-
/** Forwarded verbatim to `runLivePreview`/`previewImport`. */
|
|
16
|
-
allowDeletions?: boolean;
|
|
17
15
|
};
|
|
18
16
|
export type LivePreviewStatus = 'idle' | 'running';
|
|
19
17
|
export type UseLivePreviewReturn = {
|
|
@@ -82,7 +82,6 @@ export function useLivePreview(opts) {
|
|
|
82
82
|
host: current.host,
|
|
83
83
|
generation,
|
|
84
84
|
deleteAllComponents: current.deleteAllComponents === true,
|
|
85
|
-
allowDeletions: current.allowDeletions === true,
|
|
86
85
|
});
|
|
87
86
|
// Discard stale responses (generation tag).
|
|
88
87
|
if (result.generation !== latestRef.current)
|
package/dist/src/index.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { createProgram } from './program.js';
|
|
2
|
+
import { failActiveCommand, flushAnalytics } from './analytics/index.js';
|
|
2
3
|
createProgram()
|
|
3
4
|
.parseAsync()
|
|
4
|
-
.catch((err) => {
|
|
5
|
+
.catch(async (err) => {
|
|
6
|
+
await failActiveCommand({
|
|
7
|
+
error_name: err instanceof Error ? err.name : 'Error',
|
|
8
|
+
});
|
|
9
|
+
await flushAnalytics();
|
|
5
10
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
6
11
|
process.exit(1);
|
|
7
12
|
});
|
|
@@ -3,4 +3,3 @@ export declare function addArtifactInputOptions(cmd: Command): Command;
|
|
|
3
3
|
export declare function addContentfulTargetOptions(cmd: Command): Command;
|
|
4
4
|
export declare function addCompositionOptions(cmd: Command): Command;
|
|
5
5
|
export declare function addSelectionOptions(cmd: Command): Command;
|
|
6
|
-
export declare function addAllowDeletionsOption(cmd: Command): Command;
|
|
@@ -25,6 +25,3 @@ export function addSelectionOptions(cmd) {
|
|
|
25
25
|
.option('--select <pattern>', 'Select entities by ID pattern (repeatable)', collectOptionValue, [])
|
|
26
26
|
.option('--deselect <pattern>', 'Deselect entities by ID pattern (repeatable)', collectOptionValue, []);
|
|
27
27
|
}
|
|
28
|
-
export function addAllowDeletionsOption(cmd) {
|
|
29
|
-
return cmd.option('--allow-deletions', 'Allow the push to delete remote ComponentTypes/DesignTokens missing from the manifest (default: skip them)');
|
|
30
|
-
}
|