@contentful/experience-design-system-cli 2.17.2-dev-build-ebba024.0 → 2.17.2-dev-build-ebf31d1.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 CHANGED
@@ -214,7 +214,6 @@ Pass `--select-prompt-path <path>` and/or `--generate-prompt-path <path>` to swa
214
214
  | `--host <url>` | `https://api.contentful.com` | Override API base URL |
215
215
  | `--on-conflict <mode>` | _(prompt via `<SaveConflictGate>`)_ | Headless conflict resolution when a file already exists at the save path: `overwrite`, `skip`, or `fail`. Bypasses the wizard's interactive save-conflict gate. Mutex with `--no-save`. |
216
216
  | `--print-prompt` | — | Print the generate prompt to stdout and exit. Replaces the prompt-print semantics of `--dry-run`. |
217
- | `--allow-deletions` | off (non-destructive) | Allow the push to delete remote ComponentTypes/DesignTokens missing from the manifest. Default skips them instead of deleting. Forwarded to headless subprocess pushes and `--push-from-run`. |
218
217
  | `--dry-run` | _(deprecated)_ | Deprecated alias for `--print-prompt`. Emits a stderr deprecation notice; prompt-print semantics will be removed in a future release. |
219
218
 
220
219
  ### Run-picker at wizard start
@@ -419,7 +418,7 @@ experiences apply select --space-id <id> --environment-id <env> --session <id>
419
418
  experiences apply push --space-id <id> --environment-id <env> --session <id> [--yes]
