n8nac 2.3.5 → 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -19,7 +19,6 @@ import { parsePositiveIntegerOption } from './utils/option-parsers.js';
19
19
  import { spawn } from 'child_process';
20
20
  import { createN8nManagerFacade } from '@n8n-as-code/manager-adapter';
21
21
  import { ConfigService } from './services/config-service.js';
22
- import { WorkspaceMigrationFacade } from './services/workspace-migration-facade.js';
23
22
  import { N8N_FACADE_SETUP_MODES, isN8nFacadeSetupMode, } from '@n8n-as-code/workflow-core';
24
23
  import { createTelemetryClient, getTelemetryStatus, setTelemetryEnabled, classifyTelemetryError, shouldShowTelemetryNotice, markTelemetryNoticeShown, } from '@n8n-as-code/telemetry';
25
24
  async function readSecretFromStdin() {
@@ -77,88 +76,12 @@ function hideCommand(command) {
77
76
  command.hidden = true;
78
77
  return command;
79
78
  }
80
- function formatLegacyMigrationResult(result) {
81
- if (result.status === 'not-needed') {
82
- return chalk.green(`No legacy n8nac workspace config detected at ${result.configPath}.`);
83
- }
84
- const plan = result.plan;
85
- const instanceLines = plan.instances.length > 0
86
- ? plan.instances.map((instance) => `- ${instance.name} (${instance.id})${instance.host ? ` -> ${instance.host}` : ''}${instance.hasApiKey ? ' [API key found]' : ''}`)
87
- : ['- No instances found in the legacy config.'];
88
- const workspaceLines = [
89
- plan.workspace.syncFolder ? `- Sync folder: ${plan.workspace.syncFolder}` : undefined,
90
- plan.workspace.projectName || plan.workspace.projectId ? `- Project: ${plan.workspace.projectName || plan.workspace.projectId}` : undefined,
91
- plan.activeInstanceId ? `- Workspace-pinned instance: ${plan.activeInstanceId}` : undefined,
92
- ].filter(Boolean);
93
- const header = result.status === 'dry-run'
94
- ? chalk.yellow('Legacy n8nac workspace config detected. No files changed.')
95
- : chalk.green('Legacy n8nac workspace config migrated.');
96
- const footer = result.status === 'dry-run'
97
- ? ['Run `n8nac workspace migrate-v1 --write` to migrate and create a backup first.']
98
- : [`Backup: ${result.backupPath}`, 'Run `n8nac workspace status --json` to verify the resolved context.'];
99
- return [
100
- header,
101
- `Config: ${plan.configPath}`,
102
- plan.version ? `Legacy version: ${plan.version}` : undefined,
103
- '',
104
- 'Instances:',
105
- ...instanceLines,
106
- workspaceLines.length ? '' : undefined,
107
- workspaceLines.length ? 'Workspace overrides:' : undefined,
108
- ...workspaceLines,
109
- '',
110
- 'Notes:',
111
- ...plan.warnings.map((warning) => `- ${warning}`),
112
- '',
113
- ...footer,
114
- ].filter(Boolean).join('\n');
115
- }
116
- function formatWorkspaceMigrationReport(report) {
117
- if (report.status === 'not-needed') {
118
- return chalk.green(`No n8n workspace migration required at ${report.configPath}.`);
119
- }
120
- const header = report.status === 'dry-run'
121
- ? chalk.yellow('n8n workspace migration required. No files changed.')
122
- : chalk.green('n8n workspace migration completed.');
123
- const footer = report.status === 'dry-run'
124
- ? ['Run `n8nac workspace migrate --write` to apply the migration.']
125
- : [
126
- report.backupPath ? `Backup: ${report.backupPath}` : undefined,
127
- `Migrated environments: ${report.migratedEnvironmentIds?.length || 0}`,
128
- `Removed global external instances: ${report.deletedGlobalInstanceIds?.length || 0}`,
129
- 'Run `n8nac workspace status --json` to verify the resolved context.',
130
- ].filter(Boolean);
131
- return [
132
- header,
133
- `Config: ${report.configPath}`,
134
- '',
135
- 'Migration operations:',
136
- ...report.operations.map((operation) => `- ${operation.label}: ${operation.instanceCount} instance${operation.instanceCount === 1 ? '' : 's'}`),
137
- report.warnings.length ? '' : undefined,
138
- report.warnings.length ? 'Notes:' : undefined,
139
- ...report.warnings.map((warning) => `- ${warning}`),
140
- '',
141
- ...footer,
142
- ].filter(Boolean).join('\n');
143
- }
144
79
  function redactResolvedEnvironment(environment) {
145
80
  if (!environment)
146
81
  return environment;
147
82
  const { apiKey: _apiKey, ...safeEnvironment } = environment;
148
83
  return safeEnvironment;
149
84
  }
150
- function abortIfWorkspaceMigrationRequired(configService, options = {}) {
151
- const payload = new WorkspaceMigrationFacade({ configService }).inspect();
152
- if (!payload)
153
- return;
154
- printJsonOrText(options, payload, [
155
- chalk.yellow('n8n workspace migration required before environment commands can run.'),
156
- `Config: ${payload.configPath}`,
157
- 'Run `n8nac workspace migrate --json` to inspect it.',
158
- 'After explicit confirmation, run `n8nac workspace migrate --write` to apply it.',
159
- ].join('\n'));
160
- process.exit(1);
161
- }
162
85
  /**
163
86
  * Get version from package.json
164
87
  */
@@ -217,11 +140,11 @@ const getFirstPositionalToken = (args, startIndex = 0) => {
217
140
  if (token === '--') {
218
141
  return args[index + 1];
219
142
  }
220
- if (token === '--instance' || token === '--env' || token === '--environment') {
143
+ if (token === '--env' || token === '--environment') {
221
144
  index += 1;
222
145
  continue;
223
146
  }
224
- if (token.startsWith('--instance=') || token.startsWith('--env=') || token.startsWith('--environment=')) {
147
+ if (token.startsWith('--env=') || token.startsWith('--environment=')) {
225
148
  continue;
226
149
  }
227
150
  if (token.startsWith('-')) {
@@ -338,8 +261,7 @@ program
338
261
  .description('N8N Sync Command Line Interface - Manage n8n workflows as code')
339
262
  .version(getVersion())
340
263
  .option('--env <name>', 'Target a specific workspace environment by name or ID')
341
- .addOption(new Option('--environment <name>', 'Alias for --env').hideHelp())
342
- .addOption(new Option('--instance <name>', 'Deprecated; use --env').hideHelp());
264
+ .addOption(new Option('--environment <name>', 'Alias for --env').hideHelp());
343
265
  // Inject --env into the environment only for the lifetime of the command action
344
266
  // so BaseCommand can pick it up without leaking process-wide state afterwards.
345
267
  let previousEnvironmentEnv;
@@ -410,7 +332,7 @@ telemetryProgram.command('disable')
410
332
  printJsonOrText(options, status, chalk.green('Anonymous telemetry disabled.'));
411
333
  });
412
334
  const workspaceProgram = program.command('workspace')
413
- .description('Inspect or migrate n8n workspace configuration');
335
+ .description('Inspect n8n workspace configuration');
414
336
  workspaceProgram.command('status')
415
337
  .alias('get')
416
338
  .description('Show the effective n8n workspace context resolved by the backend')
@@ -418,179 +340,24 @@ workspaceProgram.command('status')
418
340
  .action(async (options) => {
419
341
  const configService = new ConfigService();
420
342
  const selectedEnvironment = process.env.N8NAC_ENVIRONMENT?.trim() || undefined;
421
- const migration = new WorkspaceMigrationFacade({ configService }).inspect();
422
- if (migration) {
423
- printJsonOrText(options, migration, [
424
- chalk.yellow('n8n workspace migration required.'),
425
- `Config: ${migration.configPath}`,
426
- 'Run `n8nac workspace migrate --json` to inspect it.',
427
- 'After confirmation, run `n8nac workspace migrate --write` to apply it.',
428
- ].join('\n'));
429
- return;
430
- }
431
343
  const workspaceConfig = configService.getWorkspaceConfig();
432
344
  const resolvedEnvironment = selectedEnvironment
433
345
  ? await configService.prepareEnvironment(selectedEnvironment)
434
- : workspaceConfig.version === 4
435
- ? await (async () => { try {
436
- return await configService.prepareEnvironment();
437
- }
438
- catch {
439
- return undefined;
440
- } })()
441
- : undefined;
346
+ : await (async () => { try {
347
+ return await configService.prepareEnvironment();
348
+ }
349
+ catch {
350
+ return undefined;
351
+ } })();
442
352
  printJsonOrText(options, resolvedEnvironment ? { ...workspaceConfig, selectedEnvironment: redactResolvedEnvironment(resolvedEnvironment) } : workspaceConfig, [
443
353
  chalk.cyan('\nEffective n8n workspace context:\n'),
444
354
  workspaceConfig.activeEnvironmentId ? `Env : ${chalk.bold(resolvedEnvironment?.environmentName || workspaceConfig.activeEnvironment?.name || workspaceConfig.activeEnvironmentId)}` : undefined,
445
355
  `Instance: ${chalk.bold(resolvedEnvironment?.activeInstanceName || workspaceConfig.activeInstanceId || '(none)')}`,
446
356
  `Project : ${chalk.bold(resolvedEnvironment?.projectName || workspaceConfig.projectName || workspaceConfig.projectId || '(none)')}`,
447
- `Workflows path: ${chalk.bold(resolvedEnvironment?.workflowsPath || workspaceConfig.workflowsPath || workspaceConfig.workflowDir || '(none)')}`,
357
+ `Workflows path: ${chalk.bold(resolvedEnvironment?.workflowsPath || workspaceConfig.workflowsPath || '(none)')}`,
448
358
  '',
449
359
  ].filter(Boolean).join('\n'));
450
360
  });
451
- workspaceProgram.command('migrate')
452
- .description('Inspect or run required workspace migrations')
453
- .option('--write', 'Apply the migration. Without this flag, the command only reports what would change.')
454
- .option('--json', 'Output migration result as JSON')
455
- .action(async (options) => {
456
- const report = await new WorkspaceMigrationFacade().migrate({ write: Boolean(options.write) });
457
- printJsonOrText(options, report, formatWorkspaceMigrationReport(report));
458
- });
459
- workspaceProgram.command('migrate-v1')
460
- .description('Inspect or migrate a legacy v1/v2 n8nac-config.json into the v2 manager-backed storage model')
461
- .option('--write', 'Apply the migration. Without this flag, the command only reports what would change.')
462
- .option('--json', 'Output migration result as JSON')
463
- .action((options) => {
464
- const configService = new ConfigService();
465
- const result = configService.migrateLegacyWorkspaceConfig({ write: Boolean(options.write) });
466
- printJsonOrText(options, result, formatLegacyMigrationResult(result));
467
- });
468
- hideCommand(workspaceProgram.command('pin-instance'))
469
- .description('Pin the effective n8n instance for this workspace')
470
- .requiredOption('--instance-id <id>', 'Global n8n instance ID to pin')
471
- .option('--json', 'Output workspace config as JSON')
472
- .action((options) => {
473
- const configService = new ConfigService();
474
- const instance = configService.pinWorkspaceInstance(options.instanceId);
475
- const workspaceConfig = configService.getWorkspaceConfig();
476
- printJsonOrText(options, workspaceConfig, chalk.green(`✔ Workspace pinned to n8n instance: ${instance.name}`));
477
- });
478
- hideCommand(workspaceProgram.command('clear-instance'))
479
- .description('Clear the workspace n8n instance pin and fall back to the global active instance')
480
- .option('--json', 'Output workspace config as JSON')
481
- .action((options) => {
482
- const configService = new ConfigService();
483
- configService.clearWorkspaceInstanceOverride();
484
- const workspaceConfig = configService.getWorkspaceConfig();
485
- printJsonOrText(options, workspaceConfig, chalk.green('✔ Workspace instance override cleared.'));
486
- });
487
- hideCommand(workspaceProgram.command('set-sync-folder'))
488
- .description('Set the n8n sync folder override for this workspace')
489
- .argument('<path>', 'Workspace sync folder path')
490
- .option('--json', 'Output workspace config as JSON')
491
- .action((syncFolder, options) => {
492
- const configService = new ConfigService();
493
- configService.setWorkspaceSyncFolder(syncFolder);
494
- const workspaceConfig = configService.getWorkspaceConfig();
495
- printJsonOrText(options, workspaceConfig, chalk.green(`✔ Workspace sync folder set to: ${syncFolder}`));
496
- });
497
- hideCommand(workspaceProgram.command('clear-sync-folder'))
498
- .description('Clear the workspace n8n sync folder override and fall back to the global default')
499
- .option('--json', 'Output workspace config as JSON')
500
- .action((options) => {
501
- const configService = new ConfigService();
502
- configService.clearWorkspaceSyncFolderOverride();
503
- const workspaceConfig = configService.getWorkspaceConfig();
504
- printJsonOrText(options, workspaceConfig, chalk.green('✔ Workspace sync folder override cleared.'));
505
- });
506
- hideCommand(workspaceProgram.command('set-project'))
507
- .description('Set the n8n project override for this workspace from known project values')
508
- .requiredOption('--project-id <id>', 'n8n project ID to store in this workspace')
509
- .requiredOption('--project-name <name>', 'n8n project display name to store in this workspace')
510
- .option('--json', 'Output workspace config as JSON')
511
- .action((options) => {
512
- const configService = new ConfigService();
513
- configService.setWorkspaceProject({
514
- projectId: options.projectId,
515
- projectName: options.projectName,
516
- });
517
- const workspaceConfig = configService.getWorkspaceConfig();
518
- printJsonOrText(options, workspaceConfig, chalk.green(`✔ Workspace project set to: ${options.projectName}`));
519
- });
520
- hideCommand(workspaceProgram.command('clear-project'))
521
- .description('Clear the workspace n8n project override and fall back to the instance default project')
522
- .option('--json', 'Output workspace config as JSON')
523
- .action((options) => {
524
- const configService = new ConfigService();
525
- configService.clearWorkspaceProjectOverride();
526
- const workspaceConfig = configService.getWorkspaceConfig();
527
- printJsonOrText(options, workspaceConfig, chalk.green('✔ Workspace project override cleared.'));
528
- });
529
- const environmentTargetProgram = hideCommand(program.command('instance-target')
530
- .alias('target')
531
- .description('Compatibility: manage low-level workspace targets used by environments'));
532
- environmentTargetProgram.command('list')
533
- .description('List workspace instance targets')
534
- .option('--json', 'Output targets as JSON')
535
- .action((options) => {
536
- const configService = new ConfigService();
537
- const targets = configService.listInstanceTargets();
538
- printJsonOrText(options, targets, targets.length
539
- ? targets.map((target) => `${target.id}\t${target.name}\t${target.kind}\t${target.kind === 'managed-instance' ? target.managedInstanceId : target.url}`).join('\n')
540
- : 'No workspace instance targets configured.');
541
- });
542
- environmentTargetProgram.command('add')
543
- .description('Compatibility: add a low-level workspace target. Prefer `n8nac env add --base-url ...`.')
544
- .argument('<name>', 'Target display name')
545
- .option('--id <id>', 'Stable target ID')
546
- .option('--instance-ref <id>', 'Global n8n-manager instance ID to reference')
547
- .option('--base-url <url>', 'Public externalInstance n8n URL to embed without secrets')
548
- .option('--description <text>', 'Target description')
549
- .option('--json', 'Output target as JSON')
550
- .action(async (name, options) => {
551
- const configService = new ConfigService();
552
- const managedInstanceId = options.managedInstanceId || options.instanceRef;
553
- const url = options.url || options.baseUrl;
554
- if (managedInstanceId) {
555
- const instance = (await createManagerFacadeFromOptions({}).listInstances()).find((item) => item.id === managedInstanceId);
556
- if (!instance)
557
- throw new Error(`Unknown managed local n8n instance: ${managedInstanceId}`);
558
- if (instance.mode !== 'managed-local-docker') {
559
- throw new Error(`Instance "${instance.name || instance.id}" is not managed locally. Prefer \`n8nac env add <name> --base-url <url> --workflows-path workflows/<name>\` for remote n8n environments.`);
560
- }
561
- }
562
- const target = configService.addInstanceTarget({
563
- name,
564
- id: options.id,
565
- managedInstanceId,
566
- url,
567
- description: options.description,
568
- });
569
- printJsonOrText(options, target, chalk.green(`✔ Workspace instance target added: ${target.name}`));
570
- });
571
- environmentTargetProgram.command('update')
572
- .description('Update a workspace instance target')
573
- .argument('<name-or-id>', 'Target name or ID')
574
- .option('--name <name>', 'New display name')
575
- .option('--instance-ref <id>', 'New global n8n-manager instance reference for managedInstance targets')
576
- .option('--base-url <url>', 'New public URL for externalInstance targets')
577
- .option('--description <text>', 'New description')
578
- .option('--json', 'Output target as JSON')
579
- .action((nameOrId, options) => {
580
- const configService = new ConfigService();
581
- const target = configService.updateInstanceTarget(nameOrId, options);
582
- printJsonOrText(options, target, chalk.green(`✔ Workspace instance target updated: ${target.name}`));
583
- });
584
- environmentTargetProgram.command('remove')
585
- .alias('rm')
586
- .description('Remove an unused workspace instance target')
587
- .argument('<name-or-id>', 'Target name or ID')
588
- .option('--json', 'Output removed target as JSON')
589
- .action((nameOrId, options) => {
590
- const configService = new ConfigService();
591
- const target = configService.removeInstanceTarget(nameOrId);
592
- printJsonOrText(options, target, chalk.green(`✔ Workspace instance target removed: ${target.name}`));
593
- });
594
361
  const environmentProgram = program.command('env')
595
362
  .alias('environment')
596
363
  .description('Manage n8n workspace environments');
@@ -599,7 +366,6 @@ environmentProgram.command('list')
599
366
  .option('--json', 'Output environments as JSON')
600
367
  .action((options) => {
601
368
  const configService = new ConfigService();
602
- abortIfWorkspaceMigrationRequired(configService, options);
603
369
  const config = configService.getWorkspaceConfig();
604
370
  const environments = configService.listEnvironments().map((environment) => {
605
371
  const resolved = (() => { try {
@@ -617,7 +383,7 @@ environmentProgram.command('list')
617
383
  environment.name,
618
384
  environment.resolved?.environmentTargetName || environment.environmentTargetId,
619
385
  environment.projectName || environment.projectId || '(no project)',
620
- environment.workflowsPath || environment.workflowDir || environment.syncFolder,
386
+ environment.workflowsPath,
621
387
  ].join('\t')).join('\n')
622
388
  : 'No workspace environments configured.');
623
389
  });
@@ -626,14 +392,11 @@ environmentProgram.command('add')
626
392
  .argument('<name>', 'Environment display name')
627
393
  .option('--base-url <url>', 'Remote n8n URL to store in this workspace environment')
628
394
  .option('--managed-instance <id>', 'Local managed n8n instance ID to reference')
629
- .option('--instance-target <name-or-id>', 'Compatibility: workspace target name or ID')
630
395
  .option('--api-key <key>', 'Store a local API key for --base-url without committing it')
631
396
  .option('--api-key-stdin', 'Read the local API key for --base-url from stdin')
632
397
  .option('--project-id <id>', 'n8n project ID')
633
398
  .option('--project-name <name>', 'n8n project display name')
634
399
  .option('--workflows-path <path>', 'Directory that contains this environment workflows')
635
- .option('--workflow-dir <path>', 'Compatibility alias for --workflows-path')
636
- .option('--sync-folder <path>', 'Compatibility alias for --workflows-path')
637
400
  .option('--id <id>', 'Stable environment ID')
638
401
  .option('--folder-sync', 'Enable folder sync for this environment')
639
402
  .option('--custom-nodes-path <path>', 'Custom nodes path for this environment')
@@ -642,17 +405,15 @@ environmentProgram.command('add')
642
405
  .action(async (name, options) => {
643
406
  await hydrateApiKeyFromStdin(options);
644
407
  const configService = new ConfigService();
645
- abortIfWorkspaceMigrationRequired(configService, options);
646
- const environmentTargetOption = options.environmentTarget || options.instanceTarget;
647
408
  const urlOption = options.url || options.baseUrl;
648
- const selectors = [environmentTargetOption, urlOption, options.managedInstance].filter(Boolean);
409
+ const selectors = [urlOption, options.managedInstance].filter(Boolean);
649
410
  if (selectors.length !== 1) {
650
- throw new Error('Provide exactly one of --base-url, --managed-instance, or --instance-target.');
411
+ throw new Error('Provide exactly one of --base-url or --managed-instance.');
651
412
  }
652
413
  if ((options.projectId && !options.projectName) || (!options.projectId && options.projectName)) {
653
414
  throw new Error('Provide both --project-id and --project-name, or omit both.');
654
415
  }
655
- let environmentTarget = environmentTargetOption;
416
+ let environmentTarget;
656
417
  if (urlOption) {
657
418
  const target = configService.ensureEmbeddedInstanceTarget({
658
419
  name,
@@ -676,8 +437,6 @@ environmentProgram.command('add')
676
437
  projectId: options.projectId || (urlOption ? 'personal' : undefined),
677
438
  projectName: options.projectName || (urlOption ? 'Personal' : undefined),
678
439
  workflowsPath: options.workflowsPath,
679
- workflowDir: options.workflowDir,
680
- syncFolder: options.syncFolder,
681
440
  folderSync: Boolean(options.folderSync),
682
441
  customNodesPath: options.customNodesPath,
683
442
  description: options.description,
@@ -690,14 +449,11 @@ environmentProgram.command('update')
690
449
  .option('--name <name>', 'New display name')
691
450
  .option('--base-url <url>', 'Move this environment to a remote n8n URL')
692
451
  .option('--managed-instance <id>', 'Move this environment to a local managed n8n instance')
693
- .option('--instance-target <name-or-id>', 'Workspace instance target name or ID')
694
452
  .option('--api-key <key>', 'Store a local API key for --base-url without committing it')
695
453
  .option('--api-key-stdin', 'Read the local API key for --base-url from stdin')
696
454
  .option('--project-id <id>', 'n8n project ID')
697
455
  .option('--project-name <name>', 'n8n project display name')
698
456
  .option('--workflows-path <path>', 'Directory that contains this environment workflows')
699
- .option('--workflow-dir <path>', 'Compatibility alias for --workflows-path')
700
- .option('--sync-folder <path>', 'Compatibility alias for --workflows-path')
701
457
  .option('--folder-sync', 'Enable folder sync for this environment')
702
458
  .option('--no-folder-sync', 'Disable folder sync for this environment')
703
459
  .option('--custom-nodes-path <path>', 'Custom nodes path for this environment')
@@ -706,14 +462,12 @@ environmentProgram.command('update')
706
462
  .action(async (nameOrId, options) => {
707
463
  await hydrateApiKeyFromStdin(options);
708
464
  const configService = new ConfigService();
709
- abortIfWorkspaceMigrationRequired(configService, options);
710
- const environmentTargetOption = options.environmentTarget || options.instanceTarget;
711
465
  const urlOption = options.url || options.baseUrl;
712
- const selectors = [environmentTargetOption, urlOption, options.managedInstance].filter(Boolean);
466
+ const selectors = [urlOption, options.managedInstance].filter(Boolean);
713
467
  if (selectors.length > 1) {
714
- throw new Error('Provide at most one of --base-url, --managed-instance, or --instance-target.');
468
+ throw new Error('Provide at most one of --base-url or --managed-instance.');
715
469
  }
716
- let environmentTarget = environmentTargetOption;
470
+ let environmentTarget;
717
471
  if (urlOption) {
718
472
  const target = configService.ensureEmbeddedInstanceTarget({
719
473
  name: options.name || nameOrId,
@@ -733,8 +487,6 @@ environmentProgram.command('update')
733
487
  projectId: options.projectId,
734
488
  projectName: options.projectName,
735
489
  workflowsPath: options.workflowsPath,
736
- workflowDir: options.workflowDir,
737
- syncFolder: options.syncFolder,
738
490
  folderSync: typeof options.folderSync === 'boolean' ? options.folderSync : undefined,
739
491
  customNodesPath: options.customNodesPath,
740
492
  description: options.description,
@@ -749,7 +501,6 @@ environmentProgram.command('pin')
749
501
  .option('--json', 'Output environment as JSON')
750
502
  .action((nameOrId, options) => {
751
503
  const configService = new ConfigService();
752
- abortIfWorkspaceMigrationRequired(configService, options);
753
504
  const environment = configService.pinEnvironment(nameOrId);
754
505
  printJsonOrText(options, environment, chalk.green(`✔ Workspace environment pinned: ${environment.name}`));
755
506
  });
@@ -761,7 +512,6 @@ environmentProgram.command('remove')
761
512
  .option('--json', 'Output removed environment as JSON')
762
513
  .action((nameOrId, options) => {
763
514
  const configService = new ConfigService();
764
- abortIfWorkspaceMigrationRequired(configService, options);
765
515
  const environment = configService.removeEnvironment(nameOrId, { force: Boolean(options.force) });
766
516
  printJsonOrText(options, environment, chalk.green(`✔ Workspace environment removed: ${environment.name}`));
767
517
  });
@@ -778,7 +528,6 @@ environmentAuthProgram.command('set')
778
528
  throw new Error('Provide --api-key or --api-key-stdin.');
779
529
  }
780
530
  const configService = new ConfigService();
781
- abortIfWorkspaceMigrationRequired(configService, options);
782
531
  const environment = configService.resolveEnvironment(nameOrId);
783
532
  if (environment.sourceKind === 'managed-instance') {
784
533
  throw new Error(`Environment "${environment.environmentName}" uses managed instance "${environment.managedInstanceId}". Configure credentials through the managed n8n instance instead.`);
@@ -797,7 +546,6 @@ environmentProgram.command('status')
797
546
  .option('--json', 'Output resolved environment as JSON')
798
547
  .action((nameOrId, options) => {
799
548
  const configService = new ConfigService();
800
- abortIfWorkspaceMigrationRequired(configService, options);
801
549
  const environment = configService.resolveEnvironment(nameOrId || process.env.N8NAC_ENVIRONMENT?.trim() || undefined);
802
550
  printJsonOrText(options, redactResolvedEnvironment(environment), [
803
551
  chalk.cyan(`\nWorkspace environment: ${environment.environmentName}\n`),
@@ -805,7 +553,7 @@ environmentProgram.command('status')
805
553
  `Instance: ${chalk.bold(environment.activeInstanceName || environment.managedInstanceId || '(externalInstance)')}`,
806
554
  `Host : ${chalk.bold(environment.host)}`,
807
555
  `Project : ${chalk.bold(environment.projectName || environment.projectId || '(none)')}`,
808
- `Workflows path: ${chalk.bold(environment.workflowsPath || environment.workflowDir || '(unresolved)')}`,
556
+ `Workflows path: ${chalk.bold(environment.workflowsPath || '(unresolved)')}`,
809
557
  `API key : ${chalk.bold(environment.apiKeyAvailable ? environment.apiKeySource : 'missing')}`,
810
558
  '',
811
559
  ].join('\n'));