@contentful/experience-design-system-cli 2.26.1-dev-build-a852362.0 → 2.26.1-dev-build-f03f014.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +14 -10
- package/dist/src/index.js +34937 -9
- package/dist/src/lib/cli-path.d.ts +4 -0
- package/dist/src/runs/export-helpers.d.ts +1 -12
- package/dist/src/runs/push-helpers.d.ts +1 -6
- package/package.json +12 -7
- package/skills/generate-components.md +427 -0
- package/skills/generate-tokens.md +194 -0
- package/skills/select-components.md +224 -0
- package/dist/src/analytics/apply.js +0 -30
- package/dist/src/analytics/client.js +0 -81
- package/dist/src/analytics/constants.js +0 -4
- package/dist/src/analytics/env.js +0 -14
- package/dist/src/analytics/exit.js +0 -24
- package/dist/src/analytics/index.js +0 -9
- package/dist/src/analytics/normalize.js +0 -18
- package/dist/src/analytics/os.js +0 -13
- package/dist/src/analytics/session.js +0 -15
- package/dist/src/analytics/tracker.js +0 -126
- package/dist/src/analytics/types.js +0 -1
- package/dist/src/analyze/build-analyze-view-rows.js +0 -63
- package/dist/src/analyze/command.js +0 -599
- package/dist/src/analyze/composite-closure.js +0 -0
- package/dist/src/analyze/composition/agent-parser/author-prompt.js +0 -22
- package/dist/src/analyze/composition/agent-parser/extract-parser.js +0 -44
- package/dist/src/analyze/composition/agent-parser/load-prompt.js +0 -31
- package/dist/src/analyze/composition/agent-parser/resolve-via-parser.js +0 -88
- package/dist/src/analyze/composition/agent-parser/sandbox.js +0 -187
- package/dist/src/analyze/composition/apply-mapping.js +0 -67
- package/dist/src/analyze/composition/candidate-critic-agent.js +0 -39
- package/dist/src/analyze/composition/candidate-critic.js +0 -63
- package/dist/src/analyze/composition/candidate-files.js +0 -131
- package/dist/src/analyze/composition/composition-cache-key.js +0 -19
- package/dist/src/analyze/composition/interchange-schema.js +0 -61
- package/dist/src/analyze/composition/manifest-doc-evidence.js +0 -136
- package/dist/src/analyze/composition/merge-edges.js +0 -70
- package/dist/src/analyze/composition/parse-map-edges.js +0 -55
- package/dist/src/analyze/composition/resolve-mapping-cli.js +0 -29
- package/dist/src/analyze/composition/resolve-mapping.js +0 -111
- package/dist/src/analyze/cycle-detection.js +0 -234
- package/dist/src/analyze/cycle-view.js +0 -28
- package/dist/src/analyze/fuzzy-search.js +0 -55
- package/dist/src/analyze/issue-inheritance.js +0 -108
- package/dist/src/analyze/lineage.js +0 -0
- package/dist/src/analyze/scope-gate-cascade.js +0 -170
- package/dist/src/analyze/search-neighborhood.js +0 -56
- package/dist/src/analyze/select/command.js +0 -484
- package/dist/src/analyze/select/index.js +0 -5
- package/dist/src/analyze/select/parser.js +0 -53
- package/dist/src/analyze/select/persistence.js +0 -80
- package/dist/src/analyze/select/preview-annotations.js +0 -62
- package/dist/src/analyze/select/stdout.js +0 -3
- package/dist/src/analyze/select/tui/App.js +0 -483
- package/dist/src/analyze/select/tui/components/ComponentDetail.js +0 -48
- package/dist/src/analyze/select/tui/components/ComponentRationalePanel.js +0 -125
- package/dist/src/analyze/select/tui/components/FieldEditor.js +0 -1131
- package/dist/src/analyze/select/tui/components/FinalizeDialog.js +0 -36
- package/dist/src/analyze/select/tui/components/GotoBanner.js +0 -30
- package/dist/src/analyze/select/tui/components/GroupedSidebar.js +0 -517
- package/dist/src/analyze/select/tui/components/HelpOverlay.js +0 -17
- package/dist/src/analyze/select/tui/components/JsonEditor.js +0 -131
- package/dist/src/analyze/select/tui/components/JsonPanel.js +0 -66
- package/dist/src/analyze/select/tui/components/LineagePanel.js +0 -22
- package/dist/src/analyze/select/tui/components/PreviewSummaryBar.js +0 -29
- package/dist/src/analyze/select/tui/components/QuitDialog.js +0 -14
- package/dist/src/analyze/select/tui/components/RationalePanel.js +0 -80
- package/dist/src/analyze/select/tui/components/Sidebar.js +0 -92
- package/dist/src/analyze/select/tui/components/SourcePanel.js +0 -52
- package/dist/src/analyze/select/tui/components/StatusBar.js +0 -7
- package/dist/src/analyze/select/tui/components/TopBar.js +0 -10
- package/dist/src/analyze/select/tui/components/removed-components-text.js +0 -11
- package/dist/src/analyze/select/tui/hooks/scroll-offset.js +0 -26
- package/dist/src/analyze/select/tui/hooks/useImmediateInput.js +0 -66
- package/dist/src/analyze/select/tui/hooks/useKeymap.js +0 -67
- package/dist/src/analyze/select/tui/hooks/useSession.js +0 -52
- package/dist/src/analyze/select/tui/hooks/useUndo.js +0 -26
- package/dist/src/analyze/select/tui/theme.js +0 -28
- package/dist/src/analyze/select/types.js +0 -39
- package/dist/src/analyze/select-agent/command.js +0 -558
- package/dist/src/analyze/select-agent/context-builder.js +0 -197
- package/dist/src/analyze/select-agent/show-rationale.js +0 -92
- package/dist/src/analyze/selection-cascade.js +0 -19
- package/dist/src/analyze/slot-graph.js +0 -17
- package/dist/src/analyze/tui/AnalyzeView.js +0 -64
- package/dist/src/apply/api-client.js +0 -440
- package/dist/src/apply/command.js +0 -845
- package/dist/src/apply/manifest.js +0 -1
- package/dist/src/apply/preview-utils.js +0 -26
- package/dist/src/apply/tui/SelectView.js +0 -34
- package/dist/src/apply/tui/ServerApplyView.js +0 -49
- package/dist/src/apply/tui/ServerPreviewView.js +0 -23
- package/dist/src/credentials-store.js +0 -74
- package/dist/src/generate/command.js +0 -597
- package/dist/src/generate/edit/command.js +0 -127
- package/dist/src/generate/tui/GenerateView.js +0 -10
- package/dist/src/host-utils.js +0 -26
- package/dist/src/import/agent-model-resolve.js +0 -35
- package/dist/src/import/auto-filter-resolve.js +0 -16
- package/dist/src/import/command.js +0 -380
- package/dist/src/import/cycle-auto-reject.js +0 -14
- package/dist/src/import/orchestrator.js +0 -603
- package/dist/src/import/path-utils.js +0 -30
- package/dist/src/import/picker-dispatch.js +0 -44
- package/dist/src/import/print-prompt.js +0 -31
- package/dist/src/import/strip-allowed-components.js +0 -22
- package/dist/src/import/tui/CustomPromptBanner.js +0 -8
- package/dist/src/import/tui/WizardApp.js +0 -1670
- package/dist/src/import/tui/ai-flag.js +0 -6
- package/dist/src/import/tui/auto-filter-error.js +0 -29
- package/dist/src/import/tui/autocomplete.js +0 -32
- package/dist/src/import/tui/components/AutoFilterBanner.js +0 -19
- package/dist/src/import/tui/components/CounterStrip.js +0 -12
- package/dist/src/import/tui/components/LegendEntry.js +0 -6
- package/dist/src/import/tui/cycle-panel-scroll.js +0 -33
- package/dist/src/import/tui/final-review-host.js +0 -25
- package/dist/src/import/tui/group-collapse.js +0 -11
- package/dist/src/import/tui/history.js +0 -53
- package/dist/src/import/tui/hooks/useLineage.js +0 -50
- package/dist/src/import/tui/hooks/useOverlayPanel.js +0 -27
- package/dist/src/import/tui/lineage-layout.js +0 -82
- package/dist/src/import/tui/merge-ai-decisions.js +0 -22
- package/dist/src/import/tui/push-decision-gate-helpers.js +0 -8
- package/dist/src/import/tui/push-progress.js +0 -1
- package/dist/src/import/tui/run-print-files-helpers.js +0 -8
- package/dist/src/import/tui/run-teaser.js +0 -9
- package/dist/src/import/tui/runLivePreview.js +0 -82
- package/dist/src/import/tui/runScopeGate.js +0 -28
- package/dist/src/import/tui/scope-gate-columns.js +0 -94
- package/dist/src/import/tui/scope-gate-host.js +0 -28
- package/dist/src/import/tui/sidebar-width.js +0 -3
- package/dist/src/import/tui/spawn-generate.js +0 -53
- package/dist/src/import/tui/step-filters.js +0 -42
- package/dist/src/import/tui/steps/AtomicGenerateReviewStep.js +0 -726
- package/dist/src/import/tui/steps/AtomicScopeGateStep.js +0 -210
- package/dist/src/import/tui/steps/CredentialsStep.js +0 -108
- package/dist/src/import/tui/steps/DoneStep.js +0 -24
- package/dist/src/import/tui/steps/ErrorStep.js +0 -16
- package/dist/src/import/tui/steps/GateStep.js +0 -22
- package/dist/src/import/tui/steps/GenerateReviewStep.js +0 -1618
- package/dist/src/import/tui/steps/PathValidationStep.js +0 -152
- package/dist/src/import/tui/steps/PreviewStep.js +0 -37
- package/dist/src/import/tui/steps/PreviewValidationErrorStep.js +0 -23
- package/dist/src/import/tui/steps/PushDecisionGateStep.js +0 -73
- package/dist/src/import/tui/steps/PushingStep.js +0 -24
- package/dist/src/import/tui/steps/RunningStep.js +0 -21
- package/dist/src/import/tui/steps/ScopeGateStep.js +0 -907
- package/dist/src/import/tui/steps/TokenInputStep.js +0 -88
- package/dist/src/import/tui/steps/WelcomeStep.js +0 -34
- package/dist/src/import/tui/steps/WizardPreviewStep.js +0 -169
- package/dist/src/import/tui/steps/auto-reject-decision.js +0 -9
- package/dist/src/import/tui/steps/breaking-change-format.js +0 -24
- package/dist/src/import/tui/steps/enumerate-cycle-breaks.js +0 -0
- package/dist/src/import/tui/steps/preview-diff.js +0 -175
- package/dist/src/import/tui/useFinalizePreview.js +0 -0
- package/dist/src/import/tui/useLivePreview.js +0 -122
- package/dist/src/import/tui/wizard-422-helpers.js +0 -60
- package/dist/src/import/tui/wizard-generate-progress.js +0 -25
- package/dist/src/import/tui/wizard-save-flow.js +0 -20
- package/dist/src/import/tui/wizard-state-transitions.js +0 -32
- package/dist/src/lib/agent-model-options.js +0 -15
- package/dist/src/lib/command-options.js +0 -30
- package/dist/src/lib/composition-mode.js +0 -39
- package/dist/src/lib/contentful-urls.js +0 -27
- package/dist/src/lib/debug-logger.js +0 -229
- package/dist/src/lib/debug-preamble.js +0 -33
- package/dist/src/lib/error-parser.js +0 -269
- package/dist/src/lib/prompt-overrides.js +0 -69
- package/dist/src/lib/terminal-capabilities.js +0 -51
- package/dist/src/lib/user-agent.js +0 -29
- package/dist/src/output/format.js +0 -110
- package/dist/src/print/command.js +0 -221
- package/dist/src/print/validate/tui/ValidateView.js +0 -37
- package/dist/src/print/validate/validators/cdf-validator.js +0 -104
- package/dist/src/print/validate/validators/dtcg-validator.js +0 -110
- package/dist/src/print/validate/validators/format-errors.js +0 -18
- package/dist/src/program.js +0 -105
- package/dist/src/runs/export-helpers.js +0 -59
- package/dist/src/runs/fingerprint.js +0 -75
- package/dist/src/runs/ls-command.js +0 -137
- package/dist/src/runs/modify-launcher.js +0 -42
- package/dist/src/runs/path-prompt.js +0 -72
- package/dist/src/runs/push-creds-prompt.js +0 -39
- package/dist/src/runs/push-helpers.js +0 -72
- package/dist/src/runs/push-launcher.js +0 -77
- package/dist/src/runs/replay-helpers.js +0 -164
- package/dist/src/runs/resolve-run-target.js +0 -45
- package/dist/src/runs/run-picker-mount.js +0 -72
- package/dist/src/runs/run-picker.js +0 -129
- package/dist/src/runs/save-conflict.js +0 -56
- package/dist/src/runs/save-path-resolver.js +0 -75
- package/dist/src/runs/staleness.js +0 -140
- package/dist/src/runs/store.js +0 -136
- package/dist/src/session/cache-keys.js +0 -44
- package/dist/src/session/command.js +0 -261
- package/dist/src/session/db.js +0 -1538
- package/dist/src/session/migration.js +0 -117
- package/dist/src/session/session-id.js +0 -212
- package/dist/src/session/stats.js +0 -89
- package/dist/src/setup/analytics-prompt.js +0 -24
- package/dist/src/setup/auto-filter-prompt.js +0 -24
- package/dist/src/setup/command.js +0 -966
- package/dist/src/setup/composition-mode-prompt.js +0 -37
- package/dist/src/setup/debug-mode-prompt.js +0 -22
- package/dist/src/types.js +0 -1
|
@@ -1,603 +0,0 @@
|
|
|
1
|
-
import { mkdir } from 'node:fs/promises';
|
|
2
|
-
import { join, resolve } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { execFile } from 'node:child_process';
|
|
5
|
-
import { openPipelineDb, getOrCreateSession, createStep, updateStep, findLatestSessionForCommand, loadCDFComponents, } from '../session/db.js';
|
|
6
|
-
import { detectSlotCycles, formatSlotCycleReport } from '../apply/command.js';
|
|
7
|
-
import { PREVIEW_ERROR_PREFIX, VALIDATION_FAILED_CODE, parsePreviewValidationErrors } from '../apply/api-client.js';
|
|
8
|
-
import { buildPostPushUrl } from '../lib/contentful-urls.js';
|
|
9
|
-
import { getDebugLogger } from '../lib/debug-logger.js';
|
|
10
|
-
import { bindAnalyticsSession, emitSessionStarted } from '../analytics/index.js';
|
|
11
|
-
import { pipelineSubprocessEnv } from '../analytics/env.js';
|
|
12
|
-
function findCliPath() {
|
|
13
|
-
return join(fileURLToPath(import.meta.url), '..', '..', '..', '..', 'bin', 'cli.js');
|
|
14
|
-
}
|
|
15
|
-
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
16
|
-
const debug = getDebugLogger();
|
|
17
|
-
const startedAt = Date.now();
|
|
18
|
-
debug.event('import', 'subprocess.spawn', { cliPath, args });
|
|
19
|
-
return new Promise((res) => {
|
|
20
|
-
const child = execFile('node', [cliPath, ...args], {
|
|
21
|
-
env: pipelineSubprocessEnv({ ...process.env, ...env }, analyticsSessionId),
|
|
22
|
-
});
|
|
23
|
-
let stdout = '';
|
|
24
|
-
let stderr = '';
|
|
25
|
-
child.stdout?.on('data', (chunk) => {
|
|
26
|
-
stdout += chunk.toString();
|
|
27
|
-
});
|
|
28
|
-
child.stderr?.on('data', (chunk) => {
|
|
29
|
-
const text = chunk.toString();
|
|
30
|
-
stderr += text;
|
|
31
|
-
if (streamStderr)
|
|
32
|
-
process.stderr.write(text);
|
|
33
|
-
});
|
|
34
|
-
child.on('close', (code) => {
|
|
35
|
-
const exitCode = code ?? 0;
|
|
36
|
-
debug.event('import', 'subprocess.exit', {
|
|
37
|
-
args,
|
|
38
|
-
exitCode,
|
|
39
|
-
durationMs: Date.now() - startedAt,
|
|
40
|
-
stdoutLen: stdout.length,
|
|
41
|
-
stderrLen: stderr.length,
|
|
42
|
-
stderrTail: stderr.slice(-1000),
|
|
43
|
-
});
|
|
44
|
-
res({ exitCode, stdout, stderr });
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
const MAX_VALIDATION_RETRIES = Number(process.env['EDS_MAX_VALIDATION_RETRIES'] ?? 2);
|
|
49
|
-
export const SLOT_CYCLE_MARKER = 'manifest:components/slot-cycles';
|
|
50
|
-
export function isSlotCycleError(result) {
|
|
51
|
-
return result.exitCode !== 0 && result.stderr.includes(SLOT_CYCLE_MARKER);
|
|
52
|
-
}
|
|
53
|
-
export function extractCycleReport(stderr) {
|
|
54
|
-
return stderr.split('\n').filter((line) => line.trim());
|
|
55
|
-
}
|
|
56
|
-
export function parseCycleComponentNames(report) {
|
|
57
|
-
const names = [];
|
|
58
|
-
for (const line of report) {
|
|
59
|
-
const m = line.match(/Fix: remove '([^']+)' from /);
|
|
60
|
-
if (m)
|
|
61
|
-
names.push(m[1]);
|
|
62
|
-
}
|
|
63
|
-
return [...new Set(names)];
|
|
64
|
-
}
|
|
65
|
-
export function isPreviewValidationError(result) {
|
|
66
|
-
if (result.exitCode === 0 || !result.stderr.includes(`${PREVIEW_ERROR_PREFIX} 422`))
|
|
67
|
-
return false;
|
|
68
|
-
return result.stderr.includes(VALIDATION_FAILED_CODE) || result.stderr.includes('[ValidationFailed]');
|
|
69
|
-
}
|
|
70
|
-
export function parseOffendingComponentNames(output) {
|
|
71
|
-
const jsonStart = output.indexOf('{');
|
|
72
|
-
if (jsonStart !== -1) {
|
|
73
|
-
const errors = parsePreviewValidationErrors(output.slice(jsonStart));
|
|
74
|
-
const names = [...new Set(errors.map((error) => error.componentName))];
|
|
75
|
-
if (names.length > 0)
|
|
76
|
-
return names;
|
|
77
|
-
}
|
|
78
|
-
const names = [...output.matchAll(/Component:\s*([^;\n)]+)/g)].map((match) => match[1].trim()).filter(Boolean);
|
|
79
|
-
return [...new Set(names)];
|
|
80
|
-
}
|
|
81
|
-
export function buildPushStepResult(args) {
|
|
82
|
-
const { created, updated, failed, durationMs, stderr, excludedByRetry, totalFailure } = args;
|
|
83
|
-
const excludedDetail = excludedByRetry.length > 0 ? { excludedByValidationRetry: excludedByRetry } : {};
|
|
84
|
-
if (totalFailure) {
|
|
85
|
-
const detail = excludedByRetry.length > 0 ? { ...excludedDetail } : undefined;
|
|
86
|
-
return {
|
|
87
|
-
step: 'apply push',
|
|
88
|
-
status: 'failed',
|
|
89
|
-
durationMs,
|
|
90
|
-
error: stderr,
|
|
91
|
-
...(detail ? { detail } : {}),
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
const status = failed > 0 ? 'failed' : 'complete';
|
|
95
|
-
return {
|
|
96
|
-
step: 'apply push',
|
|
97
|
-
status,
|
|
98
|
-
durationMs,
|
|
99
|
-
detail: { created, updated, failed, ...excludedDetail },
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
export async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
103
|
-
const projectRoot = resolve(opts.project);
|
|
104
|
-
const outDir = resolve(opts.out);
|
|
105
|
-
const componentsPath = join(outDir, 'components.json');
|
|
106
|
-
const cliPath = cliPathOverride ?? findCliPath();
|
|
107
|
-
const db = openPipelineDb();
|
|
108
|
-
const { sessionId } = getOrCreateSession(db, undefined, undefined, {
|
|
109
|
-
command: 'import',
|
|
110
|
-
inputPath: projectRoot,
|
|
111
|
-
outDir,
|
|
112
|
-
});
|
|
113
|
-
await bindAnalyticsSession(sessionId, {
|
|
114
|
-
...(opts.spaceId ? { space_key: opts.spaceId, environment_key: opts.environmentId } : {}),
|
|
115
|
-
});
|
|
116
|
-
await emitSessionStarted('import');
|
|
117
|
-
progressWriter(`Experience Design System CLI — Pipeline Import`);
|
|
118
|
-
progressWriter(`Project: ${projectRoot}`);
|
|
119
|
-
progressWriter(`Output: ${outDir}`);
|
|
120
|
-
if (opts.spaceId)
|
|
121
|
-
progressWriter(`Space: ${opts.spaceId} (${opts.environmentId})`);
|
|
122
|
-
progressWriter(`Session: ${sessionId}`);
|
|
123
|
-
progressWriter('');
|
|
124
|
-
await mkdir(outDir, { recursive: true });
|
|
125
|
-
const steps = [];
|
|
126
|
-
let stepNum = 0;
|
|
127
|
-
const totalSteps = 4 + (opts.print ? 1 : 0);
|
|
128
|
-
function stepLabel(name) {
|
|
129
|
-
stepNum++;
|
|
130
|
-
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
131
|
-
}
|
|
132
|
-
const analyzeLabel = stepLabel('Statically analyzing project');
|
|
133
|
-
const analyzeSkipped = !opts.noCache && opts.skipAnalyze;
|
|
134
|
-
let extractSessionId = null;
|
|
135
|
-
if (analyzeSkipped) {
|
|
136
|
-
progressWriter(`${analyzeLabel}– skipped (--skip-analyze)`);
|
|
137
|
-
steps.push({
|
|
138
|
-
step: 'analyze extract',
|
|
139
|
-
status: 'skipped',
|
|
140
|
-
reason: '--skip-analyze',
|
|
141
|
-
});
|
|
142
|
-
const prior = findLatestSessionForCommand(db, 'analyze extract');
|
|
143
|
-
extractSessionId = prior ?? null;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
const stepId = createStep(db, sessionId, 'analyze extract', {
|
|
147
|
-
project: projectRoot,
|
|
148
|
-
});
|
|
149
|
-
const t0 = Date.now();
|
|
150
|
-
const analyzeArgs = ['analyze', 'extract', '--project', projectRoot];
|
|
151
|
-
if (opts.compositionMode === 'composite') {
|
|
152
|
-
analyzeArgs.push('--composite');
|
|
153
|
-
if (opts.compositionMap)
|
|
154
|
-
analyzeArgs.push('--composition-map', opts.compositionMap);
|
|
155
|
-
if (opts.compositionAgent)
|
|
156
|
-
analyzeArgs.push('--composition-agent');
|
|
157
|
-
if (opts.compositionAgentMode)
|
|
158
|
-
analyzeArgs.push('--composition-agent-mode', opts.compositionAgentMode);
|
|
159
|
-
if (opts.compositionRefresh)
|
|
160
|
-
analyzeArgs.push('--composition-refresh');
|
|
161
|
-
if (opts.generateMap)
|
|
162
|
-
analyzeArgs.push('--generate-map', opts.generateMap);
|
|
163
|
-
for (const p of opts.promptOverrides ?? [])
|
|
164
|
-
analyzeArgs.push('--prompt', p);
|
|
165
|
-
if (opts.agent)
|
|
166
|
-
analyzeArgs.push('--agent', opts.agent);
|
|
167
|
-
}
|
|
168
|
-
const r = await runStep(analyzeArgs, cliPath, sessionId);
|
|
169
|
-
const durationMs = Date.now() - t0;
|
|
170
|
-
if (r.exitCode !== 0) {
|
|
171
|
-
if (r.stderr)
|
|
172
|
-
process.stderr.write(r.stderr);
|
|
173
|
-
updateStep(db, stepId, 'failed', {}, r.stderr);
|
|
174
|
-
progressWriter(`${analyzeLabel}✗ failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
175
|
-
steps.push({
|
|
176
|
-
step: 'analyze extract',
|
|
177
|
-
status: 'failed',
|
|
178
|
-
durationMs,
|
|
179
|
-
error: r.stderr,
|
|
180
|
-
});
|
|
181
|
-
db.close();
|
|
182
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
183
|
-
}
|
|
184
|
-
extractSessionId = findLatestSessionForCommand(db, 'analyze extract') ?? null;
|
|
185
|
-
const componentMatch = /Extracted (\d+) component/.exec(r.stderr);
|
|
186
|
-
const componentCount = componentMatch ? Number(componentMatch[1]) : 0;
|
|
187
|
-
updateStep(db, stepId, 'complete', {
|
|
188
|
-
extractSessionId: extractSessionId ?? '',
|
|
189
|
-
});
|
|
190
|
-
progressWriter(`${analyzeLabel}✓ ${componentCount} component${componentCount === 1 ? '' : 's'} found (${(durationMs / 1000).toFixed(1)}s)`);
|
|
191
|
-
steps.push({
|
|
192
|
-
step: 'analyze extract',
|
|
193
|
-
status: 'complete',
|
|
194
|
-
durationMs,
|
|
195
|
-
detail: { components: componentCount },
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
const editLabel = stepLabel('Filtering components');
|
|
199
|
-
if (analyzeSkipped) {
|
|
200
|
-
progressWriter(`${editLabel}– skipped (--skip-analyze)`);
|
|
201
|
-
steps.push({
|
|
202
|
-
step: 'analyze select',
|
|
203
|
-
status: 'skipped',
|
|
204
|
-
reason: '--skip-analyze',
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
else if (extractSessionId) {
|
|
208
|
-
const editStepId = createStep(db, sessionId, 'analyze select', {
|
|
209
|
-
extractSession: extractSessionId,
|
|
210
|
-
});
|
|
211
|
-
const t0Edit = Date.now();
|
|
212
|
-
const useAgentSelect = !opts.selectAll && (!opts.select || opts.select.length === 0) && (!opts.deselect || opts.deselect.length === 0);
|
|
213
|
-
let editArgs;
|
|
214
|
-
if (useAgentSelect) {
|
|
215
|
-
editArgs = ['analyze', 'select-agent', '--session', extractSessionId, '--agent', opts.agent];
|
|
216
|
-
if (opts.model)
|
|
217
|
-
editArgs.push('--model', opts.model);
|
|
218
|
-
if (opts.excludeInvalid)
|
|
219
|
-
editArgs.push('--exclude-invalid');
|
|
220
|
-
if (opts.noCache)
|
|
221
|
-
editArgs.push('--no-cache');
|
|
222
|
-
if (opts.selectPromptPath)
|
|
223
|
-
editArgs.push('--select-prompt-path', opts.selectPromptPath);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
editArgs = ['analyze', 'select', '--session', extractSessionId];
|
|
227
|
-
if (opts.select && opts.select.length > 0) {
|
|
228
|
-
for (const p of opts.select)
|
|
229
|
-
editArgs.push('--select', p);
|
|
230
|
-
}
|
|
231
|
-
else if (opts.deselect && opts.deselect.length > 0) {
|
|
232
|
-
for (const p of opts.deselect)
|
|
233
|
-
editArgs.push('--deselect', p);
|
|
234
|
-
editArgs.push('--select-all');
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
editArgs.push('--select-all');
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
const rEdit = await runStep(editArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, useAgentSelect);
|
|
241
|
-
const editDurationMs = Date.now() - t0Edit;
|
|
242
|
-
if (rEdit.exitCode !== 0) {
|
|
243
|
-
if (rEdit.stderr && !useAgentSelect)
|
|
244
|
-
process.stderr.write(rEdit.stderr);
|
|
245
|
-
updateStep(db, editStepId, 'failed', {}, rEdit.stderr);
|
|
246
|
-
progressWriter(`${editLabel}✗ failed (${(editDurationMs / 1000).toFixed(1)}s)`);
|
|
247
|
-
steps.push({
|
|
248
|
-
step: 'analyze select',
|
|
249
|
-
status: 'failed',
|
|
250
|
-
durationMs: editDurationMs,
|
|
251
|
-
error: rEdit.stderr,
|
|
252
|
-
});
|
|
253
|
-
db.close();
|
|
254
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
255
|
-
}
|
|
256
|
-
const acceptedMatch = /Accepted: (\d+)/.exec(rEdit.stderr);
|
|
257
|
-
const acceptedCount = acceptedMatch ? Number(acceptedMatch[1]) : 0;
|
|
258
|
-
updateStep(db, editStepId, 'complete', {
|
|
259
|
-
extractSession: extractSessionId,
|
|
260
|
-
});
|
|
261
|
-
progressWriter(`${editLabel}✓ ${acceptedCount} accepted (${(editDurationMs / 1000).toFixed(1)}s)`);
|
|
262
|
-
steps.push({
|
|
263
|
-
step: 'analyze select',
|
|
264
|
-
status: 'complete',
|
|
265
|
-
durationMs: editDurationMs,
|
|
266
|
-
detail: { accepted: acceptedCount },
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
progressWriter(`${editLabel}– skipped (no extract session)`);
|
|
271
|
-
steps.push({
|
|
272
|
-
step: 'analyze select',
|
|
273
|
-
status: 'skipped',
|
|
274
|
-
reason: 'no extract session',
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
if (opts.skipGenerate) {
|
|
278
|
-
const generateLabel = stepLabel('Categorizing component props');
|
|
279
|
-
progressWriter(`${generateLabel}– skipped (--skip-generate)`);
|
|
280
|
-
steps.push({
|
|
281
|
-
step: 'generate components',
|
|
282
|
-
status: 'skipped',
|
|
283
|
-
reason: '--skip-generate',
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
const generateLabel = stepLabel('Categorizing component props');
|
|
288
|
-
const generateArgs = ['generate', 'components', '--agent', opts.agent];
|
|
289
|
-
if (opts.model)
|
|
290
|
-
generateArgs.push('--model', opts.model);
|
|
291
|
-
if (extractSessionId)
|
|
292
|
-
generateArgs.push('--session', extractSessionId);
|
|
293
|
-
if (opts.dryRun)
|
|
294
|
-
generateArgs.push('--dry-run');
|
|
295
|
-
if (opts.verbose)
|
|
296
|
-
generateArgs.push('--verbose');
|
|
297
|
-
const stepId = createStep(db, sessionId, 'generate components', {
|
|
298
|
-
extractSession: extractSessionId ?? '',
|
|
299
|
-
});
|
|
300
|
-
const t0 = Date.now();
|
|
301
|
-
const r = await runStep(generateArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
302
|
-
const durationMs = Date.now() - t0;
|
|
303
|
-
if (r.exitCode !== 0) {
|
|
304
|
-
updateStep(db, stepId, 'failed', {}, r.stderr);
|
|
305
|
-
progressWriter(`${generateLabel}✗ failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
306
|
-
steps.push({
|
|
307
|
-
step: 'generate components',
|
|
308
|
-
status: 'failed',
|
|
309
|
-
durationMs,
|
|
310
|
-
error: r.stderr,
|
|
311
|
-
});
|
|
312
|
-
db.close();
|
|
313
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
314
|
-
}
|
|
315
|
-
if (opts.dryRun) {
|
|
316
|
-
updateStep(db, stepId, 'complete', { dryRun: 'true' });
|
|
317
|
-
progressWriter(`${generateLabel}✓ prompt printed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
318
|
-
steps.push({
|
|
319
|
-
step: 'generate components',
|
|
320
|
-
status: 'complete',
|
|
321
|
-
durationMs,
|
|
322
|
-
});
|
|
323
|
-
db.close();
|
|
324
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
325
|
-
}
|
|
326
|
-
updateStep(db, stepId, 'complete', {
|
|
327
|
-
extractSession: extractSessionId ?? '',
|
|
328
|
-
});
|
|
329
|
-
progressWriter(`${generateLabel}✓ components stored locally (${(durationMs / 1000).toFixed(1)}s)`);
|
|
330
|
-
steps.push({ step: 'generate components', status: 'complete', durationMs });
|
|
331
|
-
}
|
|
332
|
-
// Block save or push when the accepted set still contains a slot cycle.
|
|
333
|
-
// Skipped under --auto-reject-cycles, which delegates to the push-path
|
|
334
|
-
// retry loop below (reject cycle members, then retry) instead of blocking.
|
|
335
|
-
if (extractSessionId && !opts.autoRejectCycles) {
|
|
336
|
-
const acceptedCycles = (() => {
|
|
337
|
-
try {
|
|
338
|
-
return detectSlotCycles(loadCDFComponents(db, extractSessionId));
|
|
339
|
-
}
|
|
340
|
-
catch {
|
|
341
|
-
return [];
|
|
342
|
-
}
|
|
343
|
-
})();
|
|
344
|
-
if (acceptedCycles.length > 0) {
|
|
345
|
-
const report = formatSlotCycleReport(acceptedCycles);
|
|
346
|
-
process.stderr.write(report.join('\n') + '\n');
|
|
347
|
-
progressWriter('Slot cycle detected. The accepted components contain circular slot references — refusing to save or push.');
|
|
348
|
-
for (const line of report)
|
|
349
|
-
progressWriter(line);
|
|
350
|
-
steps.push({ step: 'cycle gate', status: 'failed', error: report.join('\n') });
|
|
351
|
-
db.close();
|
|
352
|
-
return { session: sessionId, project: projectRoot, steps, cycleError: { report } };
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
if (opts.print) {
|
|
356
|
-
const printLabel = stepLabel('Writing components.json');
|
|
357
|
-
const printArgs = ['print', 'components', '--out', componentsPath];
|
|
358
|
-
if (extractSessionId)
|
|
359
|
-
printArgs.push('--session', extractSessionId);
|
|
360
|
-
const stepId = createStep(db, sessionId, 'print components', {
|
|
361
|
-
out: componentsPath,
|
|
362
|
-
});
|
|
363
|
-
const t0 = Date.now();
|
|
364
|
-
const r = await runStep(printArgs, cliPath, sessionId);
|
|
365
|
-
const durationMs = Date.now() - t0;
|
|
366
|
-
if (r.exitCode !== 0) {
|
|
367
|
-
if (r.stderr)
|
|
368
|
-
process.stderr.write(r.stderr);
|
|
369
|
-
updateStep(db, stepId, 'failed', {}, r.stderr);
|
|
370
|
-
progressWriter(`${printLabel}✗ failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
371
|
-
steps.push({
|
|
372
|
-
step: 'print components',
|
|
373
|
-
status: 'failed',
|
|
374
|
-
durationMs,
|
|
375
|
-
error: r.stderr,
|
|
376
|
-
});
|
|
377
|
-
db.close();
|
|
378
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
379
|
-
}
|
|
380
|
-
updateStep(db, stepId, 'complete', { components: componentsPath });
|
|
381
|
-
progressWriter(`${printLabel}✓ components.json written (${(durationMs / 1000).toFixed(1)}s)`);
|
|
382
|
-
steps.push({ step: 'print components', status: 'complete', durationMs });
|
|
383
|
-
}
|
|
384
|
-
const applyLabelText = opts.spaceId && opts.environmentId
|
|
385
|
-
? `Applying changes to Space: ${opts.spaceId} Environment: ${opts.environmentId}`
|
|
386
|
-
: 'Applying changes to Contentful';
|
|
387
|
-
if (opts.skipApply) {
|
|
388
|
-
const pushLabel = stepLabel(applyLabelText);
|
|
389
|
-
progressWriter(`${pushLabel}– skipped (--skip-apply)`);
|
|
390
|
-
steps.push({
|
|
391
|
-
step: 'apply push',
|
|
392
|
-
status: 'skipped',
|
|
393
|
-
reason: '--skip-apply',
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
const pushLabel = stepLabel(applyLabelText);
|
|
398
|
-
if (!opts.spaceId || !opts.environmentId || !opts.cmaToken) {
|
|
399
|
-
process.stderr.write('Error: --space-id, --environment-id, and --cma-token are required for apply push. Use --skip-apply to skip.\n');
|
|
400
|
-
db.close();
|
|
401
|
-
process.exit(1);
|
|
402
|
-
}
|
|
403
|
-
const pushArgs = [
|
|
404
|
-
'apply',
|
|
405
|
-
'push',
|
|
406
|
-
'--space-id',
|
|
407
|
-
opts.spaceId,
|
|
408
|
-
'--environment-id',
|
|
409
|
-
opts.environmentId,
|
|
410
|
-
'--cma-token',
|
|
411
|
-
opts.cmaToken,
|
|
412
|
-
];
|
|
413
|
-
if (extractSessionId) {
|
|
414
|
-
pushArgs.push('--session', extractSessionId);
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
pushArgs.push('--components', componentsPath);
|
|
418
|
-
}
|
|
419
|
-
if (opts.tokens)
|
|
420
|
-
pushArgs.push('--tokens', opts.tokens);
|
|
421
|
-
if (opts.viewports)
|
|
422
|
-
pushArgs.push('--viewports', opts.viewports);
|
|
423
|
-
if (opts.host)
|
|
424
|
-
pushArgs.push('--host', opts.host);
|
|
425
|
-
if (opts.verbose)
|
|
426
|
-
pushArgs.push('--verbose');
|
|
427
|
-
if (opts.allowDeletions)
|
|
428
|
-
pushArgs.push('--allow-deletions');
|
|
429
|
-
pushArgs.push('--yes');
|
|
430
|
-
const pushStepId = createStep(db, sessionId, 'apply push', {
|
|
431
|
-
components: componentsPath,
|
|
432
|
-
});
|
|
433
|
-
const t0 = Date.now();
|
|
434
|
-
let r = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
435
|
-
const excludedByRetry = [];
|
|
436
|
-
let validationRetryCount = 0;
|
|
437
|
-
while (validationRetryCount < MAX_VALIDATION_RETRIES && isPreviewValidationError(r) && extractSessionId) {
|
|
438
|
-
const offenders = parseOffendingComponentNames(r.stderr + r.stdout);
|
|
439
|
-
if (offenders.length === 0)
|
|
440
|
-
break;
|
|
441
|
-
process.stderr.write(`[retry ${validationRetryCount + 1}/${MAX_VALIDATION_RETRIES}] Preview validation failed — excluding ${offenders.join(', ')} and retrying\n`);
|
|
442
|
-
excludedByRetry.push(...offenders);
|
|
443
|
-
const rejectArgs = [
|
|
444
|
-
'analyze',
|
|
445
|
-
'select',
|
|
446
|
-
'--session',
|
|
447
|
-
extractSessionId,
|
|
448
|
-
'--exclude-components',
|
|
449
|
-
offenders.join(','),
|
|
450
|
-
];
|
|
451
|
-
const rejectResult = await runStep(rejectArgs, cliPath, sessionId);
|
|
452
|
-
if (rejectResult.exitCode !== 0)
|
|
453
|
-
break;
|
|
454
|
-
r = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
455
|
-
validationRetryCount++;
|
|
456
|
-
}
|
|
457
|
-
const durationMs = Date.now() - t0;
|
|
458
|
-
let pushResult = null;
|
|
459
|
-
try {
|
|
460
|
-
pushResult = JSON.parse(r.stdout);
|
|
461
|
-
}
|
|
462
|
-
catch {
|
|
463
|
-
// stdout wasn't JSON — fall back to regex parsing
|
|
464
|
-
}
|
|
465
|
-
const created = pushResult
|
|
466
|
-
? (pushResult.componentTypes?.created ?? 0) + (pushResult.designTokens?.created ?? 0)
|
|
467
|
-
: Number(/(\d+) created/.exec(r.stdout + r.stderr)?.[1] ?? 0);
|
|
468
|
-
const updated = pushResult
|
|
469
|
-
? (pushResult.componentTypes?.updated ?? 0) + (pushResult.designTokens?.updated ?? 0)
|
|
470
|
-
: Number(/(\d+) updated/.exec(r.stdout + r.stderr)?.[1] ?? 0);
|
|
471
|
-
const failed = pushResult
|
|
472
|
-
? (pushResult.componentTypes?.failed ?? 0) + (pushResult.designTokens?.failed ?? 0)
|
|
473
|
-
: Number(/(\d+) failed/.exec(r.stdout + r.stderr)?.[1] ?? 0);
|
|
474
|
-
const totalPushed = created + updated + failed;
|
|
475
|
-
if (isSlotCycleError(r)) {
|
|
476
|
-
const report = extractCycleReport(r.stderr);
|
|
477
|
-
if (opts.autoRejectCycles && extractSessionId) {
|
|
478
|
-
const cycleNames = parseCycleComponentNames(report);
|
|
479
|
-
if (cycleNames.length > 0) {
|
|
480
|
-
process.stderr.write(`[cycle-retry] Slot cycle detected — excluding ${cycleNames.join(', ')} and retrying\n`);
|
|
481
|
-
const rejectArgs = [
|
|
482
|
-
'analyze',
|
|
483
|
-
'select',
|
|
484
|
-
'--session',
|
|
485
|
-
extractSessionId,
|
|
486
|
-
'--exclude-components',
|
|
487
|
-
cycleNames.join(','),
|
|
488
|
-
];
|
|
489
|
-
const rejectResult = await runStep(rejectArgs, cliPath, sessionId);
|
|
490
|
-
if (rejectResult.exitCode === 0) {
|
|
491
|
-
const retryT0 = Date.now();
|
|
492
|
-
const retryR = await runStep(pushArgs, cliPath, sessionId, { FORCE_COLOR: '1' }, true);
|
|
493
|
-
const retryDurationMs = Date.now() - t0 + (Date.now() - retryT0);
|
|
494
|
-
if (isSlotCycleError(retryR)) {
|
|
495
|
-
const retryReport = extractCycleReport(retryR.stderr);
|
|
496
|
-
updateStep(db, pushStepId, 'failed', {}, retryR.stderr);
|
|
497
|
-
progressWriter(`${pushLabel}✗ failed (${(retryDurationMs / 1000).toFixed(1)}s)`);
|
|
498
|
-
progressWriter('Slot cycle detected after auto-reject retry. The manifest still contains circular slot references.');
|
|
499
|
-
for (const line of retryReport)
|
|
500
|
-
progressWriter(line);
|
|
501
|
-
steps.push(buildPushStepResult({
|
|
502
|
-
created,
|
|
503
|
-
updated,
|
|
504
|
-
failed,
|
|
505
|
-
durationMs: retryDurationMs,
|
|
506
|
-
stderr: retryR.stderr,
|
|
507
|
-
excludedByRetry: [...excludedByRetry, ...cycleNames],
|
|
508
|
-
totalFailure: true,
|
|
509
|
-
}));
|
|
510
|
-
db.close();
|
|
511
|
-
return { session: sessionId, project: projectRoot, steps, cycleError: { report: retryReport } };
|
|
512
|
-
}
|
|
513
|
-
if (retryR.exitCode !== 0) {
|
|
514
|
-
updateStep(db, pushStepId, 'failed', {}, retryR.stderr);
|
|
515
|
-
progressWriter(`${pushLabel}✗ failed (${(retryDurationMs / 1000).toFixed(1)}s)`);
|
|
516
|
-
steps.push(buildPushStepResult({
|
|
517
|
-
created,
|
|
518
|
-
updated,
|
|
519
|
-
failed,
|
|
520
|
-
durationMs: retryDurationMs,
|
|
521
|
-
stderr: retryR.stderr,
|
|
522
|
-
excludedByRetry: [...excludedByRetry, ...cycleNames],
|
|
523
|
-
totalFailure: true,
|
|
524
|
-
}));
|
|
525
|
-
db.close();
|
|
526
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
527
|
-
}
|
|
528
|
-
excludedByRetry.push(...cycleNames);
|
|
529
|
-
r = retryR;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
if (isSlotCycleError(r)) {
|
|
534
|
-
updateStep(db, pushStepId, 'failed', {}, r.stderr);
|
|
535
|
-
progressWriter(`${pushLabel}✗ failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
536
|
-
progressWriter('Slot cycle detected. The manifest contains circular slot references that would block the push.');
|
|
537
|
-
for (const line of report)
|
|
538
|
-
progressWriter(line);
|
|
539
|
-
steps.push(buildPushStepResult({
|
|
540
|
-
created,
|
|
541
|
-
updated,
|
|
542
|
-
failed,
|
|
543
|
-
durationMs,
|
|
544
|
-
stderr: r.stderr,
|
|
545
|
-
excludedByRetry,
|
|
546
|
-
totalFailure: true,
|
|
547
|
-
}));
|
|
548
|
-
db.close();
|
|
549
|
-
return { session: sessionId, project: projectRoot, steps, cycleError: { report } };
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
if (r.exitCode !== 0 && (totalPushed === 0 || failed === totalPushed)) {
|
|
553
|
-
// Total failure — nothing was pushed
|
|
554
|
-
updateStep(db, pushStepId, 'failed', {}, r.stderr);
|
|
555
|
-
progressWriter(`${pushLabel}✗ failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
556
|
-
steps.push(buildPushStepResult({
|
|
557
|
-
created,
|
|
558
|
-
updated,
|
|
559
|
-
failed,
|
|
560
|
-
durationMs,
|
|
561
|
-
stderr: r.stderr,
|
|
562
|
-
excludedByRetry,
|
|
563
|
-
totalFailure: true,
|
|
564
|
-
}));
|
|
565
|
-
db.close();
|
|
566
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
567
|
-
}
|
|
568
|
-
const stepResult = buildPushStepResult({
|
|
569
|
-
created,
|
|
570
|
-
updated,
|
|
571
|
-
failed,
|
|
572
|
-
durationMs,
|
|
573
|
-
stderr: r.stderr,
|
|
574
|
-
excludedByRetry,
|
|
575
|
-
});
|
|
576
|
-
updateStep(db, pushStepId, stepResult.status === 'complete' ? 'complete' : 'failed', {
|
|
577
|
-
components: componentsPath,
|
|
578
|
-
});
|
|
579
|
-
const statusIcon = failed > 0 ? '⚠' : '✓';
|
|
580
|
-
progressWriter(`${pushLabel}${statusIcon} ${created} created, ${updated} updated, ${failed} failed (${(durationMs / 1000).toFixed(1)}s)`);
|
|
581
|
-
steps.push(stepResult);
|
|
582
|
-
}
|
|
583
|
-
progressWriter('');
|
|
584
|
-
progressWriter(`Pipeline complete. Session: ${sessionId}`);
|
|
585
|
-
if (opts.spaceId && opts.environmentId && !opts.skipApply) {
|
|
586
|
-
const viewUrl = buildPostPushUrl({
|
|
587
|
-
host: opts.host ?? 'api.contentful.com',
|
|
588
|
-
spaceId: opts.spaceId,
|
|
589
|
-
environmentId: opts.environmentId,
|
|
590
|
-
});
|
|
591
|
-
const tokensUrl = buildPostPushUrl({
|
|
592
|
-
host: opts.host ?? 'api.contentful.com',
|
|
593
|
-
spaceId: opts.spaceId,
|
|
594
|
-
environmentId: opts.environmentId,
|
|
595
|
-
view: 'design_tokens',
|
|
596
|
-
});
|
|
597
|
-
progressWriter('');
|
|
598
|
-
progressWriter(`View your design system: ${viewUrl}`);
|
|
599
|
-
progressWriter(`View your design tokens: ${tokensUrl}`);
|
|
600
|
-
}
|
|
601
|
-
db.close();
|
|
602
|
-
return { session: sessionId, project: projectRoot, steps };
|
|
603
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'node:path';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
/**
|
|
4
|
-
* Expands a leading `~` to the user's home directory.
|
|
5
|
-
* Exported separately so it can be unit-tested and reused.
|
|
6
|
-
*/
|
|
7
|
-
export function expandTilde(input) {
|
|
8
|
-
if (input === '~' || input.startsWith('~/') || input.startsWith('~\\')) {
|
|
9
|
-
return homedir() + input.slice(1);
|
|
10
|
-
}
|
|
11
|
-
return input;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Normalizes a user-entered path to an absolute path, handling all common
|
|
15
|
-
* terminal path styles:
|
|
16
|
-
* - surrounding quotes ("~/path" or '~/path') → stripped
|
|
17
|
-
* - tilde prefix (~/projects/mylib) → expanded to $HOME
|
|
18
|
-
* - relative paths (../mylib, ./src, mylib) → resolved against CWD
|
|
19
|
-
* - absolute paths (/Users/ryun/projects/mylib) → passed through
|
|
20
|
-
* - trailing slashes, repeated slashes → normalized by path.resolve
|
|
21
|
-
*/
|
|
22
|
-
export function normalizePath(input) {
|
|
23
|
-
let p = input.trim();
|
|
24
|
-
// strip surrounding single or double quotes
|
|
25
|
-
if (p.length >= 2 && ((p.startsWith('"') && p.endsWith('"')) || (p.startsWith("'") && p.endsWith("'")))) {
|
|
26
|
-
p = p.slice(1, -1);
|
|
27
|
-
}
|
|
28
|
-
p = expandTilde(p);
|
|
29
|
-
return resolve(p);
|
|
30
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// Route a resolved RunPickerSelection into replayRun / modifyRun / picker-push.
|
|
2
|
-
// Extracted from command.ts so the dispatch decision is testable without an
|
|
3
|
-
// Ink runtime and so the picker callback in command.ts is a simple
|
|
4
|
-
// state-capture (no process.exit shenanigans that would kill the process
|
|
5
|
-
// before dispatch runs).
|
|
6
|
-
export async function dispatchPickerSelection(selection, opts, deps) {
|
|
7
|
-
if (selection.action === 'push' && selection.runId) {
|
|
8
|
-
// Interactive TTY → mount the wizard's preview + push UX. Non-interactive
|
|
9
|
-
// (CI / scripted / non-TTY) → keep the headless shell-out via replayRun
|
|
10
|
-
// that `experiences import --push-from-run <id>` relies on.
|
|
11
|
-
if (opts.interactive !== false && deps.pickerPushRun) {
|
|
12
|
-
await deps.pickerPushRun({
|
|
13
|
-
runIdOrPath: selection.runId,
|
|
14
|
-
...(opts.spaceId ? { spaceId: opts.spaceId } : {}),
|
|
15
|
-
...(opts.environmentId ? { environmentId: opts.environmentId } : {}),
|
|
16
|
-
...(opts.cmaToken ? { cmaToken: opts.cmaToken } : {}),
|
|
17
|
-
...(opts.host ? { host: opts.host } : {}),
|
|
18
|
-
...(opts.force ? { force: true } : {}),
|
|
19
|
-
});
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
await deps.replayRun({
|
|
23
|
-
runIdOrPath: selection.runId,
|
|
24
|
-
...(opts.spaceId ? { spaceId: opts.spaceId } : {}),
|
|
25
|
-
...(opts.environmentId ? { environmentId: opts.environmentId } : {}),
|
|
26
|
-
...(opts.cmaToken ? { cmaToken: opts.cmaToken } : {}),
|
|
27
|
-
...(opts.host ? { host: opts.host } : {}),
|
|
28
|
-
...(opts.interactive !== undefined ? { interactive: opts.interactive } : {}),
|
|
29
|
-
...(opts.force ? { force: true } : {}),
|
|
30
|
-
});
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (selection.action === 'modify' && selection.runId) {
|
|
34
|
-
await deps.modifyRun({
|
|
35
|
-
runIdOrPath: selection.runId,
|
|
36
|
-
...(opts.outDir ? { outDir: opts.outDir } : {}),
|
|
37
|
-
...(opts.overwrite ? { overwrite: true } : {}),
|
|
38
|
-
...(opts.saveAsNew ? { saveAsNew: true } : {}),
|
|
39
|
-
...(opts.force ? { force: true } : {}),
|
|
40
|
-
});
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
// action === 'new' → no-op; the wizard already advanced past the picker.
|
|
44
|
-
}
|