@contentful/experience-design-system-cli 2.18.1-dev-build-2117d43.0 → 2.18.1-dev-build-b4ecc99.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.18.1-dev-build-2117d43.0",
3
+ "version": "2.18.1-dev-build-b4ecc99.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -51,11 +51,11 @@
51
51
  "@tsconfig/node24": "^24.0.3",
52
52
  "@types/node": "^24.0.3",
53
53
  "@types/react": "^18.3.24",
54
- "eslint": "^9.39.2",
54
+ "eslint": "^9.39.5",
55
55
  "eslint-config-prettier": "^10.1.8",
56
- "eslint-plugin-prettier": "^5.5.4",
56
+ "eslint-plugin-prettier": "^5.5.6",
57
57
  "ink-testing-library": "^4.0.0",
58
- "typescript-eslint": "^8.52.0",
58
+ "typescript-eslint": "^8.66.0",
59
59
  "vitest": "^4.0.16"
60
60
  },
61
61
  "repository": {
@@ -51,10 +51,7 @@ export declare class ImportApiClient {
51
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;
@@ -296,14 +296,12 @@ export class ImportApiClient {
296
296
  debug.event('apply', 'preview.ok', { status: result.response.status, durationMs: Date.now() - startedAt });
297
297
  return sanitizePreviewResponse(parsed);
298
298
  }
299
- async applyImport(manifest, options) {
300
- const { acknowledgeBreakingChanges, allowDeletions = false } = options;
299
+ async applyImport(manifest, acknowledgeBreakingChanges) {
301
300
  const debug = getDebugLogger();
302
301
  const startedAt = Date.now();
303
302
  debug.event('apply', 'apply.request', {
304
303
  url: `${this.base()}/design_systems/imports/apply`,
305
304
  acknowledgeBreakingChanges,
306
- allowDeletions,
307
305
  });
308
306
  let result;
309
307
  try {
@@ -311,7 +309,7 @@ export class ImportApiClient {
311
309
  baseUrl: this.host,
312
310
  headers: this.headers(),
313
311
  path: { spaceId: this.spaceId, environmentId: this.environmentId },
314
- body: { ...manifest, acknowledgeBreakingChanges, allowDeletions },
312
+ body: { ...manifest, acknowledgeBreakingChanges },
315
313
  parseAs: 'json',
316
314
  });
317
315
  }
@@ -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';
@@ -457,7 +457,6 @@ export function registerApplyCommand(program) {
457
457
  preview,
458
458
  spaceId,
459
459
  environmentId,
460
- allowDeletions: false,
461
460
  }));
462
461
  await waitUntilExit();
463
462
  }
@@ -470,7 +469,6 @@ export function registerApplyCommand(program) {
470
469
  addArtifactInputOptions(pushCmd);
471
470
  addContentfulTargetOptions(pushCmd);
472
471
  addCompositionOptions(pushCmd);
473
- addAllowDeletionsOption(pushCmd);
474
472
  pushCmd
475
473
  .option('--yes', 'Skip interactive confirmation')
476
474
  .option('--verbose', 'Show all entity progress including skipped/unchanged')
@@ -519,7 +517,6 @@ export function registerApplyCommand(program) {
519
517
  preview,
520
518
  spaceId,
521
519
  environmentId,
522
- allowDeletions: opts.allowDeletions === true,
523
520
  }));
524
521
  await waitUntilExit();
525
522
  }
@@ -550,10 +547,7 @@ export function registerApplyCommand(program) {
550
547
  }
551
548
  let operation;
552
549
  try {
553
- operation = await client.applyImport(manifest, {
554
- acknowledgeBreakingChanges: breakingWithImpact || opts.force === true,
555
- allowDeletions: opts.allowDeletions === true,
556
- });
550
+ operation = await client.applyImport(manifest, breakingWithImpact || opts.force === true);
557
551
  }
558
552
  catch (e) {
559
553
  if (e instanceof ApiError)
@@ -583,10 +577,7 @@ export function registerApplyCommand(program) {
583
577
  }));
584
578
  let operation;
585
579
  try {
586
- operation = await client.applyImport(manifest, {
587
- acknowledgeBreakingChanges: acknowledge,
588
- allowDeletions: opts.allowDeletions === true,
589
- });
580
+ operation = await client.applyImport(manifest, acknowledge);
590
581
  }