420
419
  ```
421
420
 
422
- Shared flags: `--components`, `--tokens`, `--session`, `--space-id`, `--environment-id`, `--cma-token`, `--host`, `--viewports`. `apply preview` adds `--include-unchanged`. `apply select` adds `--select-all`, `--select`, `--deselect`, `--force`, `--allow-deletions`. `apply push` adds `--yes`, `--verbose`, `--force`, `--dry-run`, `--allow-deletions`. By default, remote ComponentTypes and DesignTokens missing from the pushed manifest are skipped, not deleted; pass `--allow-deletions` to restore the prior delete behavior.
421
+ Shared flags: `--components`, `--tokens`, `--session`, `--space-id`, `--environment-id`, `--cma-token`, `--host`, `--viewports`. `apply preview` adds `--include-unchanged`. `apply select` adds `--select-all`, `--select`, `--deselect`, `--force`. `apply push` adds `--yes`, `--verbose`, `--force`, `--dry-run`.
423
422
 
424
423
  Design tokens are written first (component types may reference token kinds). Each entity write is recorded in the session database atomically — interrupted pushes resume from where they left off.
425
424
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.17.2-dev-build-ebba024.0",
3
+ "version": "2.17.2-dev-build-ebf31d1.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,6 +38,7 @@
38
38
  "lint:fix": "nx lint:fix experience-design-system-cli"
39
39
  },
40
40
  "dependencies": {
41
+ "@contentful/experience-design-system-client": "workspace:*",
41
42
  "@contentful/experience-design-system-extraction": "workspace:*",
42
43
  "@contentful/experience-design-system-types": "workspace:*",
43
44
  "commander": "^13.1.0",
@@ -48,13 +48,10 @@ export declare class ImportApiClient {
48
48
  constructor(opts: ApiClientOptions);
49
49
  private base;
50
50
  private headers;
51
- private fetchWithRetry;
51
+ private requestWithRetry;
52
52
  validateToken(): Promise<void>;
53
53
  previewImport(manifest: ManifestPayload): Promise<ServerPreviewResponse>;
54
- applyImport(manifest: ManifestPayload, options: {
55
- acknowledgeBreakingChanges: boolean;
56
- allowDeletions?: boolean;
57
- }): Promise<ApplyOperationResponse>;
54
+ applyImport(manifest: ManifestPayload, acknowledgeBreakingChanges: boolean): Promise<ApplyOperationResponse>;
58
55
  pollOperation(operationId: string, opts?: {
59
56
  intervalMs?: number;
60
57
  maxIntervalMs?: number;
@@ -1,3 +1,4 @@
1
+ import { designSystemImportSourcelessPreview, designSystemImportApply, designSystemImportGetOperation, } from '@contentful/experience-design-system-client';
1
2
  import { DEFAULT_API_HOST, toApiHost } from '../host-utils.js';
2
3
  import { getDebugLogger } from '../lib/debug-logger.js';
3
4
  import { buildUserAgent } from '../lib/user-agent.js';
@@ -32,6 +33,14 @@ function retryAfterMs(response) {
32
33
  function errorMessage(error) {
33
34
  return error instanceof Error && error.message ? error.message : String(error);
34
35
  }
36
+ // The generated client parses non-2xx bodies to JSON internally (unlike a raw
37
+ // fetch(), which hands back the raw body string). Re-serializing here keeps
38
+ // ApiError's `body: string` contract and parsePreviewValidationErrors'
39
+ // `JSON.parse` unchanged for callers, at the cost of a harmless double-parse
40
+ // on error paths only.
41
+ function stringifyError(error) {
42
+ return typeof error === 'string' ? error : JSON.stringify(error ?? {});
43
+ }
35
44
  // Cap on the body slice appended to ApiError.message. Bumped from 1000 →
36
45
  // 16384 so realistic 422 ValidationFailed reports (which list every
37
46
  // offending component, ~100 chars per error, easily exceeds 1KB once you
@@ -182,45 +191,15 @@ export class ImportApiClient {
182
191
  'X-Contentful-User-Agent': buildUserAgent(),
183
192
  };
184
193
  }
185
- async fetchWithRetry(phase, url, init, context = {}) {
194
+ async requestWithRetry(phase, errorPrefix, makeCall, context = {}) {
186
195
  const debug = getDebugLogger();
187
- const errorPrefix = phase === 'preview' ? PREVIEW_ERROR_PREFIX : 'poll failed:';
188
196
  const startedAt = Date.now();
189
197
  for (let attempt = 1; attempt <= this.retry.maxAttempts; attempt++) {
198
+ let result;
190
199
  try {
191
- const response = await fetch(url, init);
192
- if (!isTransientStatus(response.status))
193
- return response;
194
- const body = await response.text();
195
- if (attempt === this.retry.maxAttempts) {
196
- const guidance = `The ${phase} request failed after ${attempt} attempts because the service remained unavailable. ` +
197
- 'Wait a moment and try again.';
198
- debug.event('apply', `${phase}.error`, {
199
- ...context,
200
- attempt,
201
- maxAttempts: this.retry.maxAttempts,
202
- status: response.status,
203
- reason: 'retry_exhausted',
204
- durationMs: Date.now() - startedAt,
205
- bodyHead: body.slice(0, 2000),
206
- });
207
- throw new ApiError(`${errorPrefix} ${response.status}`, response.status, body, guidance);
208
- }
209
- const backoffMs = Math.min(this.retry.initialDelayMs * 2 ** (attempt - 1), this.retry.maxDelayMs);
210
- const delayMs = retryAfterMs(response) ?? backoffMs;
211
- debug.event('apply', `${phase}.retry`, {
212
- ...context,
213
- attempt,
214
- maxAttempts: this.retry.maxAttempts,
215
- status: response.status,
216
- reason: 'http_5xx',
217
- delayMs,
218
- });
219
- await this.retry.sleep(delayMs);
200
+ result = await makeCall();
220
201
  }
221
202
  catch (error) {
222
- if (error instanceof ApiError)
223
- throw error;
224
203
  if (attempt === this.retry.maxAttempts) {
225
204
  const body = `The request failed after ${attempt} attempts because of a network error: ${errorMessage(error)}. ` +
226
205
  'Check your connection and try again.';
@@ -244,7 +223,36 @@ export class ImportApiClient {
244
223
  delayMs,
245
224
  });
246
225
  await this.retry.sleep(delayMs);
226
+ continue;
227
+ }
228
+ if (!isTransientStatus(result.response.status))
229
+ return result;
230
+ if (attempt === this.retry.maxAttempts) {
231
+ const body = stringifyError(result.error);
232
+ const guidance = `The ${phase} request failed after ${attempt} attempts because the service remained unavailable. ` +
233
+ 'Wait a moment and try again.';
234
+ debug.event('apply', `${phase}.error`, {
235
+ ...context,
236
+ attempt,
237
+ maxAttempts: this.retry.maxAttempts,
238
+ status: result.response.status,
239
+ reason: 'retry_exhausted',
240
+ durationMs: Date.now() - startedAt,
241
+ bodyHead: body.slice(0, 2000),
242
+ });
243
+ throw new ApiError(`${errorPrefix} ${result.response.status}`, result.response.status, body, guidance);
247
244
  }
245
+ const backoffMs = Math.min(this.retry.initialDelayMs * 2 ** (attempt - 1), this.retry.maxDelayMs);
246
+ const delayMs = retryAfterMs(result.response) ?? backoffMs;
247
+ debug.event('apply', `${phase}.retry`, {
248
+ ...context,
249
+ attempt,
250
+ maxAttempts: this.retry.maxAttempts,
251
+ status: result.response.status,
252
+ reason: 'http_5xx',
253
+ delayMs,
254
+ });
255
+ await this.retry.sleep(delayMs);
248
256
  }
249
257
  throw new Error('Retry attempts exhausted');
250
258
  }
@@ -261,44 +269,48 @@ export class ImportApiClient {
261
269
  }
262
270
  }
263
271
  async previewImport(manifest) {
264
- const url = `${this.base()}/design_systems/imports/preview`;
265
272
  const debug = getDebugLogger();
266
273
  const startedAt = Date.now();
267
274
  debug.event('apply', 'preview.request', {
268
- url,
275
+ url: `${this.base()}/design_systems/imports/preview`,
269
276
  componentCount: manifest.components?.length ?? 0,
270
277
  tokenCount: manifest.designTokens?.length ?? 0,
271
278
  });
272
- const res = await this.fetchWithRetry('preview', url, {
273
- method: 'POST',
279
+ const result = await this.requestWithRetry('preview', PREVIEW_ERROR_PREFIX, () => designSystemImportSourcelessPreview({
280
+ baseUrl: this.host,
274
281
  headers: this.headers(),
275
- body: JSON.stringify(manifest),
276
- });
277
- if (!res.ok) {
278
- const body = await res.text();
282
+ path: { spaceId: this.spaceId, environmentId: this.environmentId },
283
+ body: manifest,
284
+ parseAs: 'json',
285
+ }));
286
+ if (!result.response.ok) {
287
+ const body = stringifyError(result.error);
279
288
  debug.event('apply', 'preview.error', {
280
- status: res.status,
289
+ status: result.response.status,
281
290
  durationMs: Date.now() - startedAt,
282
291
  bodyHead: body.slice(0, 2000),
283
292
  });
284
- throw new ApiError(`${PREVIEW_ERROR_PREFIX} ${res.status}`, res.status, body);
293
+ throw new ApiError(`${PREVIEW_ERROR_PREFIX} ${result.response.status}`, result.response.status, body);
285
294
  }
286
- const parsed = (await res.json());
287
- debug.event('apply', 'preview.ok', { status: res.status, durationMs: Date.now() - startedAt });
295
+ const parsed = result.data;
296
+ debug.event('apply', 'preview.ok', { status: result.response.status, durationMs: Date.now() - startedAt });
288
297
  return sanitizePreviewResponse(parsed);
289
298
  }
290
- async applyImport(manifest, options) {
291
- const { acknowledgeBreakingChanges, allowDeletions = false } = options;
292
- const url = `${this.base()}/design_systems/imports/apply`;
299
+ async applyImport(manifest, acknowledgeBreakingChanges) {
293
300
  const debug = getDebugLogger();
294
301
  const startedAt = Date.now();
295
- debug.event('apply', 'apply.request', { url, acknowledgeBreakingChanges, allowDeletions });
296
- let res;
302
+ debug.event('apply', 'apply.request', {
303
+ url: `${this.base()}/design_systems/imports/apply`,
304
+ acknowledgeBreakingChanges,
305
+ });
306
+ let result;
297
307
  try {
298
- res = await fetch(url, {
299
- method: 'POST',
308
+ result = await designSystemImportApply({
309
+ baseUrl: this.host,
300
310
  headers: this.headers(),
301
- body: JSON.stringify({ ...manifest, acknowledgeBreakingChanges, allowDeletions }),
311
+ path: { spaceId: this.spaceId, environmentId: this.environmentId },
312
+ body: { ...manifest, acknowledgeBreakingChanges },
313
+ parseAs: 'json',
302
314
  });
303
315
  }
304
316
  catch (error) {
@@ -311,21 +323,21 @@ export class ImportApiClient {
311
323
  });
312
324
  throw new ApiError(`${APPLY_ERROR_PREFIX} 0`, 0, body);
313
325
  }
314
- if (!res.ok) {
315
- const body = await res.text();
316
- const guidance = isTransientStatus(res.status)
326
+ if (!result.response.ok) {
327
+ const body = stringifyError(result.error);
328
+ const guidance = isTransientStatus(result.response.status)
317
329
  ? 'The apply request was not retried because the server may already have started an operation and retrying could create a duplicate. Check for an existing operation before trying again.'
318
330
  : undefined;
319
331
  debug.event('apply', 'apply.error', {
320
- status: res.status,
332
+ status: result.response.status,
321
333
  durationMs: Date.now() - startedAt,
322
334
  bodyHead: body.slice(0, 2000),
323
335
  });
324
- throw new ApiError(`${APPLY_ERROR_PREFIX} ${res.status}`, res.status, body, guidance);
336
+ throw new ApiError(`${APPLY_ERROR_PREFIX} ${result.response.status}`, result.response.status, body, guidance);
325
337
  }
326
- const parsed = (await res.json());
338
+ const parsed = result.data;
327
339
  debug.event('apply', 'apply.accepted', {
328
- status: res.status,
340
+ status: result.response.status,
329
341
  operationId: parsed.sys?.id,
330
342
  durationMs: Date.now() - startedAt,
331
343
  });
@@ -337,15 +349,16 @@ export class ImportApiClient {
337
349
  const maxAttempts = opts.maxAttempts ?? 150;
338
350
  const terminalStatuses = new Set(['succeeded', 'partial', 'failed']);
339
351
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
340
- const url = `${this.base()}/design_systems/imports/apply/${encodeURIComponent(operationId)}`;
341
- const res = await this.fetchWithRetry('poll', url, {
342
- method: 'GET',
352
+ const result = await this.requestWithRetry('poll', 'poll failed:', () => designSystemImportGetOperation({
353
+ baseUrl: this.host,
343
354
  headers: this.headers(),
344
- }, { operationId });
345
- if (!res.ok) {
346
- throw new ApiError(`poll failed: ${res.status}`, res.status, await res.text());
355
+ path: { spaceId: this.spaceId, environmentId: this.environmentId, operationId },
356
+ parseAs: 'json',
357
+ }), { operationId });
358
+ if (!result.response.ok) {
359
+ throw new ApiError(`poll failed: ${result.response.status}`, result.response.status, stringifyError(result.error));
347
360
  }
348
- const op = (await res.json());
361
+ const op = result.data;
349
362
  opts.onProgress?.(op);
350
363
  getDebugLogger().event('apply', 'poll.tick', {
351
364
  operationId,
@@ -12,7 +12,7 @@ import { ServerPreviewApp, ServerPreviewConfirm, ServerApplyProgress, ServerAppl
12
12
  import { SelectView, makeSelectKey } from './tui/SelectView.js';
13
13
  import { buildPostPushUrl } from '../lib/contentful-urls.js';
14
14
  import { resolveCompositionMode } from '../lib/composition-mode.js';
15
- import { addAllowDeletionsOption, addArtifactInputOptions, addCompositionOptions, addContentfulTargetOptions, addSelectionOptions, } from '../lib/command-options.js';
15
+ import { addArtifactInputOptions, addCompositionOptions, addContentfulTargetOptions, addSelectionOptions, } from '../lib/command-options.js';
16
16
  import { stripAllowedComponents } from '../import/strip-allowed-components.js';
17
17
  import { readExperiencesCredentials } from '../credentials-store.js';
18
18
  import { getInteractiveTerminalSupport, requireInteractiveTerminal } from '../lib/terminal-capabilities.js';
@@ -469,7 +469,6 @@ export function registerApplyCommand(program) {
469
469
  addArtifactInputOptions(pushCmd);
470
470
  addContentfulTargetOptions(pushCmd);
471
471
  addCompositionOptions(pushCmd);
472
- addAllowDeletionsOption(pushCmd);
473
472
  pushCmd
474
473
  .option('--yes', 'Skip interactive confirmation')
475
474
  .option('--verbose', 'Show all entity progress including skipped/unchanged')
@@ -548,10 +547,7 @@ export function registerApplyCommand(program) {
548
547
  }
549
548
  let operation;
550
549
  try {
551
- operation = await client.applyImport(manifest, {
552
- acknowledgeBreakingChanges: breakingWithImpact || opts.force === true,
553
- allowDeletions: opts.allowDeletions === true,
554
- });
550
+ operation = await client.applyImport(manifest, breakingWithImpact || opts.force === true);
555
551
  }
556
552
  catch (e) {
557
553
  if (e instanceof ApiError)
@@ -581,10 +577,7 @@ export function registerApplyCommand(program) {
581
577
  }));
582
578
  let operation;
583
579
  try {
584
- operation = await client.applyImport(manifest, {
585
- acknowledgeBreakingChanges: acknowledge,
586
- allowDeletions: opts.allowDeletions === true,
587
- });
580
+ operation = await client.applyImport(manifest, acknowledge);
588
581
  }
589
582
  catch (e) {
590
583
  if (e instanceof ApiError) {
@@ -647,7 +640,6 @@ export function registerApplyCommand(program) {
647
640
  addContentfulTargetOptions(selectCmd);
648
641
  addCompositionOptions(selectCmd);
649
642
  addSelectionOptions(selectCmd);
650
- addAllowDeletionsOption(selectCmd);
651
643
  selectCmd.option('--force', 'Skip confirmation for breaking changes').action(async (opts) => {
652
644
  const nonInteractive = opts.selectAll || (opts.select ?? []).length > 0 || (opts.deselect ?? []).length > 0;
653
645
  if (!nonInteractive) {
@@ -715,10 +707,7 @@ export function registerApplyCommand(program) {
715
707
  }
716
708
  let operation;
717
709
  try {
718
- operation = await client.applyImport(filteredManifest, {
719
- acknowledgeBreakingChanges: hasBreaking || opts.force === true,
720
- allowDeletions: opts.allowDeletions === true,
721
- });
710
+ operation = await client.applyImport(filteredManifest, hasBreaking || opts.force === true);
722
711
  }
723
712
  catch (e) {
724
713
  if (e instanceof ApiError)
@@ -760,10 +749,7 @@ export function registerApplyCommand(program) {
760
749
  }));
761
750
  let operation;
762
751
  try {
763
- operation = await client.applyImport(filteredManifest, {
764
- acknowledgeBreakingChanges: hasBreaking,
765
- allowDeletions: opts.allowDeletions === true,
766
- });
752
+ operation = await client.applyImport(filteredManifest, hasBreaking);
767
753
  }
768
754
  catch (e) {
769
755
  if (e instanceof ApiError) {
@@ -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 { addAllowDeletionsOption, addCompositionOptions } from '../lib/command-options.js';
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;
@@ -418,8 +418,6 @@ export async function runPipeline(opts, progressWriter, cliPathOverride) {
418
418
  pushArgs.push('--host', opts.host);
419
419
  if (opts.verbose)
420
420
  pushArgs.push('--verbose');
421
- if (opts.allowDeletions)
422
- pushArgs.push('--allow-deletions');
423
421
  pushArgs.push('--yes');
424
422
  const pushStepId = createStep(db, sessionId, 'apply push', {
425
423
  components: componentsPath,
@@ -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, allowDeletions, }?: WizardAppProps): React.ReactElement;
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, allowDeletions = false, } = {}) {
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();
@@ -982,7 +982,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
982
982
  environmentId,
983
983
  host: resolvedHost,
984
984
  });
985
- let operation = await client.applyImport(manifest, { acknowledgeBreakingChanges, allowDeletions });
985
+ let operation = await client.applyImport(manifest, acknowledgeBreakingChanges);
986
986
  try {
987
987
  logStep({
988
988
  applyResponse: {
@@ -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
- }
@@ -26,7 +26,5 @@ 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;
31
29
  };
32
30
  export declare function launchModifyWizard(input: ModifyLauncherInput): Promise<void>;
@@ -35,8 +35,6 @@ 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;
40
38
  const { waitUntilExit } = render(createElement(WizardApp, props));
41
39
  await waitUntilExit();
42
40
  }
@@ -15,7 +15,6 @@ export type PushSessionOptions = {
15
15
  environmentId: string;
16
16
  cmaToken: string;
17
17
  host?: string;
18
- allowDeletions?: boolean;
19
18
  };
20
19
  /**
21
20
  * Push a recorded pipeline.db session's components + tokens to Contentful by
@@ -60,9 +60,6 @@ export async function pushRunSession(opts) {
60
60
  if (opts.host) {
61
61
  args.push('--host', opts.host);
62
62
  }
63
- if (opts.allowDeletions) {
64
- args.push('--allow-deletions');
65
- }
66
63
  const r = await runCli(args);
67
64
  if (r.exitCode === 0)
68
65
  return { ok: true };
@@ -16,8 +16,6 @@ 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;
21
19
  /**
22
20
  * Test seam: replace the interactive prompt with a deterministic resolver.
23
21
  * The CLI surface never sets this; only used by tests.
@@ -59,8 +57,6 @@ export type ModifyRunOptions = {
59
57
  outDir?: string;
60
58
  /** When true, bypass the source/saved-file staleness check. */
61
59
  force?: boolean;
62
- /** From `--allow-deletions` flag. Forwarded through the modify wizard's push step. */
63
- allowDeletions?: boolean;
64
60
  };
65
61
  /**
66
62
  * Re-open the wizard with a prior run's extract/generate session pre-populated
@@ -83,7 +83,6 @@ export async function replayRun(opts) {
83
83
  environmentId,
84
84
  cmaToken,
85
85
  ...(host ? { host } : {}),
86
- ...(opts.allowDeletions ? { allowDeletions: true } : {}),
87
86
  });
88
87
  if (!result.ok) {
89
88
  throw new Error(result.error);
@@ -99,7 +98,6 @@ export async function replayRun(opts) {
99
98
  environmentId,
100
99
  cmaToken,
101
100
  ...(host ? { host } : {}),
102
- ...(opts.allowDeletions ? { allowDeletions: true } : {}),
103
101
  });
104
102
  if (!tokenResult.ok) {
105
103
  throw new Error(tokenResult.error);
@@ -159,6 +157,5 @@ export async function modifyRun(opts) {
159
157
  ...(mergedEnvironmentId ? { initialEnvironmentId: mergedEnvironmentId } : {}),
160
158
  ...(mergedHost ? { initialHost: mergedHost } : {}),
161
159
  ...(mergedCmaToken ? { initialCmaToken: mergedCmaToken } : {}),
162
- ...(opts.allowDeletions !== undefined ? { allowDeletions: opts.allowDeletions } : {}),
163
160
  });
164
161
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.17.2-dev-build-ebba024.0",
3
+ "version": "2.17.2-dev-build-ebf31d1.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,8 +34,9 @@
34
34
  "react": "^18.3.1",
35
35
  "react-devtools-core": "^4.19.1",
36
36
  "react-dom": "^18.3.1",
37
- "@contentful/experience-design-system-extraction": "2.17.2-dev-build-ebba024.0",
38
- "@contentful/experience-design-system-types": "2.17.2-dev-build-ebba024.0"
37
+ "@contentful/experience-design-system-client": "2.17.2-dev-build-ebf31d1.0",
38
+ "@contentful/experience-design-system-extraction": "2.17.2-dev-build-ebf31d1.0",
39
+ "@contentful/experience-design-system-types": "2.17.2-dev-build-ebf31d1.0"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@tsconfig/node24": "^24.0.3",