@contentful/experience-design-system-cli 2.23.2-dev-build-8b2cfc9.0 → 2.23.2-dev-build-09d87bb.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 +2 -24
- package/dist/package.json +1 -2
- package/dist/src/analyze/command.js +0 -4
- package/dist/src/analyze/select/tui/App.js +4 -1
- package/dist/src/apply/api-client.d.ts +5 -5
- package/dist/src/apply/api-client.js +8 -18
- package/dist/src/apply/command.js +32 -32
- package/dist/src/apply/preview-utils.d.ts +5 -1
- package/dist/src/apply/preview-utils.js +5 -1
- package/dist/src/apply/tui/ServerApplyView.d.ts +6 -3
- package/dist/src/apply/tui/ServerApplyView.js +15 -6
- package/dist/src/apply/tui/ServerPreviewView.d.ts +2 -1
- package/dist/src/apply/tui/ServerPreviewView.js +3 -3
- package/dist/src/import/command.js +6 -1
- package/dist/src/import/orchestrator.d.ts +1 -0
- package/dist/src/import/orchestrator.js +3 -6
- package/dist/src/import/tui/WizardApp.d.ts +2 -1
- package/dist/src/import/tui/WizardApp.js +8 -8
- package/dist/src/import/tui/final-review-host.d.ts +2 -1
- package/dist/src/import/tui/final-review-host.js +2 -2
- package/dist/src/import/tui/runLivePreview.d.ts +3 -0
- package/dist/src/import/tui/runLivePreview.js +4 -1
- package/dist/src/import/tui/steps/GenerateReviewStep.d.ts +2 -1
- package/dist/src/import/tui/steps/GenerateReviewStep.js +3 -3
- package/dist/src/import/tui/steps/WizardPreviewStep.d.ts +6 -2
- package/dist/src/import/tui/steps/WizardPreviewStep.js +12 -3
- package/dist/src/import/tui/useFinalizePreview.d.ts +2 -0
- package/dist/src/import/tui/useFinalizePreview.js +0 -0
- package/dist/src/import/tui/useLivePreview.d.ts +2 -0
- package/dist/src/import/tui/useLivePreview.js +1 -0
- package/dist/src/index.js +1 -5
- package/dist/src/lib/command-options.d.ts +1 -0
- package/dist/src/lib/command-options.js +3 -0
- package/dist/src/program.js +1 -8
- package/dist/src/runs/modify-launcher.d.ts +2 -0
- package/dist/src/runs/modify-launcher.js +2 -0
- package/dist/src/runs/push-helpers.d.ts +1 -0
- package/dist/src/runs/push-helpers.js +3 -0
- package/dist/src/runs/replay-helpers.d.ts +4 -0
- package/dist/src/runs/replay-helpers.js +3 -0
- package/package.json +5 -6
- package/dist/src/analytics/apply.d.ts +0 -6
- package/dist/src/analytics/apply.js +0 -30
- package/dist/src/analytics/client.d.ts +0 -3
- package/dist/src/analytics/client.js +0 -39
- package/dist/src/analytics/index.d.ts +0 -6
- package/dist/src/analytics/index.js +0 -5
- package/dist/src/analytics/normalize.d.ts +0 -3
- package/dist/src/analytics/normalize.js +0 -17
- package/dist/src/analytics/os.d.ts +0 -2
- package/dist/src/analytics/os.js +0 -13
- package/dist/src/analytics/tracker.d.ts +0 -19
- package/dist/src/analytics/tracker.js +0 -157
- package/dist/src/analytics/types.d.ts +0 -29
- package/dist/src/analytics/types.js +0 -1
|
@@ -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, allowDeletions = false, } = {}) {
|
|
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, allowDeletions);
|
|
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, allowDeletions);
|
|
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, preview) => {
|
|
949
|
+
const runPush = async (manifest, spaceId, environmentId, cmaToken, host, acknowledgeBreakingChanges, allowDeletions, 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, acknowledgeBreakingChanges);
|
|
989
|
+
let operation = await client.applyImport(manifest, { acknowledgeBreakingChanges, allowDeletions });
|
|
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, onFinalize: (accepted, rejected, unresolved) => {
|
|
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, allowDeletions: allowDeletions, 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, onConfirm: (acknowledge) => {
|
|
1609
|
-
void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge, state.serverPreview);
|
|
1608
|
+
return (_jsx(WizardPreviewStep, { preview: state.serverPreview, spaceId: state.spaceId, environmentId: state.environmentId, stepNumber: totalSteps, totalSteps: totalSteps, allowDeletions: allowDeletions, onConfirm: (acknowledge, deleteMissing) => {
|
|
1609
|
+
void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge, deleteMissing, state.serverPreview);
|
|
1610
1610
|
}, ...(editableComponentCount > 0 ? { onEdit: () => void runEditFromPreview() } : {}), onSaveFiles: () => {
|
|
1611
1611
|
void startSaveFlow();
|
|
1612
1612
|
}, onQuit: () => process.exit(0) }));
|
|
@@ -14,5 +14,6 @@ export type FinalReviewHostProps = {
|
|
|
14
14
|
host?: string;
|
|
15
15
|
tokensPath?: string;
|
|
16
16
|
initialFinalizeError?: string | null;
|
|
17
|
+
allowDeletions?: boolean;
|
|
17
18
|
};
|
|
18
|
-
export declare function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, }: FinalReviewHostProps): React.ReactElement;
|
|
19
|
+
export declare function FinalReviewHost({ extractSessionId, generatedCount, autoAccept, compositionMode, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, allowDeletions, }: 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, allowDeletions, }) {
|
|
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, ...(compositionMode !== 'atomic' ? { allowDeletions } : {}) }));
|
|
19
19
|
}
|
|
20
20
|
function FinalReviewAutoAccept({ generatedCount, onFinalize, }) {
|
|
21
21
|
React.useEffect(() => {
|
|
@@ -26,6 +26,9 @@ 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;
|
|
29
32
|
};
|
|
30
33
|
/**
|
|
31
34
|
* Pure async helper used by `useLivePreview` to re-fire `previewImport` after a
|
|
@@ -60,7 +60,10 @@ export async function runLivePreview(opts) {
|
|
|
60
60
|
timeoutHandle = setTimeout(() => reject(new TimeoutError()), timeoutMs);
|
|
61
61
|
});
|
|
62
62
|
try {
|
|
63
|
-
const response = (await Promise.race([
|
|
63
|
+
const response = (await Promise.race([
|
|
64
|
+
client.previewImport(manifest, opts.allowDeletions === true),
|
|
65
|
+
timeoutPromise,
|
|
66
|
+
]));
|
|
64
67
|
if (process.env['EDS_VERBOSE']) {
|
|
65
68
|
const durationMs = Date.now() - startedAt;
|
|
66
69
|
try {
|
|
@@ -11,6 +11,7 @@ type GenerateReviewStepProps = {
|
|
|
11
11
|
host?: string;
|
|
12
12
|
tokensPath?: string;
|
|
13
13
|
initialFinalizeError?: string | null;
|
|
14
|
+
allowDeletions?: boolean;
|
|
14
15
|
};
|
|
15
16
|
export declare function sortComponentsForSidebar<T extends {
|
|
16
17
|
key: string;
|
|
@@ -33,4 +34,4 @@ export interface BreakingRow {
|
|
|
33
34
|
}
|
|
34
35
|
export declare function buildBreakingRows(breakingChanges: BreakingComponent[]): BreakingRow[];
|
|
35
36
|
export declare function deriveBreakingChanges(response: ServerPreviewResponse): BreakingComponent[];
|
|
36
|
-
export declare function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, }: GenerateReviewStepProps): React.ReactElement;
|
|
37
|
+
export declare function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, livePreview, spaceId, environmentId, cmaToken, host, tokensPath, initialFinalizeError, allowDeletions, }: 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, allowDeletions = false, }) {
|
|
178
178
|
const { stdout } = useStdout();
|
|
179
179
|
const terminalWidth = stdout?.columns ?? 80;
|
|
180
180
|
const [components, setComponents] = useState([]);
|
|
@@ -271,9 +271,8 @@ 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).
|
|
276
274
|
deleteAllComponents: acceptedCountForPreview === 0,
|
|
275
|
+
allowDeletions,
|
|
277
276
|
});
|
|
278
277
|
const SPINNER_FRAMES = '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏';
|
|
279
278
|
const [spinnerTick, setSpinnerTick] = useState(0);
|
|
@@ -352,6 +351,7 @@ export function GenerateReviewStep({ extractSessionId, onFinalize, onQuit, liveP
|
|
|
352
351
|
cmaToken,
|
|
353
352
|
host,
|
|
354
353
|
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,10 +12,14 @@ type WizardPreviewStepProps = {
|
|
|
12
12
|
environmentId: string;
|
|
13
13
|
stepNumber: number;
|
|
14
14
|
totalSteps: number;
|
|
15
|
-
|
|
15
|
+
/** The value the preview was actually fetched with — not a hint. When
|
|
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;
|
|
16
20
|
onEdit?: () => void;
|
|
17
21
|
onSaveFiles?: () => void;
|
|
18
22
|
onQuit: () => void;
|
|
19
23
|
};
|
|
20
|
-
export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }: WizardPreviewStepProps): React.ReactElement;
|
|
24
|
+
export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, allowDeletions: fetchedAllowDeletions, onConfirm, onEdit, onSaveFiles, onQuit, }: WizardPreviewStepProps): React.ReactElement;
|
|
21
25
|
export {};
|
|
@@ -89,10 +89,14 @@ export function buildPreviewDiffLines(preview) {
|
|
|
89
89
|
}
|
|
90
90
|
return lines;
|
|
91
91
|
}
|
|
92
|
-
export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }) {
|
|
92
|
+
export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, allowDeletions: fetchedAllowDeletions = false, 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);
|
|
96
100
|
const { stdout } = useStdout();
|
|
97
101
|
const terminalRows = stdout?.rows ?? 40;
|
|
98
102
|
const viewportHeight = Math.max(terminalRows - 14, 10);
|
|
@@ -105,9 +109,14 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
|
|
|
105
109
|
}));
|
|
106
110
|
}, [diffExpanded, preview]);
|
|
107
111
|
const maxScroll = Math.max(0, allDiffLines.length - viewportHeight);
|
|
112
|
+
const removedCount = preview.components.removed.length + preview.tokens.removed.length;
|
|
108
113
|
useImmediateInput((input, key) => {
|
|
109
114
|
if (key.return) {
|
|
110
|
-
onConfirm(breakingWithImpact);
|
|
115
|
+
onConfirm(breakingWithImpact, allowDeletions);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if ((input === 'x' || input === 'X') && fetchedAllowDeletions && removedCount > 0) {
|
|
119
|
+
setAllowDeletions((prev) => !prev);
|
|
111
120
|
return;
|
|
112
121
|
}
|
|
113
122
|
if (input === 'd' || input === 'D') {
|
|
@@ -156,5 +165,5 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
|
|
|
156
165
|
})] })), 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) => {
|
|
157
166
|
const isBreaking = item.changeClassification?.classification === 'breaking';
|
|
158
167
|
return (_jsxs(Text, { color: isBreaking ? PALETTE.error : PALETTE.warning, children: [' ', isBreaking ? '⚠' : '~', " ", item.current.name] }, `chg-${i}`));
|
|
159
|
-
})] })), components.removed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.error, children:
|
|
168
|
+
})] })), components.removed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: allowDeletions ? PALETTE.error : PALETTE.warning, children: allowDeletions ? ' ✗' : ' ⊘' }), _jsxs(Text, { children: [components.removed.length, " will be ", allowDeletions ? 'deleted' : 'skipped'] })] }), components.removed.map((item, i) => (_jsxs(Text, { color: allowDeletions ? PALETTE.error : PALETTE.warning, dimColor: !allowDeletions, children: [' ', allowDeletions ? '✗' : '⊘', " ", 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: allowDeletions ? PALETTE.error : PALETTE.warning, children: allowDeletions ? ' ✗' : ' ⊘' }), _jsxs(Text, { children: [tokens.removed.length, " will be ", allowDeletions ? 'deleted' : 'skipped'] })] })), 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." })), !fetchedAllowDeletions && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.warning, children: " \u2298" }), _jsx(Text, { children: "Deletions are hidden by default \u2014 rerun with --allow-deletions to see them." })] })), _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." }) })), allowDeletions && removedCount > 0 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: PALETTE.error, bold: true, children: ["\u26A0 ", removedCount, " missing ", removedCount === 1 ? 'entity' : 'entities', " will be permanently deleted. Press Enter to confirm."] }) })), _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" }), fetchedAllowDeletions && removedCount > 0 && (_jsxs(Text, { dimColor: true, children: ["[x] ", allowDeletions ? '[✓]' : '[ ]', " Allow deletions"] })), _jsx(Text, { dimColor: true, children: "[q] Cancel" })] })] }));
|
|
160
169
|
}
|
|
@@ -11,6 +11,8 @@ 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;
|
|
14
16
|
};
|
|
15
17
|
export type UseFinalizePreviewReturn = {
|
|
16
18
|
status: FinalizePreviewStatus;
|
|
Binary file
|
|
@@ -12,6 +12,8 @@ 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;
|
|
15
17
|
};
|
|
16
18
|
export type LivePreviewStatus = 'idle' | 'running';
|
|
17
19
|
export type UseLivePreviewReturn = {
|
|
@@ -82,6 +82,7 @@ export function useLivePreview(opts) {
|
|
|
82
82
|
host: current.host,
|
|
83
83
|
generation,
|
|
84
84
|
deleteAllComponents: current.deleteAllComponents === true,
|
|
85
|
+
allowDeletions: current.allowDeletions === true,
|
|
85
86
|
});
|
|
86
87
|
// Discard stale responses (generation tag).
|
|
87
88
|
if (result.generation !== latestRef.current)
|
package/dist/src/index.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { createProgram } from './program.js';
|
|
2
|
-
import { failActiveCommand } from './analytics/index.js';
|
|
3
2
|
createProgram()
|
|
4
3
|
.parseAsync()
|
|
5
|
-
.catch(
|
|
6
|
-
await failActiveCommand({
|
|
7
|
-
error_name: err instanceof Error ? err.name : 'Error',
|
|
8
|
-
});
|
|
4
|
+
.catch((err) => {
|
|
9
5
|
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
10
6
|
process.exit(1);
|
|
11
7
|
});
|
|
@@ -3,3 +3,4 @@ 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,3 +25,6 @@ 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
|
+
}
|
package/dist/src/program.js
CHANGED
|
@@ -12,7 +12,6 @@ import { registerImportCommand } from './import/command.js';
|
|
|
12
12
|
import { registerSetupCommand } from './setup/command.js';
|
|
13
13
|
import { registerRunsCommand } from './runs/ls-command.js';
|
|
14
14
|
import { beginCommand } from './lib/debug-preamble.js';
|
|
15
|
-
import { completeActiveCommand, noteCommandStart, registerAnalyticsExitHook } from './analytics/index.js';
|
|
16
15
|
const require = createRequire(import.meta.url);
|
|
17
16
|
const pkg = require('../package.json');
|
|
18
17
|
/**
|
|
@@ -74,7 +73,6 @@ export function createProgram() {
|
|
|
74
73
|
// and a bright-green "debug logs at <path>" banner is printed to stderr.
|
|
75
74
|
program.option('--debug', 'Write a JSONL trace of every decision to ~/.contentful/experience-design-system-cli/debug/');
|
|
76
75
|
program.option('--no-debug', 'Force debug logging off (overrides EDSI_DEBUG and persisted setup preference)');
|
|
77
|
-
registerAnalyticsExitHook();
|
|
78
76
|
program.hook('preAction', async (_thisCommand, actionCommand) => {
|
|
79
77
|
// Merge opts from actionCommand and all ancestors — root-level --debug
|
|
80
78
|
// set alongside a subcommand ends up on the root command's opts, not the
|
|
@@ -91,12 +89,7 @@ export function createProgram() {
|
|
|
91
89
|
const chain = [];
|
|
92
90
|
for (let c = actionCommand; c && c.parent; c = c.parent)
|
|
93
91
|
chain.unshift(c.name());
|
|
94
|
-
|
|
95
|
-
noteCommandStart(commandChain);
|
|
96
|
-
await beginCommand(commandChain, { ...(debug !== undefined ? { debug } : {}) });
|
|
97
|
-
});
|
|
98
|
-
program.hook('postAction', async () => {
|
|
99
|
-
await completeActiveCommand();
|
|
92
|
+
await beginCommand(chain.join(' ') || actionCommand.name(), { ...(debug !== undefined ? { debug } : {}) });
|
|
100
93
|
});
|
|
101
94
|
return program;
|
|
102
95
|
}
|
|
@@ -26,5 +26,7 @@ export type ModifyLauncherInput = {
|
|
|
26
26
|
initialHost?: string;
|
|
27
27
|
/** Pre-fill CMA token (from credentials.json / env). */
|
|
28
28
|
initialCmaToken?: string;
|
|
29
|
+
/** From `--allow-deletions` flag. Forwarded to wizard's push step. */
|
|
30
|
+
allowDeletions?: boolean;
|
|
29
31
|
};
|
|
30
32
|
export declare function launchModifyWizard(input: ModifyLauncherInput): Promise<void>;
|
|
@@ -35,6 +35,8 @@ export async function launchModifyWizard(input) {
|
|
|
35
35
|
props.initialHost = input.initialHost;
|
|
36
36
|
if (input.initialCmaToken)
|
|
37
37
|
props.initialCmaToken = input.initialCmaToken;
|
|
38
|
+
if (input.allowDeletions !== undefined)
|
|
39
|
+
props.allowDeletions = input.allowDeletions;
|
|
38
40
|
const { waitUntilExit } = render(createElement(WizardApp, props));
|
|
39
41
|
await waitUntilExit();
|
|
40
42
|
}
|
|
@@ -16,6 +16,8 @@ export type ReplayRunOptions = {
|
|
|
16
16
|
interactive?: boolean;
|
|
17
17
|
/** When true, bypass the source/saved-file staleness check. */
|
|
18
18
|
force?: boolean;
|
|
19
|
+
/** From `--allow-deletions` flag. Forwarded verbatim to the pushed session's apply request. */
|
|
20
|
+
allowDeletions?: boolean;
|
|
19
21
|
/**
|
|
20
22
|
* Test seam: replace the interactive prompt with a deterministic resolver.
|
|
21
23
|
* The CLI surface never sets this; only used by tests.
|
|
@@ -57,6 +59,8 @@ export type ModifyRunOptions = {
|
|
|
57
59
|
outDir?: string;
|
|
58
60
|
/** When true, bypass the source/saved-file staleness check. */
|
|
59
61
|
force?: boolean;
|
|
62
|
+
/** From `--allow-deletions` flag. Forwarded through the modify wizard's push step. */
|
|
63
|
+
allowDeletions?: boolean;
|
|
60
64
|
};
|
|
61
65
|
/**
|
|
62
66
|
* Re-open the wizard with a prior run's extract/generate session pre-populated
|
|
@@ -83,6 +83,7 @@ export async function replayRun(opts) {
|
|
|
83
83
|
environmentId,
|
|
84
84
|
cmaToken,
|
|
85
85
|
...(host ? { host } : {}),
|
|
86
|
+
...(opts.allowDeletions ? { allowDeletions: true } : {}),
|
|
86
87
|
});
|
|
87
88
|
if (!result.ok) {
|
|
88
89
|
throw new Error(result.error);
|
|
@@ -98,6 +99,7 @@ export async function replayRun(opts) {
|
|
|
98
99
|
environmentId,
|
|
99
100
|
cmaToken,
|
|
100
101
|
...(host ? { host } : {}),
|
|
102
|
+
...(opts.allowDeletions ? { allowDeletions: true } : {}),
|
|
101
103
|
});
|
|
102
104
|
if (!tokenResult.ok) {
|
|
103
105
|
throw new Error(tokenResult.error);
|
|
@@ -157,5 +159,6 @@ export async function modifyRun(opts) {
|
|
|
157
159
|
...(mergedEnvironmentId ? { initialEnvironmentId: mergedEnvironmentId } : {}),
|
|
158
160
|
...(mergedHost ? { initialHost: mergedHost } : {}),
|
|
159
161
|
...(mergedCmaToken ? { initialCmaToken: mergedCmaToken } : {}),
|
|
162
|
+
...(opts.allowDeletions !== undefined ? { allowDeletions: opts.allowDeletions } : {}),
|
|
160
163
|
});
|
|
161
164
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.23.2-dev-build-
|
|
3
|
+
"version": "2.23.2-dev-build-09d87bb.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -28,16 +28,15 @@
|
|
|
28
28
|
"prompts/"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@segment/analytics-node": "^3.0.0",
|
|
32
31
|
"commander": "^13.1.0",
|
|
33
32
|
"ink": "^4.4.1",
|
|
34
33
|
"react": "^18.3.1",
|
|
35
34
|
"react-devtools-core": "^4.19.1",
|
|
36
35
|
"react-dom": "^18.3.1",
|
|
37
|
-
"@contentful/experience-design-system-client": "2.23.2-dev-build-
|
|
38
|
-
"@contentful/experience-design-system-
|
|
39
|
-
"@contentful/experience-design-system-
|
|
40
|
-
"@contentful/experience-design-system-
|
|
36
|
+
"@contentful/experience-design-system-client": "2.23.2-dev-build-09d87bb.0",
|
|
37
|
+
"@contentful/experience-design-system-generation": "2.23.2-dev-build-09d87bb.0",
|
|
38
|
+
"@contentful/experience-design-system-types": "2.23.2-dev-build-09d87bb.0",
|
|
39
|
+
"@contentful/experience-design-system-extraction": "2.23.2-dev-build-09d87bb.0"
|
|
41
40
|
},
|
|
42
41
|
"devDependencies": {
|
|
43
42
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ApplyOperationResponse } from '@contentful/experience-design-system-types';
|
|
2
|
-
import type { ImportApiClient } from '../apply/api-client.js';
|
|
3
|
-
/** Record apply/preview API outcomes on the active command. */
|
|
4
|
-
export declare function recordApplyOutcome(client: ImportApiClient, spaceId: string, environmentId: string, operation: ApplyOperationResponse): void;
|
|
5
|
-
/** Record Contentful target context without an apply operation (e.g. preview-only). */
|
|
6
|
-
export declare function recordContentfulContext(client: ImportApiClient, spaceId: string, environmentId: string): void;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { enrichCommandResult, setCommandContext } from './tracker.js';
|
|
2
|
-
function countWriteResult(items, entityType) {
|
|
3
|
-
const subset = items.filter((item) => item.entityType === entityType);
|
|
4
|
-
return {
|
|
5
|
-
created_count: subset.filter((item) => item.action === 'create' && item.status === 'succeeded').length,
|
|
6
|
-
updated_count: subset.filter((item) => item.action === 'update' && item.status === 'succeeded').length,
|
|
7
|
-
failed_count: subset.filter((item) => item.status === 'failed').length,
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
/** Record apply/preview API outcomes on the active command. */
|
|
11
|
-
export function recordApplyOutcome(client, spaceId, environmentId, operation) {
|
|
12
|
-
setCommandContext({
|
|
13
|
-
space_key: spaceId,
|
|
14
|
-
environment_key: environmentId,
|
|
15
|
-
x_contentful_request_id: client.getLastRequestId(),
|
|
16
|
-
});
|
|
17
|
-
enrichCommandResult({
|
|
18
|
-
dsi_operation_id: operation.sys.id,
|
|
19
|
-
component_type_result: countWriteResult(operation.items ?? [], 'ComponentType'),
|
|
20
|
-
design_token_result: countWriteResult(operation.items ?? [], 'DesignToken'),
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
/** Record Contentful target context without an apply operation (e.g. preview-only). */
|
|
24
|
-
export function recordContentfulContext(client, spaceId, environmentId) {
|
|
25
|
-
setCommandContext({
|
|
26
|
-
space_key: spaceId,
|
|
27
|
-
environment_key: environmentId,
|
|
28
|
-
x_contentful_request_id: client.getLastRequestId(),
|
|
29
|
-
});
|
|
30
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'node:module';
|
|
2
|
-
import { Analytics } from '@segment/analytics-node';
|
|
3
|
-
const require = createRequire(import.meta.url);
|
|
4
|
-
const pkg = require('../../package.json');
|
|
5
|
-
// Anonymous usage telemetry for the CLI. Disabled when DISABLE_ANALYTICS is set
|
|
6
|
-
// or when no write key is configured. Never blocks command execution.
|
|
7
|
-
export function cliVersion() {
|
|
8
|
-
return pkg.version;
|
|
9
|
-
}
|
|
10
|
-
export function analyticsEnabled() {
|
|
11
|
-
return !process.env.DISABLE_ANALYTICS && Boolean(resolveWriteKey());
|
|
12
|
-
}
|
|
13
|
-
function resolveWriteKey() {
|
|
14
|
-
const key = (process.env.SEGMENT_WRITE_KEY ?? '').trim();
|
|
15
|
-
return key.length > 0 ? key : undefined;
|
|
16
|
-
}
|
|
17
|
-
export async function trackEvent(event, properties, anonymousId) {
|
|
18
|
-
if (!analyticsEnabled())
|
|
19
|
-
return;
|
|
20
|
-
const writeKey = resolveWriteKey();
|
|
21
|
-
if (!writeKey)
|
|
22
|
-
return;
|
|
23
|
-
try {
|
|
24
|
-
const client = new Analytics({ writeKey });
|
|
25
|
-
client.on('error', () => {
|
|
26
|
-
/* never block the CLI on telemetry errors */
|
|
27
|
-
});
|
|
28
|
-
client.track({
|
|
29
|
-
event,
|
|
30
|
-
properties,
|
|
31
|
-
anonymousId,
|
|
32
|
-
timestamp: new Date(),
|
|
33
|
-
});
|
|
34
|
-
await client.closeAndFlush();
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// Telemetry must never affect CLI exit codes or output.
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { analyticsEnabled, cliVersion, trackEvent } from './client.js';
|
|
2
|
-
export { normalizeCommand } from './normalize.js';
|
|
3
|
-
export { getOsName } from './os.js';
|
|
4
|
-
export { bindAnalyticsSession, bindAnalyticsSessionId, completeActiveCommand, emitSessionStarted, enrichCommandResult, failActiveCommand, getBoundSessionId, noteCommandStart, registerAnalyticsExitHook, resetAnalyticsStateForTests, setCommandContext, } from './tracker.js';
|
|
5
|
-
export { recordApplyOutcome, recordContentfulContext } from './apply.js';
|
|
6
|
-
export type { CommandCompletion, CommandContext, CommandFailure, DsiCliCommand, EntryCommand, OsName, WriteResult, } from './types.js';
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { analyticsEnabled, cliVersion, trackEvent } from './client.js';
|
|
2
|
-
export { normalizeCommand } from './normalize.js';
|
|
3
|
-
export { getOsName } from './os.js';
|
|
4
|
-
export { bindAnalyticsSession, bindAnalyticsSessionId, completeActiveCommand, emitSessionStarted, enrichCommandResult, failActiveCommand, getBoundSessionId, noteCommandStart, registerAnalyticsExitHook, resetAnalyticsStateForTests, setCommandContext, } from './tracker.js';
|
|
5
|
-
export { recordApplyOutcome, recordContentfulContext } from './apply.js';
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const COMMAND_MAP = {
|
|
2
|
-
'analyze extract': 'analyze_extract',
|
|
3
|
-
'analyze select': 'analyze_select',
|
|
4
|
-
'generate components': 'generate_components',
|
|
5
|
-
'generate tokens': 'generate_tokens',
|
|
6
|
-
'generate edit': 'generate_edit',
|
|
7
|
-
'apply preview': 'apply_preview',
|
|
8
|
-
'apply select': 'apply_select',
|
|
9
|
-
'apply push': 'apply_push',
|
|
10
|
-
'print components': 'print_components',
|
|
11
|
-
'print tokens': 'print_tokens',
|
|
12
|
-
import: 'import',
|
|
13
|
-
};
|
|
14
|
-
/** Map a Commander command chain (e.g. "apply push") to a tracked command id, if any. */
|
|
15
|
-
export function normalizeCommand(commandChain) {
|
|
16
|
-
return COMMAND_MAP[commandChain];
|
|
17
|
-
}
|
package/dist/src/analytics/os.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const OS_NAMES = {
|
|
2
|
-
android: 'Android',
|
|
3
|
-
aix: 'Linux',
|
|
4
|
-
darwin: 'macOS',
|
|
5
|
-
freebsd: 'Linux',
|
|
6
|
-
linux: 'Linux',
|
|
7
|
-
openbsd: 'Linux',
|
|
8
|
-
sunos: 'Linux',
|
|
9
|
-
win32: 'Windows',
|
|
10
|
-
};
|
|
11
|
-
export function getOsName() {
|
|
12
|
-
return OS_NAMES[process.platform] ?? 'other';
|
|
13
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { CommandCompletion, CommandContext, CommandFailure, EntryCommand } from './types.js';
|
|
2
|
-
/** Record the start of a tracked command. Invoked is deferred until a session is bound. */
|
|
3
|
-
export declare function noteCommandStart(commandChain: string): void;
|
|
4
|
-
/** Bind a session id, minting one when the command has no pipeline session. */
|
|
5
|
-
export declare function bindAnalyticsSessionId(sessionId: string | undefined, context?: CommandContext): Promise<string>;
|
|
6
|
-
/** Attach Contentful target context for the active command. */
|
|
7
|
-
export declare function setCommandContext(context: CommandContext): void;
|
|
8
|
-
/** Merge optional completion fields before the terminal event fires. */
|
|
9
|
-
export declare function enrichCommandResult(fields: CommandCompletion): void;
|
|
10
|
-
export declare function getBoundSessionId(): string | undefined;
|
|
11
|
-
/** Bind the pipeline session and emit invoked once both command and session are known. */
|
|
12
|
-
export declare function bindAnalyticsSession(id: string, context?: CommandContext): Promise<void>;
|
|
13
|
-
/** Emit session_started once per new pipeline head. */
|
|
14
|
-
export declare function emitSessionStarted(entryCommand: EntryCommand): Promise<void>;
|
|
15
|
-
export declare function completeActiveCommand(): Promise<void>;
|
|
16
|
-
export declare function failActiveCommand(fields?: CommandFailure): Promise<void>;
|
|
17
|
-
/** Best-effort terminal event when the process exits without a clean postAction hook. */
|
|
18
|
-
export declare function registerAnalyticsExitHook(): void;
|
|
19
|
-
export declare function resetAnalyticsStateForTests(): void;
|