591
582
  catch (e) {
592
583
  if (e instanceof ApiError) {
@@ -634,7 +625,6 @@ export function registerApplyCommand(program) {
634
625
  spaceId,
635
626
  environmentId,
636
627
  breakingWithImpact,
637
- allowDeletions: opts.allowDeletions === true,
638
628
  onConfirm: (acknowledge) => {
639
629
  void runApply(acknowledge);
640
630
  },
@@ -650,7 +640,6 @@ export function registerApplyCommand(program) {
650
640
  addContentfulTargetOptions(selectCmd);
651
641
  addCompositionOptions(selectCmd);
652
642
  addSelectionOptions(selectCmd);
653
- addAllowDeletionsOption(selectCmd);
654
643
  selectCmd.option('--force', 'Skip confirmation for breaking changes').action(async (opts) => {
655
644
  const nonInteractive = opts.selectAll || (opts.select ?? []).length > 0 || (opts.deselect ?? []).length > 0;
656
645
  if (!nonInteractive) {
@@ -718,10 +707,7 @@ export function registerApplyCommand(program) {
718
707
  }
719
708
  let operation;
720
709
  try {
721
- operation = await client.applyImport(filteredManifest, {
722
- acknowledgeBreakingChanges: hasBreaking || opts.force === true,
723
- allowDeletions: opts.allowDeletions === true,
724
- });
710
+ operation = await client.applyImport(filteredManifest, hasBreaking || opts.force === true);
725
711
  }
726
712
  catch (e) {
727
713
  if (e instanceof ApiError)
@@ -763,10 +749,7 @@ export function registerApplyCommand(program) {
763
749
  }));
764
750
  let operation;
765
751
  try {
766
- operation = await client.applyImport(filteredManifest, {
767
- acknowledgeBreakingChanges: hasBreaking,
768
- allowDeletions: opts.allowDeletions === true,
769
- });
752
+ operation = await client.applyImport(filteredManifest, hasBreaking);
770
753
  }
771
754
  catch (e) {
772
755
  if (e instanceof ApiError) {
@@ -5,18 +5,16 @@ interface ServerPreviewConfirmProps {
5
5
  spaceId: string;
6
6
  environmentId: string;
7
7
  breakingWithImpact: boolean;
8
- allowDeletions: boolean;
9
8
  onConfirm: (acknowledge: boolean) => void;
10
9
  onCancel: () => void;
11
10
  }
12
- export declare function ServerPreviewConfirm({ preview, spaceId, environmentId, breakingWithImpact, allowDeletions, onConfirm, onCancel, }: ServerPreviewConfirmProps): React.ReactElement;
11
+ export declare function ServerPreviewConfirm({ preview, spaceId, environmentId, breakingWithImpact, onConfirm, onCancel, }: ServerPreviewConfirmProps): React.ReactElement;
13
12
  interface ServerPreviewAppProps {
14
13
  preview: ServerPreviewResponse;
15
14
  spaceId: string;
16
15
  environmentId: string;
17
- allowDeletions: boolean;
18
16
  }
19
- export declare function ServerPreviewApp({ preview, spaceId, environmentId, allowDeletions, }: ServerPreviewAppProps): React.ReactElement;
17
+ export declare function ServerPreviewApp({ preview, spaceId, environmentId }: ServerPreviewAppProps): React.ReactElement;
20
18
  interface ServerApplyProgressProps {
21
19
  spaceId: string;
22
20
  environmentId: string;
@@ -3,22 +3,21 @@ import { Box, Text, useInput } from 'ink';
3
3
  import { ServerPreviewView } from './ServerPreviewView.js';
4
4
  import { buildPostPushUrl } from '../../lib/contentful-urls.js';
5
5
  import { formatEdsiError } from '../../lib/error-parser.js';
6
- export function ServerPreviewConfirm({ preview, spaceId, environmentId, breakingWithImpact, allowDeletions, onConfirm, onCancel, }) {
6
+ export function ServerPreviewConfirm({ preview, spaceId, environmentId, breakingWithImpact, onConfirm, onCancel, }) {
7
7
  useInput((input, key) => {
8
8
  if (key.return)
9
9
  onConfirm(breakingWithImpact);
10
10
  if (key.escape || input === 'q')
11
11
  onCancel();
12
12
  });
13
- const removedCount = preview.components.removed.length + preview.tokens.removed.length;
14
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(ServerPreviewView, { preview: preview, spaceId: spaceId, environmentId: environmentId, allowDeletions: allowDeletions }), _jsxs(Box, { paddingX: 2, flexDirection: "column", children: [breakingWithImpact && (_jsxs(Text, { color: "red", bold: true, children: [' ', "\u26A0 Breaking changes will affect downstream entities. Press Enter to acknowledge and apply."] })), allowDeletions && removedCount > 0 && (_jsxs(Text, { color: "red", bold: true, children: [' ', "\u26A0 ", removedCount, " missing ", removedCount === 1 ? 'entity' : 'entities', " will be permanently deleted. Press Enter to confirm."] })), _jsxs(Text, { children: [' ', "Press ", _jsx(Text, { bold: true, children: "Enter" }), " to apply, ", _jsx(Text, { bold: true, children: "Esc" }), " to cancel"] })] })] }));
13
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(ServerPreviewView, { preview: preview, spaceId: spaceId, environmentId: environmentId }), _jsxs(Box, { paddingX: 2, flexDirection: "column", children: [breakingWithImpact && (_jsxs(Text, { color: "red", bold: true, children: [' ', "\u26A0 Breaking changes will affect downstream entities. Press Enter to acknowledge and apply."] })), _jsxs(Text, { children: [' ', "Press ", _jsx(Text, { bold: true, children: "Enter" }), " to apply, ", _jsx(Text, { bold: true, children: "Esc" }), " to cancel"] })] })] }));
15
14
  }
16
- export function ServerPreviewApp({ preview, spaceId, environmentId, allowDeletions, }) {
15
+ export function ServerPreviewApp({ preview, spaceId, environmentId }) {
17
16
  useInput((input, key) => {
18
17
  if (key.escape || input === 'q')
19
18
  process.exit(0);
20
19
  });
21
- return (_jsx(ServerPreviewView, { preview: preview, spaceId: spaceId, environmentId: environmentId, allowDeletions: allowDeletions }));
20
+ return _jsx(ServerPreviewView, { preview: preview, spaceId: spaceId, environmentId: environmentId });
22
21
  }
23
22
  export function ServerApplyProgress({ spaceId, environmentId, status, operationId, error, }) {
24
23
  useInput((_input, key) => {
@@ -4,7 +4,6 @@ interface ServerPreviewViewProps {
4
4
  preview: ServerPreviewResponse;
5
5
  spaceId: string;
6
6
  environmentId: string;
7
- allowDeletions: boolean;
8
7
  }
9
- export declare function ServerPreviewView({ preview, spaceId, environmentId, allowDeletions, }: ServerPreviewViewProps): React.ReactElement;
8
+ export declare function ServerPreviewView({ preview, spaceId, environmentId }: ServerPreviewViewProps): React.ReactElement;
10
9
  export {};
@@ -13,11 +13,11 @@ function DraftWarning({ hasDraft }) {
13
13
  return null;
14
14
  return _jsx(Text, { color: "yellow", children: " \u26A1 has pending draft changes" });
15
15
  }
16
- export function ServerPreviewView({ preview, spaceId, environmentId, allowDeletions, }) {
16
+ export function ServerPreviewView({ preview, spaceId, environmentId }) {
17
17
  const { components, tokens } = preview;
18
18
  const totalComponents = components.new.length + components.changed.length + components.unchanged.length + components.removed.length;
19
19
  const totalTokens = tokens.new.length + tokens.changed.length + tokens.unchanged.length + tokens.removed.length;
20
- return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Text, { bold: true, children: ["Preview \u2014 ", environmentId, " @ ", spaceId] }), _jsx(Text, { children: " " }), totalComponents > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [" Component Types (", totalComponents, " total)"] }), _jsxs(Text, { color: "green", children: [" \u2746 ", components.new.length, " to create"] }), _jsxs(Text, { color: "yellow", children: [" ~ ", components.changed.length, " to update"] }), _jsxs(Text, { color: allowDeletions ? 'red' : 'yellow', children: [' ', allowDeletions ? '✗' : '⊘', " ", components.removed.length, " to ", allowDeletions ? 'delete' : 'skip'] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", components.unchanged.length, " unchanged"] }), components.changed.map((item, i) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: "yellow", children: [" ~ ", item.current.name] }), _jsx(DraftWarning, { hasDraft: item.hasPendingDraftChanges })] }), _jsx(BreakingBadge, { item: item })] }, i))), _jsx(Text, { children: " " })] })), totalTokens > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [" Design Tokens (", totalTokens, " total)"] }), _jsxs(Text, { color: "green", children: [" \u2746 ", tokens.new.length, " to create"] }), _jsxs(Text, { color: "yellow", children: [" ~ ", tokens.changed.length, " to update"] }), _jsxs(Text, { color: allowDeletions ? 'red' : 'yellow', children: [' ', allowDeletions ? '✗' : '⊘', " ", tokens.removed.length, " to ", allowDeletions ? 'delete' : 'skip'] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", tokens.unchanged.length, " unchanged"] }), tokens.changed
20
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Text, { bold: true, children: ["Preview \u2014 ", environmentId, " @ ", spaceId] }), _jsx(Text, { children: " " }), totalComponents > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [" Component Types (", totalComponents, " total)"] }), _jsxs(Text, { color: "green", children: [" \u2746 ", components.new.length, " to create"] }), _jsxs(Text, { color: "yellow", children: [" ~ ", components.changed.length, " to update"] }), _jsxs(Text, { color: "red", children: [" \u2717 ", components.removed.length, " to remove"] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", components.unchanged.length, " unchanged"] }), components.changed.map((item, i) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: "yellow", children: [" ~ ", item.current.name] }), _jsx(DraftWarning, { hasDraft: item.hasPendingDraftChanges })] }), _jsx(BreakingBadge, { item: item })] }, i))), _jsx(Text, { children: " " })] })), totalTokens > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, children: [" Design Tokens (", totalTokens, " total)"] }), _jsxs(Text, { color: "green", children: [" \u2746 ", tokens.new.length, " to create"] }), _jsxs(Text, { color: "yellow", children: [" ~ ", tokens.changed.length, " to update"] }), _jsxs(Text, { color: "red", children: [" \u2717 ", tokens.removed.length, " to remove"] }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", tokens.unchanged.length, " unchanged"] }), tokens.changed
21
21
  .filter((t) => t.hasPendingDraftChanges)
