CLI Package - Development Guide
Note: This guide is for developers who want to understand, extend, or contribute to the command-line interface component of n8n-as-code.
๐ฏ Purposeโ
The CLI package (n8nac) provides a command-line interface for managing n8n workflows from the terminal. It offers:
- Project Management: Initialize and configure n8n-as-code projects
- Workflow Synchronization: Sync workflows between local files and n8n with git-like commands
- AI Assistance: AI-powered workflow generation and assistance
๐๏ธ Architectureโ
Package Structureโ
packages/cli/
โโโ src/
โ โโโ index.ts # CLI entry point (registers all commands)
โ โโโ commands/
โ โ โโโ base.ts # Base command class
โ โ โโโ update-ai.ts # UpdateAiCommand
โ โ โโโ list.ts # List command
โ โ โโโ convert.ts # Convert command (JSON โ TypeScript)
โ โ โโโ sync.ts # Sync command (pull / push / fetch / resolve)
โ โโโ core/
โ โ โโโ types.ts # WorkflowSyncStatus enum, interfaces
โ โ โโโ sync-manager.ts # Core sync engine
โ โ โโโ ... # API client, services
โ โโโ services/
โ โโโ config-service.ts # Configuration management
โโโ bin/
โ โโโ n8n-as-code.js # CLI executable
โโโ package.json # Package manifest
โโโ tsconfig.json # TypeScript configuration
Command Hierarchyโ
๐งฉ Sync Componentsโ
1. CLI Entry Point (index.ts)โ
The main entry point that sets up the CLI application.
Key Responsibilities:
- Parse command-line arguments
- Initialize configuration
- Execute appropriate command
- Handle global errors
Setup:
import { Command } from 'commander';
import { InitCommand, SyncCommand, ListCommand, InitAICommand } from './commands';
const program = new Command();
program
.name('n8n-as-code')
.description('Manage n8n workflows as code')
.version(version);
// Register commands
new InitCommand(program);
new SyncCommand(program);
new ListCommand(program);
new InitAICommand(program);
program.parse(process.argv);
2. Base Command (commands/base.ts)โ
Abstract base class for all commands.
Key Responsibilities:
- Provide common command functionality
- Handle error reporting
- Manage configuration loading
- Provide logging utilities
Base Implementation:
abstract class BaseCommand {
protected config: Config;
protected logger: Logger;
constructor(protected program: Command) {
this.config = ConfigService.load();
this.logger = new Logger(program.opts().verbose);
}
abstract execute(options: any): Promise<void>;
protected handleError(error: Error): void {
this.logger.error(error.message);
process.exit(1);
}
}
3. Workspace Commandsโ
Workspace commands own only local overrides over the global n8n-manager configuration.
Key Responsibilities:
- Show backend-resolved workspace status
- Pin or clear the effective workspace instance
- Set or clear legacy workspace sync-folder overrides
- Set or clear the workspace project override
4. Sync Command (commands/sync.ts)โ
Synchronizes workflows between local files and n8n.
Key Responsibilities:
- Pull workflows from n8n to local files
- Push local workflows to n8n
- Handle conflicts and resolutions
- Provide sync progress reporting
Sync Modes:
interface SyncOptions {
mode: 'pull' | 'push' | 'both';
force: boolean;
dryRun: boolean;
instance?: string;
}
5. List Command (commands/list.ts)โ
Shows current sync status of all workflows.
Key Responsibilities:
- Fetch fresh remote metadata on each invocation
- Calculate 3-way status (local vs remote vs base)
- Display color-coded status table
- Support
--local/--remotefilters for focused views
6. Update AI Command (commands/update-ai.ts)โ
Regenerates AI context files for the project.
Key Responsibilities:
- Generate
AGENTS.mdwith n8n-specific AI agent instructions - Generate
.vscode/n8n.code-snippetsfrom the n8n node index - Optionally connect to n8n to embed the running instance version
7. Config Service (services/config-service.ts)โ
Manages CLI configuration.
Key Responsibilities:
- Load configuration from multiple sources
- Validate configuration
- Merge environment variables and file config
- Provide typed configuration access
Configuration Sources:
The CLI currently loads local configuration from n8nac-config.json in the current working directory and stores API keys in a secure global credential store.
๐ Integration with CLI Coreโ
Sync Engine Usageโ
The CLI commands use the sync engine (embedded in packages/cli/src/core/):
import { SyncManager, StateManager, N8nApiClient } from 'n8nac';
class SyncCommand extends BaseCommand {
private syncManager: SyncManager;
constructor() {
super();
this.syncManager = new SyncManager(this.config);
}
async execute(options: any): Promise<void> {
const result = await this.syncManager.sync({
mode: options.mode,
force: options.force
});
this.logger.reportSyncResult(result);
}
}
Event Handlingโ
The CLI listens to Sync library events:
syncManager.on('sync:progress', (progress) => {
this.logger.progress(progress);
});
syncManager.on('sync:conflict', (conflict) => {
this.logger.conflict(conflict);
// Prompt user for resolution
});
syncManager.on('sync:complete', (result) => {
this.logger.success(`Synced ${result.synced} workflows`);
});
๐ ๏ธ Development Setupโ
Prerequisitesโ
- Node.js 18+
- n8n instance for testing
- Git (for version control features)
Local Developmentโ
# Install dependencies
cd packages/cli
npm install
# Build CLI
npm run build
# Link for local testing
npm link
# Test commands
n8nac --help
Testing with Local n8nโ
- Start a local n8n instance.
- Get an API key from n8n settings.
- Configure a workspace environment:
n8nac env add Dev --base-url <url> --workflows-path workflows/dev
n8nac env auth set Dev --api-key-stdin
n8nac env use Dev
๐ง Adding New Commandsโ
Step 1: Create Command Classโ
// commands/new-command.ts
import { Command } from 'commander';
import { BaseCommand } from './base';
export class NewCommand extends BaseCommand {
constructor(program: Command) {
super(program);
program
.command('new-command')
.description('Description of new command')
.option('--option <value>', 'Option description')
.action(this.execute.bind(this));
}
async execute(options: any): Promise<void> {
// Command implementation
this.logger.info('New command executed');
}
}
Step 2: Register Commandโ
// index.ts
import { NewCommand } from './commands/new-command';
// Add to command registration
new NewCommand(program);
Step 3: Update TypeScript Configurationโ
Ensure the new command is included in the build.
๐งช Testingโ
Test Structureโ
packages/cli/
โโโ tests/
โโโ unit/
โ โโโ commands/
โ โ โโโ init.test.ts
โ โ โโโ sync.test.ts
โ โโโ services/
โ โโโ config-service.test.ts
โโโ integration/
โโโ cli-integration.test.ts
Running Testsโ
cd packages/cli
npm test
Mockingโ
Mock file system and n8n API for testing:
import mockFs from 'mock-fs';
import nock from 'nock';
beforeEach(() => {
mockFs({
'workflows': {},
'n8nac-config.json': JSON.stringify({
version: 4,
activeEnvironmentId: 'dev',
environments: [{
id: 'dev',
name: 'Dev',
environmentTargetId: 'dev',
projectId: 'personal',
projectName: 'Personal',
workflowsPath: 'workflows/dev'
}],
environmentTargets: [{
id: 'dev',
name: 'Dev',
kind: 'external-instance', // persisted kind for a remote n8n URL target
url: 'http://test.n8n'
}]
})
});
nock('http://test.n8n')
.get('/api/v1/workflows')
.reply(200, []);
});
afterEach(() => {
mockFs.restore();
nock.cleanAll();
});
๐ฆ Packaging and Distributionโ
Building for Productionโ
npm run build
Creating Executableโ
The CLI uses pkg or nexe for creating standalone executables:
{
"bin": {
"n8nac": "./dist/index.js"
}
}
Publishing to npmโ
npm version patch
npm publish
๐ Security Considerationsโ
API Key Managementโ
- Never Log: API keys are never logged
- Environment Variables: Preferred over config files
- Encryption: Optional encryption for stored keys
Input Validationโ
- Validate All Inputs: Host URLs, file paths, etc.
- Sanitize Outputs: Prevent injection attacks
- Rate Limiting: Prevent abuse of n8n API
๐ Performance Optimizationโ
Command Performanceโ
- Lazy Loading: Load Sync library only when needed
- Caching: Cache configuration and API responses
- Parallel Processing: Sync multiple workflows in parallel
Memory Managementโ
- Stream Processing: Process large workflows as streams
- Cleanup: Proper disposal of resources
- Monitoring: Track memory usage
๐ Troubleshootingโ
Common Issuesโ
Connection Failedโ
# Test connection manually
curl -H "X-N8N-API-KEY: your-key" https://your-n8n.com/api/v1/workflows
Configuration Not Foundโ
- Check current directory for
n8nac-config.json. - Run
n8nac env add Dev --base-url <url> --workflows-path workflows/devto create an environment. - Run
n8nac env auth set Dev --api-key-stdinto store the local API key.
Sync Conflictsโ
- Review conflict details in output
- Use
--forceto overwrite (with caution) - Manually resolve in n8n UI
Debug Modeโ
Enable verbose logging:
DEBUG=n8n-as-code:* n8nac list
Log Filesโ
Check the terminal output (and VS Code Output panel when using the extension) for detailed error information.
๐ Related Documentationโ
- Sync Engine: Sync engine internals (embedded in CLI)
- Architecture Overview: Overall system architecture
- VS Code Extension: VS Code extension development
- Contribution Guide: How to contribute
The n8nac package provides powerful command-line tools for n8n workflow management, enabling automation, scripting, and integration with other development tools. It also exposes n8nac skills โ a subcommand group bridging to the @n8n-as-code/skills library for AI agent tooling.