N8n n8nac
Code-first n8n workflow development with n8nac (n8n-as-code). Workspace bootstrap, GitOps sync protocol, TypeScript decorator syntax, error classification, research protocol, and common mistakes. USE WHEN n8nac, n8n-as-code, code-first workflow, workflow.ts, n8nac init, n8nac push, n8nac pull, n8nac verify, n8nac test, n8nac list, workflow as code, TypeScript workflow, decorator workflow, GitOps n8n, push workflow, pull workflow, verify workflow, test workflow, Class A error, Class B error, n8nac bootstrap, n8nac setup, workflow sync.From its SKILL.md
npx -y skills add mj-deving/pai-skills --skill n8n-n8nacAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.6 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
n8nac — Code-First n8n Workflow Development
n8nac (@n8n-as-code/cli) manages n8n workflows as clean, version-controlled TypeScript files using decorators. This skill covers the universal protocol — project-specific config is generated by n8nac update-ai.
Based on n8nac v1.6.x protocol. Run
npx --yes n8nac update-aiin your project for the latest project-specific AGENTS.md.
Drift check: This skill captures the stable universal protocol. If n8nac has been updated since v1.6.x, run
npx --yes n8nac update-aiand compare the generated AGENTS.md against this skill. If the protocol changed (new commands, renamed flags, new error classes), update this skill to match.
Workspace Bootstrap (MANDATORY)
Before ANY n8nac command, the workspace must be initialized.
Check
- Look for
n8nac-config.jsonat workspace root - If missing or incomplete (no
projectId/projectName): not initialized
Initialize (2-step non-interactive)
# Step 1: Save credentials
npx --yes n8nac init-auth --host <url> --api-key <key>
# Step 2: Select project
npx --yes n8nac init-project --project-index 1 --sync-folder workflows
1-command alternative (when project is known)
npx --yes n8nac init --yes --host <url> --api-key <key> --project-index 1 --sync-folder workflows
Environment variables
If N8N_HOST and N8N_API_KEY are set in the shell, use them:
npx --yes n8nac init-auth --host "$N8N_HOST" --api-key "$N8N_API_KEY"
Instance management
npx --yes n8nac instance list --json # List saved configs
npx --yes n8nac instance select --instance-name <name> # Switch
npx --yes n8nac instance delete --instance-name <name> --yes # Remove
Rules:
- Never tell the user to run init — the agent runs it
- Never write
n8nac-config.jsonby hand - Never run list/pull/push before init completes
- Don't assume init happened just because workflow files exist
GitOps Sync Protocol (CRITICAL)
n8nac uses a Git-like sync architecture. Local code is source of truth, but the user might have edited in n8n UI.
The 7-Step Workflow
1. LIST — Check status
npx --yes n8nac list # All workflows with sync status
npx --yes n8nac list --local # Local .workflow.ts files only
npx --yes n8nac list --remote # Remote workflows only
2. PULL — Download remote changes before editing
npx --yes n8nac pull <workflowId>
Required if remote has newer changes. Skip = OCC rejection on push.
3. EDIT/CREATE — Work on local .workflow.ts
- Existing: edit the pulled file
- New: create in the
workflowDirfromn8nac-config.json(the active instance's canonical path) - Confirm with
npx --yes n8nac list --localbefore pushing
4. PUSH — Upload to n8n
npx --yes n8nac push <path> # Full or workspace-relative path
npx --yes n8nac push <path> --verify # Push + verify in one step
Path rules:
- Always use full path including
.workflow.tssuffix - Use absolute or workspace-root-relative path (e.g.,
workflows/instance/project/my-workflow.workflow.ts) - Never bare filename, never omit extension, never use workflow title
5. VERIFY — Validate live workflow
npx --yes n8nac verify <workflowId>
Catches: invalid typeVersion, bad operation values, missing required params, unknown node types.
6. TEST-PLAN — Check testability
npx --yes n8nac test-plan <workflowId> # Human readable
npx --yes n8nac test-plan <workflowId> --json # Structured for agents
7. TEST — Execute webhook/chat/form workflows
# STANDARD sequence (ALWAYS use this):
npx --yes n8nac workflow activate <workflowId>
npx --yes n8nac test <workflowId> --prod
# With custom payload:
npx --yes n8nac test <workflowId> --prod --data '{"key":"value"}'
Default rule: ALWAYS activate first, ALWAYS use --prod. Bare test <id> requires manual arm in n8n editor.
8. RESOLVE — Handle conflicts
npx --yes n8nac resolve <id> --mode keep-current # Force local
npx --yes n8nac resolve <id> --mode keep-incoming # Force remote
Error Classification
n8nac test classifies failures into three buckets:
| Class | Exit Code | Action |
|---|---|---|
| Class A — Config gap | 0 | Missing credentials/model/env var. Inform user, do NOT re-edit code |
| Runtime state | 0 | Webhook not armed, production webhook not registered. Fix state, NOT code |
| Class B — Wiring error | 1 | Bad expression, wrong field. Fix .workflow.ts, push, re-test |
Critical: A Class A error is NOT a bug. Never push/edit to fix missing credentials.
Research Protocol (MANDATORY before creating/editing nodes)
Step 0: Pattern Discovery
npx --yes n8nac skills examples search "telegram chatbot"
Step 1: Search for the node
npx --yes n8nac skills search "google sheets"
Step 2: Get exact schema
npx --yes n8nac skills node-info googleSheets # Complete
npx --yes n8nac skills node-schema googleSheets # Quick reference
Step 3: Apply schema as absolute truth
- Use EXACT
typefrom schema (with full package prefix) - Use HIGHEST
typeVersionfrom schema - Use exact parameter names
Step 4: Validate before push
npx --yes n8nac skills validate workflow.workflow.ts
Step 5: Verify after push
npx --yes n8nac verify <workflowId>
TypeScript Decorator Syntax
Minimal workflow structure
import { workflow, node, links } from '@n8n-as-code/transformer';
@workflow({ name: 'Workflow Name', active: false })
export class MyWorkflow {
@node({
name: 'Descriptive Name',
type: '/* EXACT from search */',
version: 4,
position: [250, 300]
})
MyNode = { /* parameters from node-info */ };
@links()
defineRouting() {
this.MyNode.out(0).to(this.NextNode.in(0));
}
}
AI Agent pattern (LangChain nodes)
@workflow({ name: 'AI Agent', active: false })
export class AIAgentWorkflow {
@node({ name: 'Chat Trigger', type: '@n8n/n8n-nodes-langchain.chatTrigger', version: 1.4 })
ChatTrigger = {};
@node({ name: 'AI Agent', type: '@n8n/n8n-nodes-langchain.agent', version: 3.1 })
AiAgent = {
promptType: 'define',
text: '={{ $json.chatInput }}',
hasOutputParser: true,
options: { systemMessage: 'You are a helpful assistant.' },
};
@node({ name: 'Model', type: '@n8n/n8n-nodes-langchain.lmChatOpenAi', version: 1.3,
credentials: { openAiApi: { id: 'xxx', name: 'OpenAI' } } })
Model = { model: { mode: 'list', value: 'gpt-4o-mini' }, options: {} };
@links()
defineRouting() {
this.ChatTrigger.out(0).to(this.AiAgent.in(0));
// AI sub-nodes MUST use .uses(), NEVER .out().to()
this.AiAgent.uses({
ai_languageModel: this.Model.output, // single ref
ai_tool: [this.SearchTool.output], // array ref (tools, documents)
});
}
}
Key rule: Regular nodes: .out(0).to(target.in(0)). AI sub-nodes (models, memory, tools, parsers): .uses() only.
Workflow Map Navigation
Every .workflow.ts starts with a <workflow-map> comment block — a compact index. Read this FIRST, then search for the specific property name you need. Never load the entire file into context.
13 Common Mistakes
- Wrong node type — missing package prefix (
switchvsn8n-nodes-base.switch) - Outdated typeVersion — always use highest from schema
- Non-existent typeVersion — verify against exact array in node-schema
- Invalid operation value — check exact string in options[].value list
- Mismatched resource + operation — each resource has different valid operations
- Guessing parameter structure — always check schema for nested objects
- Wrong connection names — must match exact node
namefield - Inventing non-existent nodes — use
searchto verify - Wrong
.uses()syntax —ai_tool/ai_documentare ALWAYS arrays; all others single refs - Connecting AI sub-nodes with
.out().to()— use.uses()for anything flagged[ai_*] - Guessing fixedCollection values — always run
node-infofirst - Inverting value1/value2 in Switch/If — value1 = expression, value2 = literal
- Wrong formFields structure for Wait — use
{ values: [...] }, notformFieldsUi.fieldItems
Additional Tools
# Execution inspection (debug post-trigger)
npx --yes n8nac execution list --workflow-id <id> --limit 5 --json
npx --yes n8nac execution get <execId> --include-data --json
# Credential management (resolve Class A without UI)
npx --yes n8nac workflow credential-required <id> --json
npx --yes n8nac credential schema <type>
npx --yes n8nac credential list --json
npx --yes n8nac credential create --type <type> --name <name> --file cred.json --json
# Workflow lifecycle
npx --yes n8nac workflow activate <id>
npx --yes n8nac workflow deactivate <id>
# Documentation
npx --yes n8nac skills docs "OpenAI"
npx --yes n8nac skills guides "webhook"
When in doubt:
npx --yes n8nac skills node-info <nodeName>— the schema is always the source of truth.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.