22
22
  .map((item, i) => (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: "yellow", children: [" ~ ", item.current.name] }), _jsx(DraftWarning, { hasDraft: true })] }, i))), _jsx(Text, { children: " " })] })), _jsx(Text, { dimColor: true, children: " Press Q to exit." })] }));
23
23
  }
@@ -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();
@@ -942,7 +942,7 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
942
942
  });
943
943
  }
944
944
  };
945
- const runPush = async (manifest, spaceId, environmentId, cmaToken, host, acknowledgeBreakingChanges, allowDeletions, preview) => {
945
+ const runPush = async (manifest, spaceId, environmentId, cmaToken, host, acknowledgeBreakingChanges, preview) => {
946
946
  if (shouldRefusePush(state)) {
947
947
  update(buildSkippedPushTransition());
948
948
  return;
@@ -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: {
@@ -1601,8 +1601,8 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
1601
1601
  // present-but-empty (only $schema), so editing would dead-end on the
1602
1602
  // "No generated definitions found" screen.
1603
1603
  const editableComponentCount = Object.keys(state.manifest?.componentsManifest ?? {}).filter((k) => k !== '$schema').length;
1604
- return (_jsx(WizardPreviewStep, { preview: state.serverPreview, spaceId: state.spaceId, environmentId: state.environmentId, stepNumber: totalSteps, totalSteps: totalSteps, initialAllowDeletions: allowDeletions, onConfirm: (acknowledge, deleteMissing) => {
1605
- void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge, deleteMissing, state.serverPreview);
1604
+ return (_jsx(WizardPreviewStep, { preview: state.serverPreview, spaceId: state.spaceId, environmentId: state.environmentId, stepNumber: totalSteps, totalSteps: totalSteps, onConfirm: (acknowledge) => {
1605
+ void runPush(state.manifest, state.spaceId, state.environmentId, state.cmaToken, state.host, acknowledge, state.serverPreview);
1606
1606
  }, ...(editableComponentCount > 0 ? { onEdit: () => void runEditFromPreview() } : {}), onSaveFiles: () => {
1607
1607
  void startSaveFlow();
1608
1608
  }, onQuit: () => process.exit(0) }));
@@ -12,11 +12,10 @@ type WizardPreviewStepProps = {
12
12
  environmentId: string;
13
13
  stepNumber: number;
14
14
  totalSteps: number;
15
- initialAllowDeletions?: boolean;
16
- onConfirm: (acknowledge: boolean, allowDeletions: boolean) => void;
15
+ onConfirm: (acknowledge: boolean) => void;
17
16
  onEdit?: () => void;
18
17
  onSaveFiles?: () => void;
19
18
  onQuit: () => void;
20
19
  };
21
- export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, initialAllowDeletions, onConfirm, onEdit, onSaveFiles, onQuit, }: WizardPreviewStepProps): React.ReactElement;
20
+ export declare function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }: WizardPreviewStepProps): React.ReactElement;
22
21
  export {};
@@ -89,11 +89,10 @@ export function buildPreviewDiffLines(preview) {
89
89
  }
90
90
  return lines;
91
91
  }
92
- export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, initialAllowDeletions = false, onConfirm, onEdit, onSaveFiles, onQuit, }) {
92
+ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber, totalSteps, onConfirm, onEdit, onSaveFiles, onQuit, }) {
93
93
  const breakingWithImpact = hasBreakingChangesWithImpact(preview);
94
94
  const [diffExpanded, setDiffExpanded] = useState(false);
95
95
  const [scrollOffset, setScrollOffset] = useState(0);
96
- const [allowDeletions, setAllowDeletions] = useState(initialAllowDeletions);
97
96
  const { stdout } = useStdout();
98
97
  const terminalRows = stdout?.rows ?? 40;
99
98
  const viewportHeight = Math.max(terminalRows - 14, 10);
@@ -106,14 +105,9 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
106
105
  }));
107
106
  }, [diffExpanded, preview]);
108
107
  const maxScroll = Math.max(0, allDiffLines.length - viewportHeight);
109
- const removedCount = preview.components.removed.length + preview.tokens.removed.length;
110
108
  useImmediateInput((input, key) => {
111
109
  if (key.return) {
112
- onConfirm(breakingWithImpact, allowDeletions);
113
- return;
114
- }
115
- if ((input === 'x' || input === 'X') && removedCount > 0) {
116
- setAllowDeletions((prev) => !prev);
110
+ onConfirm(breakingWithImpact);
117
111
  return;
118
112
  }
119
113
  if (input === 'd' || input === 'D') {
@@ -162,5 +156,5 @@ export function WizardPreviewStep({ preview, spaceId, environmentId, stepNumber,
162
156
  })] })), components.changed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.warning, children: " \uFF5E" }), _jsxs(Text, { children: [components.changed.length, " will be updated"] })] }), components.changed.map((item, i) => {
163
157
  const isBreaking = item.changeClassification?.classification === 'breaking';
164
158
  return (_jsxs(Text, { color: isBreaking ? PALETTE.error : PALETTE.warning, children: [' ', isBreaking ? '⚠' : '~', " ", item.current.name] }, `chg-${i}`));
165
- })] })), 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." })), _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" }), removedCount > 0 && (_jsxs(Text, { dimColor: true, children: ["[x] ", allowDeletions ? '[✓]' : '[ ]', " Also delete ", removedCount, " ", removedCount === 1 ? 'entity' : 'entities'] })), _jsx(Text, { dimColor: true, children: "[q] Cancel" })] })] }));
159
+ })] })), components.removed.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.error, children: " \u2717" }), _jsxs(Text, { children: [components.removed.length, " will be removed"] })] }), components.removed.map((item, i) => (_jsxs(Text, { color: PALETTE.error, children: [' ', "\u2717 ", item.name] }, `rm-${i}`)))] })), components.unchanged.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: " \u00B7" }), _jsxs(Text, { dimColor: true, children: [components.unchanged.length, " unchanged"] })] }))] })), hasTokens && (_jsxs(Box, { flexDirection: "column", gap: 0, children: [_jsx(Box, { gap: 1, marginTop: 1, children: _jsx(Text, { bold: true, dimColor: true, children: "Design Tokens" }) }), tokens.new.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.success, children: " \uFF0B" }), _jsxs(Text, { children: [tokens.new.length, " will be created"] })] })), tokens.changed.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.warning, children: " \uFF5E" }), _jsxs(Text, { children: [tokens.changed.length, " will be updated"] })] })), tokens.removed.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: PALETTE.error, children: " \u2717" }), _jsxs(Text, { children: [tokens.removed.length, " will be removed"] })] })), tokens.unchanged.length > 0 && (_jsxs(Box, { gap: 1, children: [_jsx(Text, { dimColor: true, children: " \u00B7" }), _jsxs(Text, { dimColor: true, children: [tokens.unchanged.length, " unchanged"] })] }))] })), diffExpanded && allDiffLines.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, children: '─'.repeat(40) }), _jsxs(Text, { dimColor: true, children: [' ', "Diff (", allDiffLines.length, " lines) \u2014 line ", scrollOffset + 1, "\u2013", Math.min(scrollOffset + viewportHeight, allDiffLines.length), " of ", allDiffLines.length] }), _jsx(Box, { flexDirection: "column", children: allDiffLines.slice(scrollOffset, scrollOffset + viewportHeight).map((line) => (_jsx(Box, { children: line.element }, line.key))) }), maxScroll > 0 && _jsx(Text, { dimColor: true, children: " \u2195 j/k to scroll, f/b to page" })] }))] })) : (_jsx(Text, { dimColor: true, children: "Nothing to push \u2014 everything is already up to date." })), _jsxs(Box, { gap: 1, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Space:" }), _jsx(Text, { children: spaceId }), _jsx(Text, { dimColor: true, children: "/" }), _jsx(Text, { dimColor: true, children: "Environment:" }), _jsx(Text, { children: environmentId })] }), breakingWithImpact && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: PALETTE.error, bold: true, children: "\u26A0 Breaking changes will affect downstream entities. Press Enter to acknowledge and apply." }) })), _jsxs(Box, { gap: 3, marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "[Enter] Push to Contentful" }), _jsxs(Text, { dimColor: true, children: ["[d] ", diffExpanded ? 'Hide' : 'Show', " diff"] }), diffExpanded && _jsx(Text, { dimColor: true, children: "[j/k] Scroll [f/b] Page" }), onEdit && _jsx(Text, { dimColor: true, children: "[e] Edit definitions" }), onSaveFiles && _jsx(Text, { dimColor: true, children: "[s] Save files instead" }), _jsx(Text, { dimColor: true, children: "[q] Cancel" })] })] }));
166
160
  }
@@ -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.18.1-dev-build-2117d43.0",
3
+ "version": "2.18.1-dev-build-b4ecc99.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,19 +34,19 @@
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-client": "2.18.1-dev-build-2117d43.0",
38
- "@contentful/experience-design-system-types": "2.18.1-dev-build-2117d43.0",
39
- "@contentful/experience-design-system-extraction": "2.18.1-dev-build-2117d43.0"
37
+ "@contentful/experience-design-system-client": "2.18.1-dev-build-b4ecc99.0",
38
+ "@contentful/experience-design-system-extraction": "2.18.1-dev-build-b4ecc99.0",
39
+ "@contentful/experience-design-system-types": "2.18.1-dev-build-b4ecc99.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@tsconfig/node24": "^24.0.3",
43
43
  "@types/node": "^24.0.3",
44
44
  "@types/react": "^18.3.24",
45
- "eslint": "^9.39.2",
45
+ "eslint": "^9.39.5",
46
46
  "eslint-config-prettier": "^10.1.8",
47
- "eslint-plugin-prettier": "^5.5.4",
47
+ "eslint-plugin-prettier": "^5.5.6",
48
48
  "ink-testing-library": "^4.0.0",
49
- "typescript-eslint": "^8.52.0",
49
+ "typescript-eslint": "^8.66.0",
50
50
  "vitest": "^4.0.16"
51
51
  },
52
52
  "repository": {