@n8n-as-code/n8nac 2.0.0-next.56
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/CHANGELOG.md +42 -0
- package/README.md +170 -0
- package/index.ts +137 -0
- package/openclaw.plugin.json +19 -0
- package/package.json +52 -0
- package/skills/n8n-architect/SKILL.md +379 -0
- package/skills/n8n-manager/SKILL.md +116 -0
- package/src/cli.ts +24 -0
- package/src/workspace.ts +53 -0
- package/tsconfig.json +18 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @n8n-as-code/n8nac
|
|
2
|
+
|
|
3
|
+
## [2026.5.0](https://github.com/EtienneLescot/n8n-as-code/compare/@n8n-as-code/n8nac@v2026.4.1...@n8n-as-code/n8nac@v2026.5.0) (2026-03-31)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* add integration tests for CLI instance management and update AI functionality ([f3131de](https://github.com/EtienneLescot/n8n-as-code/commit/f3131de6f74c28875e8264c5ac929291046cee7b))
|
|
8
|
+
* add agent-friendly instance management flows ([3d63571](https://github.com/EtienneLescot/n8n-as-code/commit/3d63571e1c5243e58a51a93b0c0b927946be86bf))
|
|
9
|
+
* extend instance library to plugins docs and integration tests ([3f97f54](https://github.com/EtienneLescot/n8n-as-code/commit/3f97f54869ddf99cd8c9b3837cf7ec94d35dccb5))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* address PR review feedback for instance config flows ([06f0298](https://github.com/EtienneLescot/n8n-as-code/commit/06f029828969da738b154cf65f64461c8bda5571))
|
|
14
|
+
|
|
15
|
+
### Documentation
|
|
16
|
+
|
|
17
|
+
* align config flows across product surfaces ([d961f78](https://github.com/EtienneLescot/n8n-as-code/commit/d961f783e1b95022acdbf3f13ca0982520026619))
|
|
18
|
+
|
|
19
|
+
## [2026.4.1](https://github.com/EtienneLescot/n8n-as-code/compare/@n8n-as-code/n8nac@v2026.4.0...@n8n-as-code/n8nac@v2026.4.1) (2026-03-30)
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* make agent workflow testing and sync state resilient ([5850d07](https://github.com/EtienneLescot/n8n-as-code/commit/5850d07d8136ffb24c5106c7391b2d49d4dd2e5d))
|
|
24
|
+
|
|
25
|
+
## [2026.4.0](https://github.com/EtienneLescot/n8n-as-code/compare/@n8n-as-code/n8nac@v2026.3.1...@n8n-as-code/n8nac@v2026.4.0) (2026-03-17)
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
* scope OpenClaw n8n context via bundled skill ([abf1501](https://github.com/EtienneLescot/n8n-as-code/commit/abf15012e2d5f5cab9bd04fc930fe27b4fd48802))
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* tighten getChildEnv() allowlist + add unit tests ([2846414](https://github.com/EtienneLescot/n8n-as-code/commit/28464143bfb3390d51db6303bb377783a2994cfb))
|
|
34
|
+
* prevent credential forwarding to child processes via explicit env filtering ([283d005](https://github.com/EtienneLescot/n8n-as-code/commit/283d0059a1fcf33d70ec27d4485333e4441be240))
|
|
35
|
+
* refresh generated OpenClaw skill output ([b1f1eac](https://github.com/EtienneLescot/n8n-as-code/commit/b1f1eacb7bf1a988e19f42bdc86bb9088691cbae))
|
|
36
|
+
* generate OpenClaw skill from shared SSOT ([b6678bd](https://github.com/EtienneLescot/n8n-as-code/commit/b6678bd45c7da338b5ea4b6d5082be8b6d5105d4))
|
|
37
|
+
|
|
38
|
+
## [2026.3.1](https://github.com/EtienneLescot/n8n-as-code/compare/@n8n-as-code/n8nac@v2026.3.0...@n8n-as-code/n8nac@v2026.3.1) (2026-03-13)
|
|
39
|
+
|
|
40
|
+
### Documentation
|
|
41
|
+
|
|
42
|
+
* align editor and integration release messaging ([e1d6198](https://github.com/EtienneLescot/n8n-as-code/commit/e1d6198c3c6c942afe024f34b4ad419005ed991c))
|
package/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# @n8n-as-code/n8nac
|
|
2
|
+
|
|
3
|
+
**OpenClaw access to the standard `n8n-as-code` skills and workflow stack.**
|
|
4
|
+
|
|
5
|
+
Use OpenClaw to build, update, validate, and manage n8n workflows with the same `n8nac` CLI and AI context model used across the wider `n8n-as-code` project.
|
|
6
|
+
|
|
7
|
+
## v2 migration note
|
|
8
|
+
|
|
9
|
+
Version 2 removes the facade-specific OpenClaw runtime tool path. The plugin now delegates instance, auth, project, tunnel, credential, and presentation operations to `n8n-manager`, while workspace sync context is stored through `n8nac workspace` in `~/.openclaw/n8nac/`.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
openclaw plugins install @n8n-as-code/n8nac
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
If you previously installed `@n8n-as-code/openclaw-plugin`, remove the old install first so OpenClaw re-registers the plugin cleanly under `n8nac`:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
openclaw plugins uninstall n8nac
|
|
21
|
+
openclaw plugins install @n8n-as-code/n8nac
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Restart the gateway. Runtime access, project selection, workspace sync, and
|
|
25
|
+
workflow guidance are handled by the bundled `n8n-manager` and `n8n-architect`
|
|
26
|
+
skills through their documented shell commands.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Once the runtime and workspace are configured through the skills, talk to OpenClaw:
|
|
31
|
+
|
|
32
|
+
> "Create an n8n workflow that sends a Slack message when a GitHub issue is opened"
|
|
33
|
+
|
|
34
|
+
> "Pull workflow 42 and add an error handler to it"
|
|
35
|
+
|
|
36
|
+
> "What operations does the Google Sheets node support?"
|
|
37
|
+
|
|
38
|
+
The plugin keeps its prompt hook lightweight. OpenClaw uses the bundled
|
|
39
|
+
`n8n-manager` and `n8n-architect` skills for explicit n8n sessions. Those
|
|
40
|
+
skills use the same shell commands as Claude, Codex, Cursor, VS Code, and other
|
|
41
|
+
agents: `n8n-manager ...` and `n8nac ...`.
|
|
42
|
+
|
|
43
|
+
## CLI commands
|
|
44
|
+
|
|
45
|
+
| Command | Description |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `openclaw n8nac:status` | Show workspace status |
|
|
48
|
+
|
|
49
|
+
## Workspace
|
|
50
|
+
|
|
51
|
+
All files live in `~/.openclaw/n8nac/`:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
~/.openclaw/n8nac/
|
|
55
|
+
n8nac-config.json ← workspace project/sync overrides only
|
|
56
|
+
AGENTS.md ← lightweight agent bootstrap (written by n8nac update-ai)
|
|
57
|
+
.agents/skills/ ← portable n8n-manager + n8n-architect skills
|
|
58
|
+
workflows/ ← .workflow.ts files (your n8n workflows)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Instances and API keys are not stored in this workspace. They live in the global
|
|
62
|
+
`n8n-manager` configuration under `~/.n8n-manager`.
|
|
63
|
+
|
|
64
|
+
## Agent skills
|
|
65
|
+
|
|
66
|
+
The plugin does not register a facade-specific agent tool. Agents should use
|
|
67
|
+
the portable skills and shell commands directly:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
n8n-manager instances list
|
|
71
|
+
n8nac workspace status --json
|
|
72
|
+
n8nac list
|
|
73
|
+
n8nac pull <workflowId>
|
|
74
|
+
n8nac push <path-to-workflow.workflow.ts> --verify
|
|
75
|
+
n8nac skills node-info <nodeName>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`AGENTS.md` is not a configuration source of truth. It points agents to the
|
|
79
|
+
local skills and to `n8nac workspace status --json`, which resolves the
|
|
80
|
+
effective context through the backend.
|
|
81
|
+
|
|
82
|
+
## Local development
|
|
83
|
+
|
|
84
|
+
This section covers how to load the plugin from source during development so
|
|
85
|
+
that changes take effect immediately without an npm publish cycle.
|
|
86
|
+
|
|
87
|
+
### 1. Link the plugin directory
|
|
88
|
+
|
|
89
|
+
OpenClaw's `--link` flag registers a local path instead of installing a copy.
|
|
90
|
+
jiti is used to run TypeScript directly, so no build step is needed.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
openclaw plugins install --link \
|
|
94
|
+
/home/etienne/repos/n8n-as-code/plugins/openclaw/n8n-as-code
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
What this does:
|
|
98
|
+
- Adds the path to `plugins.load.paths` in `~/.openclaw/openclaw.json`
|
|
99
|
+
- Registers a `source: "path"` install record bound to the plugin ID `n8nac`
|
|
100
|
+
- No file copy — OpenClaw loads `index.ts` directly from the source tree
|
|
101
|
+
|
|
102
|
+
### 2. Verify the plugin is registered
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
openclaw plugins info n8nac
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
You should see status `loaded`, the bundled skills, and the `n8nac:status` CLI
|
|
109
|
+
command. The plugin intentionally does not register a
|
|
110
|
+
facade-specific agent tool.
|
|
111
|
+
|
|
112
|
+
### 3. Configure runtime access through skills
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
n8n-manager auth set --url <url> --api-key-stdin
|
|
116
|
+
n8n-manager projects list
|
|
117
|
+
n8n-manager projects select <project-id-or-name>
|
|
118
|
+
n8nac workspace set-sync-folder workflows
|
|
119
|
+
n8nac update-ai
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The OpenClaw plugin does not own setup orchestration. It exposes lightweight
|
|
123
|
+
context and lets the portable skills manage global instances, secrets, projects,
|
|
124
|
+
workspace overrides, `AGENTS.md`, and `.agents/skills`.
|
|
125
|
+
|
|
126
|
+
### 4. Iterate on the code
|
|
127
|
+
|
|
128
|
+
- Edit any `.ts` file in `plugins/openclaw/n8n-as-code/`
|
|
129
|
+
- **Restart the gateway** to reload: `openclaw stop && openclaw start` (or the
|
|
130
|
+
equivalent service restart on your setup)
|
|
131
|
+
- The `before_prompt_build` hook and CLI commands reload on
|
|
132
|
+
gateway start
|
|
133
|
+
|
|
134
|
+
### 5. Check gateway logs
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
tail -f ~/.openclaw/logs/openclaw-$(date +%Y-%m-%d).log | grep n8nac
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The plugin prefixes all `api.logger` calls with `[n8nac]`.
|
|
141
|
+
|
|
142
|
+
### 6. Inspect the n8nac workspace
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
~/.openclaw/n8nac/
|
|
146
|
+
n8nac-config.json ← workspace project/sync overrides only
|
|
147
|
+
AGENTS.md ← lightweight bootstrap written by update-ai
|
|
148
|
+
.agents/skills/ ← portable skills written by update-ai
|
|
149
|
+
workflows/ ← .workflow.ts files
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
To reset and redo setup from scratch:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
rm -rf ~/.openclaw/n8nac
|
|
156
|
+
n8nac workspace set-sync-folder workflows
|
|
157
|
+
n8nac update-ai
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 7. Unlink when done
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
openclaw plugins uninstall n8nac
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Source
|
|
169
|
+
|
|
170
|
+
Part of the [n8n-as-code](https://github.com/EtienneLescot/n8n-as-code) monorepo.
|
package/index.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { accessSync, constants, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { N8N_FACADE_SETUP_MODES } from "@n8n-as-code/workflow-core";
|
|
4
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
5
|
+
import { registerN8nAcCli } from "./src/cli.js";
|
|
6
|
+
import { getWorkspaceDir, isWorkspaceInitialized, readWorkspaceBinding } from "./src/workspace.js";
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Lightweight prompt context
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const SETUP_MODE_CONTEXT = N8N_FACADE_SETUP_MODES
|
|
13
|
+
.map((mode) => `- \`${mode.id}\`: ${mode.description}`)
|
|
14
|
+
.join("\n");
|
|
15
|
+
|
|
16
|
+
const BOOTSTRAP_CONTEXT = `\
|
|
17
|
+
## n8n-as-code — Bootstrap
|
|
18
|
+
|
|
19
|
+
The n8n-as-code plugin is installed but the workspace has not been initialized yet.
|
|
20
|
+
|
|
21
|
+
**Tell the user:**
|
|
22
|
+
> "To start building n8n workflows, choose whether I should connect to your existing n8n access, let n8n-manager prepare runtime access, or stay in generation-only mode."
|
|
23
|
+
|
|
24
|
+
Supported facade runtime modes:
|
|
25
|
+
${SETUP_MODE_CONTEXT}
|
|
26
|
+
|
|
27
|
+
For agent-driven flows, use the installed \`n8n-manager\` and \`n8n-architect\`
|
|
28
|
+
skills and their documented shell commands. Instance/auth/project management
|
|
29
|
+
belongs to \`n8n-manager\`; context-root overrides and workflow sync belong
|
|
30
|
+
to \`n8nac workspace\` and the n8n-as-code skills.
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
function buildStatusHeader(workspaceDir: string): string {
|
|
34
|
+
const cfg = readWorkspaceBinding(workspaceDir);
|
|
35
|
+
return [
|
|
36
|
+
"## n8n-as-code Context Root Status",
|
|
37
|
+
"",
|
|
38
|
+
"**The context root is initialized. Do NOT infer effective n8n config from this prompt.**",
|
|
39
|
+
"",
|
|
40
|
+
`- Context root: \`${workspaceDir}\``,
|
|
41
|
+
`- Local overrides file: \`${join(workspaceDir, "n8nac-config.json")}\``,
|
|
42
|
+
`- Bootstrap file: \`${join(workspaceDir, "AGENTS.md")}\``,
|
|
43
|
+
"",
|
|
44
|
+
"Before n8n work, run `n8nac workspace status --json` from the context root and use the backend-resolved result.",
|
|
45
|
+
cfg.activeInstanceId || cfg.projectId || cfg.projectName || cfg.syncFolder
|
|
46
|
+
? "The local overrides file exists, but n8n-manager plus n8nac backend resolution remains the only source of effective state."
|
|
47
|
+
: "The local overrides file is present but incomplete.",
|
|
48
|
+
].join("\n");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function hasAgentsContext(workspaceDir: string): boolean {
|
|
52
|
+
const agentsPath = join(workspaceDir, "AGENTS.md");
|
|
53
|
+
try {
|
|
54
|
+
accessSync(agentsPath, constants.R_OK);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function buildPromptContext(workspaceDir: string): string {
|
|
62
|
+
if (!isWorkspaceInitialized(workspaceDir)) {
|
|
63
|
+
return BOOTSTRAP_CONTEXT;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const agentsPath = join(workspaceDir, "AGENTS.md");
|
|
67
|
+
const guidanceLines = hasAgentsContext(workspaceDir)
|
|
68
|
+
? [
|
|
69
|
+
"",
|
|
70
|
+
"Detailed workflow-authoring guidance is intentionally scoped to the `n8n-architect` skill.",
|
|
71
|
+
"Only use that deeper n8n workflow context when the request is clearly about n8n workflow work.",
|
|
72
|
+
`When that happens, read \`${agentsPath}\` and the local \`${join(workspaceDir, ".agents", "skills")}\` skills.`,
|
|
73
|
+
]
|
|
74
|
+
: [
|
|
75
|
+
"",
|
|
76
|
+
"Detailed workflow-authoring guidance is intentionally scoped to the `n8n-architect` skill, but the generated workspace AI context file (`AGENTS.md`) is missing.",
|
|
77
|
+
"If the user starts explicit n8n workflow work, use the n8n-manager and n8n-architect skills to configure access and regenerate `AGENTS.md` with `npx --yes n8nac update-ai` when needed.",
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
return [
|
|
81
|
+
buildStatusHeader(workspaceDir),
|
|
82
|
+
...guidanceLines,
|
|
83
|
+
"",
|
|
84
|
+
"For unrelated requests, ignore this plugin context.",
|
|
85
|
+
].join("\n");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Plugin
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
const n8nAcPlugin = {
|
|
93
|
+
id: "n8nac",
|
|
94
|
+
name: "n8n-as-code",
|
|
95
|
+
description:
|
|
96
|
+
"Create and manage n8n workflows from OpenClaw using n8n-as-code (n8nac). " +
|
|
97
|
+
"Guides through workspace initialization, workflow CRUD, and AI-powered node schema lookup.",
|
|
98
|
+
|
|
99
|
+
register(api: OpenClawPluginApi) {
|
|
100
|
+
const workspaceDir = getWorkspaceDir();
|
|
101
|
+
|
|
102
|
+
// Ensure the plugin workspace directory always exists.
|
|
103
|
+
mkdirSync(workspaceDir, { recursive: true });
|
|
104
|
+
|
|
105
|
+
// -- Context injection ---------------------------------------------------
|
|
106
|
+
// Keep default context lightweight; full workflow-authoring guidance lives
|
|
107
|
+
// in the bundled skills and the context-root AGENTS.md file.
|
|
108
|
+
api.on("before_prompt_build", () => {
|
|
109
|
+
return { prependContext: buildPromptContext(workspaceDir) };
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// -- CLI status ----------------------------------------------------------
|
|
113
|
+
api.registerCli(
|
|
114
|
+
({ program }) => registerN8nAcCli({ program, workspaceDir }),
|
|
115
|
+
{ commands: ["n8nac:status"] },
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// -- Service -------------------------------------------------------------
|
|
119
|
+
api.registerService({
|
|
120
|
+
id: "n8nac-context",
|
|
121
|
+
start: async () => {
|
|
122
|
+
if (isWorkspaceInitialized(workspaceDir)) {
|
|
123
|
+
if (hasAgentsContext(workspaceDir)) {
|
|
124
|
+
api.logger.info("[n8nac] Workspace ready — lightweight prompt context enabled; n8n skill available.");
|
|
125
|
+
} else {
|
|
126
|
+
api.logger.warn("[n8nac] Workspace ready, but AGENTS.md is missing or unreadable.");
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
api.logger.info("[n8nac] Workspace not initialized. Use the n8n-manager and n8n-architect skills to configure it.");
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
stop: async () => {},
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export default n8nAcPlugin;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "n8nac",
|
|
3
|
+
"name": "n8n-as-code",
|
|
4
|
+
"description": "Create and manage n8n workflows from OpenClaw. Uses n8n-manager for runtime setup and n8nac for workspace/workflow tools.",
|
|
5
|
+
"skills": [
|
|
6
|
+
"skills"
|
|
7
|
+
],
|
|
8
|
+
"configSchema": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"properties": {
|
|
12
|
+
"enabled": {
|
|
13
|
+
"type": "boolean",
|
|
14
|
+
"default": false,
|
|
15
|
+
"description": "Enable the n8n-as-code integration"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@n8n-as-code/n8nac",
|
|
3
|
+
"version": "2.0.0-next.56",
|
|
4
|
+
"description": "OpenClaw plugin for n8n-as-code — create and manage n8n workflows from OpenClaw",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n",
|
|
7
|
+
"workflow",
|
|
8
|
+
"automation",
|
|
9
|
+
"openclaw",
|
|
10
|
+
"openclaw-plugin",
|
|
11
|
+
"n8nac"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/EtienneLescot/n8n-as-code.git",
|
|
16
|
+
"directory": "plugins/openclaw/n8n-as-code"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "npm run typecheck",
|
|
22
|
+
"clean": "rm -rf node_modules/.vitest",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@n8n-as-code/workflow-core": "0.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^22.0.0",
|
|
31
|
+
"openclaw": "^2026.2.26",
|
|
32
|
+
"typescript": "^5.8.0",
|
|
33
|
+
"vitest": "^1.6.1"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"CHANGELOG.md",
|
|
37
|
+
"README.md",
|
|
38
|
+
"index.ts",
|
|
39
|
+
"openclaw.plugin.json",
|
|
40
|
+
"skills/",
|
|
41
|
+
"src/",
|
|
42
|
+
"tsconfig.json"
|
|
43
|
+
],
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"openclaw": ">=2026.2.0"
|
|
46
|
+
},
|
|
47
|
+
"openclaw": {
|
|
48
|
+
"extensions": [
|
|
49
|
+
"./index.ts"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: n8n-architect
|
|
3
|
+
description: Use when the user explicitly wants to create, edit, validate, sync, or troubleshoot n8n workflows, asks about n8n nodes or automation, or wants to use n8n-as-code in the current context root.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# n8n Architect
|
|
7
|
+
|
|
8
|
+
Use this skill for workflow engineering. Use the `n8n-manager` skill for instance, auth, runtime, tunnel, project-default, credential infrastructure, or workflow presentation work.
|
|
9
|
+
|
|
10
|
+
## Context Root Protocol
|
|
11
|
+
|
|
12
|
+
- Treat the current context root as the directory containing `n8nac-config.json`, `AGENTS.md`, `.agents/skills`, and the workflow sync folder.
|
|
13
|
+
- Generated context root hint: not embedded. Use the shell launch directory or the workspace path explicitly given by the user.
|
|
14
|
+
- Before any n8n work, first run `npx --yes n8nac update-ai` from the context root, then read `AGENTS.md`. `update-ai` is designed to create or refresh the n8n-as-code block without destroying existing user or agent instructions.
|
|
15
|
+
- Use the exact `n8nac command` and `n8n-manager command` listed in `AGENTS.md`. Those context-root commands override the portable examples in this skill.
|
|
16
|
+
- Run every `npx --yes n8nac workspace ...`, `npx --yes n8nac list`, `pull`, `push`, `validate`, `test`, and `update-ai` command from the context root unless the user explicitly gives another context root.
|
|
17
|
+
- `AGENTS.md` is bootstrap context only, not a source of configuration truth.
|
|
18
|
+
- Do not infer instance, project, sync folder, or workflow directory from `AGENTS.md`.
|
|
19
|
+
- Before n8n work, resolve the effective context from the backend:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx --yes n8nac workspace status --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- Use the returned `workflowDir` for workflow files. Do not reconstruct it from `syncFolder`, `instanceIdentifier`, or `projectName`.
|
|
26
|
+
- Never write `n8nac-config.json` by hand. Use `npx --yes n8nac workspace ...` commands.
|
|
27
|
+
|
|
28
|
+
## Bootstrap Order
|
|
29
|
+
|
|
30
|
+
1. `cd` to the context root.
|
|
31
|
+
2. Run `npx --yes n8nac update-ai`, then read `AGENTS.md`.
|
|
32
|
+
3. Run `npx --yes n8nac workspace status --json`.
|
|
33
|
+
4. If the context root is not ready, inspect instances with `n8n-manager instances list`.
|
|
34
|
+
5. Reuse an existing instance when suitable.
|
|
35
|
+
6. If no suitable instance exists, stop and ask the user whether they want to reuse/configure an existing instance, create a managed local n8n instance, or connect an existing/remote n8n instance. Do not create infrastructure by default. If the user chooses a managed local instance, ask separately whether they want a public tunnel.
|
|
36
|
+
7. Ask for host/API key only for an explicitly remote or existing n8n instance.
|
|
37
|
+
8. Configure context-root overrides with:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx --yes n8nac workspace pin-instance --instance-id <id>
|
|
41
|
+
npx --yes n8nac workspace set-sync-folder workflows
|
|
42
|
+
npx --yes n8nac workspace set-project --project-id <id> --project-name <name>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For self-hosted n8n instances where the projects API is unavailable or returns 401/403, do not keep retrying project discovery. Use the standard personal project override unless the user gave another project:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx --yes n8nac workspace set-project --project-id personal --project-name Personal
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
9. Run `npx --yes n8nac update-ai` after changing context-root overrides when the facade does not do it automatically.
|
|
52
|
+
|
|
53
|
+
## Sync Discipline
|
|
54
|
+
|
|
55
|
+
- Pull before reading or modifying an existing workflow.
|
|
56
|
+
- Push after every modification.
|
|
57
|
+
- Use `list` to inspect workflow IDs, file paths, and sync status.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx --yes n8nac list
|
|
61
|
+
npx --yes n8nac pull <workflowId>
|
|
62
|
+
npx --yes n8nac push <path-to-workflow.workflow.ts> --verify
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- `push` requires the full workflow file path, either absolute or context-root-relative. Do not pass a bare filename.
|
|
66
|
+
- For a new workflow, create the file inside the `workflowDir` returned by `workspace status --json`, then confirm it with `npx --yes n8nac list --local`.
|
|
67
|
+
- If push/pull reports a conflict, use explicit resolution commands. Do not overwrite remote changes blindly.
|
|
68
|
+
- `pull` and conflict resolution operate on a single workflow ID.
|
|
69
|
+
- `list` is the lightweight command that covers all workflows at once.
|
|
70
|
+
- If you skip pull, a later push can be rejected by optimistic concurrency control when the remote changed.
|
|
71
|
+
|
|
72
|
+
## Conflict Handling
|
|
73
|
+
|
|
74
|
+
If push or pull reports a conflict, stop and inspect the conflict. Use explicit resolution commands only after choosing the intended direction:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx --yes n8nac resolve <workflowId> --mode keep-current
|
|
78
|
+
npx --yes n8nac resolve <workflowId> --mode keep-incoming
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- `keep-current` force-pushes the local version.
|
|
82
|
+
- `keep-incoming` force-pulls the remote version.
|
|
83
|
+
- Never silently force-push over a remote change.
|
|
84
|
+
|
|
85
|
+
## Schema-First Research
|
|
86
|
+
|
|
87
|
+
Never guess n8n node parameters.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx --yes n8nac skills examples search "<workflow pattern>"
|
|
91
|
+
npx --yes n8nac skills search "<node or capability>"
|
|
92
|
+
npx --yes n8nac skills node-info <nodeName>
|
|
93
|
+
npx --yes n8nac skills validate <workflow.workflow.ts>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- Use exact node `type` and valid `typeVersion` values from `node-info`.
|
|
97
|
+
- Use exact resource, operation, option, and parameter names from schema output.
|
|
98
|
+
- Do not invent parameters, operations, credential types, or CLI flags.
|
|
99
|
+
- Treat schema output as the absolute source of truth even if examples or memory disagree.
|
|
100
|
+
- Prefer the highest valid `typeVersion` returned by schema output.
|
|
101
|
+
- For fixed collections such as Switch/If rules, Wait form fields, or nested options, read the full `node-info` output before writing values.
|
|
102
|
+
|
|
103
|
+
## Knowledge Commands
|
|
104
|
+
|
|
105
|
+
Use these commands instead of guessing:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx --yes n8nac skills search "<node or capability>"
|
|
109
|
+
npx --yes n8nac skills node-info <nodeName>
|
|
110
|
+
npx --yes n8nac skills node-schema <nodeName>
|
|
111
|
+
npx --yes n8nac skills docs "<topic>"
|
|
112
|
+
npx --yes n8nac skills guides "<topic>"
|
|
113
|
+
npx --yes n8nac skills examples search "<workflow pattern>"
|
|
114
|
+
npx --yes n8nac skills examples info <id>
|
|
115
|
+
npx --yes n8nac skills examples download <id>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- Start with `examples search` when the user asks for a common automation pattern.
|
|
119
|
+
- Use examples to learn patterns, not as authority over current node schemas.
|
|
120
|
+
- If a command or flag is unfamiliar, run `npx --yes n8nac <subcommand> --help`; do not invent flags.
|
|
121
|
+
|
|
122
|
+
## Workflow Authoring Rules
|
|
123
|
+
|
|
124
|
+
- Use TypeScript decorators from `@n8n-as-code/transformer`.
|
|
125
|
+
- Regular nodes connect with `source.out(0).to(target.in(0))`.
|
|
126
|
+
- AI sub-nodes connect with `.uses()`, never `.out().to()`.
|
|
127
|
+
- `ai_tool` and `ai_document` connections are arrays: `ai_tool: [this.Tool.output]`.
|
|
128
|
+
- Other AI connection types are single refs, such as `ai_languageModel: this.Model.output`.
|
|
129
|
+
- Check `node-info` for connection-dependent boolean flags before declaring `.uses()` connections.
|
|
130
|
+
|
|
131
|
+
Every `.workflow.ts` file starts with a `<workflow-map>` block. Read that map first, locate the property name you need, then read only the relevant class section.
|
|
132
|
+
|
|
133
|
+
### Minimal Workflow Structure
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { workflow, node, links } from '@n8n-as-code/transformer';
|
|
137
|
+
|
|
138
|
+
@workflow({
|
|
139
|
+
name: 'Workflow Name',
|
|
140
|
+
active: false
|
|
141
|
+
})
|
|
142
|
+
export class MyWorkflow {
|
|
143
|
+
@node({
|
|
144
|
+
name: 'Descriptive Name',
|
|
145
|
+
type: '/* exact type from node-info */',
|
|
146
|
+
version: 4,
|
|
147
|
+
position: [250, 300]
|
|
148
|
+
})
|
|
149
|
+
MyNode = {
|
|
150
|
+
/* parameters from node-info */
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
@node({
|
|
154
|
+
name: 'Next Node',
|
|
155
|
+
type: '/* exact type from node-info */',
|
|
156
|
+
version: 3,
|
|
157
|
+
position: [520, 300]
|
|
158
|
+
})
|
|
159
|
+
NextNode = {};
|
|
160
|
+
|
|
161
|
+
@links()
|
|
162
|
+
defineRouting() {
|
|
163
|
+
this.MyNode.out(0).to(this.NextNode.in(0));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Expression Syntax
|
|
169
|
+
|
|
170
|
+
- Prefer modern expressions: `{{ $json.fieldName }}`.
|
|
171
|
+
- Use specific-node expressions when needed: `{{ $('Node Name').item.json.field }}`.
|
|
172
|
+
- Avoid legacy `$node["Name"].json.field` unless you are preserving an existing workflow and have a reason.
|
|
173
|
+
- In Switch/If comparisons, `value1` is the expression being evaluated and `value2` is the literal comparison value.
|
|
174
|
+
|
|
175
|
+
### Node Naming
|
|
176
|
+
|
|
177
|
+
- Use descriptive names such as `Get Customers`, `Send Slack Alert`, or `Normalize Payload`.
|
|
178
|
+
- Avoid names like `Node1`, `HTTP Request`, or `Code` when a more specific name is available.
|
|
179
|
+
- Connection references must match the exact node property names in the TypeScript class.
|
|
180
|
+
|
|
181
|
+
## Reading Workflow Files Efficiently
|
|
182
|
+
|
|
183
|
+
Use the `<workflow-map>` block as the index before loading large workflow files.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// <workflow-map>
|
|
187
|
+
// Workflow : My Workflow
|
|
188
|
+
// Nodes : 12 | Connections: 14
|
|
189
|
+
//
|
|
190
|
+
// NODE INDEX
|
|
191
|
+
// Property name Node type (short) Flags
|
|
192
|
+
// ScheduleTrigger scheduleTrigger
|
|
193
|
+
// AgentGenerateApplication agent [AI] [creds]
|
|
194
|
+
// OpenaiChatModel lmChatOpenAi [creds] [ai_languageModel]
|
|
195
|
+
// Memory memoryBufferWindow [ai_memory]
|
|
196
|
+
// GithubCheckBranchRef httpRequest [onError->out(1)]
|
|
197
|
+
//
|
|
198
|
+
// ROUTING MAP
|
|
199
|
+
// ScheduleTrigger
|
|
200
|
+
// -> Configuration
|
|
201
|
+
// -> BuildProfileSources -> LoopOverProfileSources
|
|
202
|
+
//
|
|
203
|
+
// AI CONNECTIONS
|
|
204
|
+
// AgentGenerateApplication.uses({ ai_languageModel: OpenaiChatModel, ai_memory: Memory })
|
|
205
|
+
// </workflow-map>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Navigation rule:
|
|
209
|
+
|
|
210
|
+
1. Read `<workflow-map>` first.
|
|
211
|
+
2. Locate the property name you need.
|
|
212
|
+
3. Search for that property in the file.
|
|
213
|
+
4. Read only the relevant node or routing section unless broader context is required.
|
|
214
|
+
|
|
215
|
+
## AI And LangChain Node Rules
|
|
216
|
+
|
|
217
|
+
AI sub-nodes are not regular data-flow nodes.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
@links()
|
|
221
|
+
defineRouting() {
|
|
222
|
+
this.ChatTrigger.out(0).to(this.AiAgent.in(0));
|
|
223
|
+
|
|
224
|
+
this.AiAgent.uses({
|
|
225
|
+
ai_languageModel: this.OpenaiModel.output,
|
|
226
|
+
ai_memory: this.Memory.output,
|
|
227
|
+
ai_outputParser: this.OutputParser.output,
|
|
228
|
+
ai_tool: [this.SearchTool.output],
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
- Use `.uses()` for language models, memory, tools, parsers, embeddings, vector stores, retrievers, and other AI sub-nodes.
|
|
234
|
+
- Never connect AI sub-nodes with `.out().to()`.
|
|
235
|
+
- `ai_tool` and `ai_document` must be arrays.
|
|
236
|
+
- Most other AI connection types are single refs.
|
|
237
|
+
- Some nodes require boolean flags to expose AI ports or gated parameters. Check `node-info` before declaring `.uses()`.
|
|
238
|
+
|
|
239
|
+
## Common Mistakes To Avoid
|
|
240
|
+
|
|
241
|
+
- Wrong node type: use the exact full type returned by schema output, including package prefix when provided.
|
|
242
|
+
- Outdated or non-existent typeVersion: use a value from the schema output.
|
|
243
|
+
- Invalid operation/resource value: use exact option values from the schema.
|
|
244
|
+
- Mismatched resource and operation: each resource enables its own operations.
|
|
245
|
+
- Guessing nested structures: fixed collections have exact shapes.
|
|
246
|
+
- Wrong connection names: match TypeScript property names exactly.
|
|
247
|
+
- Inventing nodes, credentials, operations, or parameters.
|
|
248
|
+
- Connecting AI sub-nodes with `.out().to()`.
|
|
249
|
+
- Using `ai_tool: this.Tool.output` instead of `ai_tool: [this.Tool.output]`.
|
|
250
|
+
- Inverting Switch/If `value1` and `value2`.
|
|
251
|
+
- Using old Wait form structures such as `formFieldsUi.fieldItems` when the current schema expects `formFields: { values: [...] }`.
|
|
252
|
+
- Passing a bare filename to `push`.
|
|
253
|
+
- Treating Class A runtime/config gaps as workflow-code bugs.
|
|
254
|
+
|
|
255
|
+
## Verify, Test, And Present
|
|
256
|
+
|
|
257
|
+
After pushing:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
npx --yes n8nac verify <workflowId>
|
|
261
|
+
npx --yes n8nac test-plan <workflowId> --json
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
For webhook, chat, or form workflows, prefer the production test sequence:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
npx --yes n8nac workflow activate <workflowId>
|
|
268
|
+
npx --yes n8nac test <workflowId> --prod
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
- Class A configuration gaps require user/config action, not workflow rewrites.
|
|
272
|
+
- Runtime-state issues such as unarmed test webhooks are not workflow-code bugs.
|
|
273
|
+
- Class B wiring errors are fixable in the workflow file.
|
|
274
|
+
- Stop after two repeated failures with the same diagnostic.
|
|
275
|
+
|
|
276
|
+
## Workflow Presentation Contract
|
|
277
|
+
|
|
278
|
+
`presentWorkflowResult` is the standard way to show a workflow to the user. It is part of the workflow authoring loop, even though the command lives in n8n-manager.
|
|
279
|
+
|
|
280
|
+
Run it whenever one of these is true:
|
|
281
|
+
|
|
282
|
+
- you created a workflow;
|
|
283
|
+
- you modified and pushed a workflow;
|
|
284
|
+
- you ran or tested a workflow and the user needs to inspect it;
|
|
285
|
+
- the user asks to show, open, present, display, or give the URL/link for a workflow.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
n8n-manager presentWorkflowResult --workflow-id <workflowId> --workspace-root <contextRoot>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Rules:
|
|
292
|
+
|
|
293
|
+
- Do not manually construct n8n workflow URLs.
|
|
294
|
+
- Do not return an internal local n8n URL when a presentation URL is available.
|
|
295
|
+
- Use the `url` returned by `presentWorkflowResult` as the user-facing URL.
|
|
296
|
+
- If you do not know the workflow ID, run `npx --yes n8nac list` first and select the matching workflow.
|
|
297
|
+
- If `presentWorkflowResult` fails, report the backend diagnostic and then provide the best direct n8n URL only as a fallback.
|
|
298
|
+
- Do this before the final response when the task created, changed, pushed, ran, or explicitly asks to show a workflow.
|
|
299
|
+
|
|
300
|
+
### Testability Protocol
|
|
301
|
+
|
|
302
|
+
For webhook, chat, or form workflows:
|
|
303
|
+
|
|
304
|
+
1. Push with verification when possible.
|
|
305
|
+
2. Run `test-plan` to inspect trigger type, endpoint, and suggested payload.
|
|
306
|
+
3. Activate the workflow.
|
|
307
|
+
4. Test with `--prod` by default.
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
npx --yes n8nac push <path-to-workflow.workflow.ts> --verify
|
|
311
|
+
npx --yes n8nac test-plan <workflowId> --json
|
|
312
|
+
npx --yes n8nac workflow activate <workflowId>
|
|
313
|
+
npx --yes n8nac test <workflowId> --prod
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Use bare `npx --yes n8nac test <workflowId>` only when a test URL was intentionally armed in the n8n editor.
|
|
317
|
+
|
|
318
|
+
For GET/HEAD webhooks that read from `$json.query`, prefer:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
npx --yes n8nac test <workflowId> --query '{"key":"value"}' --prod
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Execution Debugging
|
|
325
|
+
|
|
326
|
+
If a webhook returns success but the workflow behavior is wrong, inspect executions instead of guessing:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
npx --yes n8nac execution list --workflow-id <workflowId> --limit 5 --json
|
|
330
|
+
npx --yes n8nac execution get <executionId> --include-data --json
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
- A successful HTTP trigger only means n8n accepted the request.
|
|
334
|
+
- The execution can still fail later inside the workflow.
|
|
335
|
+
- Use execution data to identify the failing node and real payload shape.
|
|
336
|
+
|
|
337
|
+
## Credential Workflow
|
|
338
|
+
|
|
339
|
+
When a workflow is blocked by missing credentials, resolve the credential gap without rewriting unrelated workflow logic.
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
npx --yes n8nac workflow credential-required <workflowId> --json
|
|
343
|
+
npx --yes n8nac credential schema <type>
|
|
344
|
+
npx --yes n8nac credential list --json
|
|
345
|
+
npx --yes n8nac credential create --type <type> --name <name> --file cred.json --json
|
|
346
|
+
npx --yes n8nac workflow activate <workflowId>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
- `workflow credential-required` exits non-zero when at least one credential is missing. Treat that as a signal to act, not as a workflow-code failure.
|
|
350
|
+
- Use `credential schema` to discover required fields.
|
|
351
|
+
- Ask the user for secret values when needed.
|
|
352
|
+
- Prefer `--file` for credential creation. Do not pass secrets inline in shell arguments.
|
|
353
|
+
- Do not print API keys or credential secret values back to the user.
|
|
354
|
+
- If credential creation fails, read the validation message and change the payload before retrying.
|
|
355
|
+
|
|
356
|
+
## Operating Loop
|
|
357
|
+
|
|
358
|
+
For most workflow tasks:
|
|
359
|
+
|
|
360
|
+
1. Resolve context with `workspace status --json`.
|
|
361
|
+
2. Read `workflowDir` from the backend response.
|
|
362
|
+
3. Inspect existing workflows with `list`.
|
|
363
|
+
4. Pull before editing an existing workflow.
|
|
364
|
+
5. Search examples and schemas.
|
|
365
|
+
6. Edit or create the `.workflow.ts` file.
|
|
366
|
+
7. Validate locally.
|
|
367
|
+
8. Push with `--verify`.
|
|
368
|
+
9. Test if the workflow is HTTP-triggered.
|
|
369
|
+
10. Inspect executions when behavior is unclear.
|
|
370
|
+
11. Present the final workflow link with `presentWorkflowResult`.
|
|
371
|
+
|
|
372
|
+
## Response Discipline
|
|
373
|
+
|
|
374
|
+
- Explain concrete actions and command results, not generic capability.
|
|
375
|
+
- When the user asks for an URL or visual inspection of a workflow, run `presentWorkflowResult` instead of composing a URL manually.
|
|
376
|
+
- If setup is missing, use `n8n-manager` for instance/auth/runtime and `n8nac workspace ...` for context-root overrides.
|
|
377
|
+
- Do not ask for host/API key until existing n8n-manager instances have been inspected.
|
|
378
|
+
- Do not tell the user to run setup commands when you can run non-interactive commands yourself.
|
|
379
|
+
- Stop after two repeated failures with the same diagnostic and report the backend error clearly.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: n8n-manager
|
|
3
|
+
description: Use when the user needs n8n instance, runtime, tunnel, auth, project, credential, or workflow presentation management through n8n-manager.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# n8n Manager
|
|
7
|
+
|
|
8
|
+
Use this skill for global n8n instance management. `n8n-manager` is the source of truth for instances, runtime state, tunnels, API keys, managed owner credentials, default projects, and workflow presentation links.
|
|
9
|
+
|
|
10
|
+
## Responsibility Boundary
|
|
11
|
+
|
|
12
|
+
- Generated context root hint: not embedded. Use the shell launch directory or the workspace path explicitly given by the user.
|
|
13
|
+
- If `n8nac` is available, first run `npx --yes n8nac update-ai` from the context root, then read `AGENTS.md`. `update-ai` is designed to create or refresh the n8n-as-code block without destroying existing user or agent instructions.
|
|
14
|
+
- Use the exact `n8n-manager command` and `n8nac command` listed in `AGENTS.md` when present. Those context-root commands override the portable examples in this skill.
|
|
15
|
+
- Use `n8n-manager` for global instance, auth, runtime, tunnel, project-default, credential, and workflow-presentation operations.
|
|
16
|
+
- Use `npx --yes n8nac workspace ...` only for context-root overrides such as pinned instance, sync folder, and project override.
|
|
17
|
+
- Use `npx --yes n8nac` workflow commands only after the effective context is ready.
|
|
18
|
+
- Never edit `n8nac-config.json`, `~/.n8n-manager`, or n8n-manager secret files by hand.
|
|
19
|
+
|
|
20
|
+
## Core Commands
|
|
21
|
+
|
|
22
|
+
Inspect existing instances before changing state:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
n8n-manager instances list
|
|
26
|
+
n8n-manager instances --help
|
|
27
|
+
n8n-manager config get
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Do not invent n8n-manager subcommands. In particular, `instances create` and `--type local` are not valid. Use `instances add --mode ...` exactly as documented by `instances --help`.
|
|
31
|
+
|
|
32
|
+
## Unconfigured Context Root
|
|
33
|
+
|
|
34
|
+
When the context root is not configured and no suitable existing instance is available, stop and ask the user to choose. Do not create infrastructure by default.
|
|
35
|
+
|
|
36
|
+
Present these choices clearly:
|
|
37
|
+
|
|
38
|
+
- use an existing n8n-manager instance if one is available;
|
|
39
|
+
- create a new managed local Docker n8n instance;
|
|
40
|
+
- connect an existing or remote n8n instance with user-provided credentials.
|
|
41
|
+
|
|
42
|
+
If the user chooses a managed local Docker instance, ask the tunnel question separately:
|
|
43
|
+
|
|
44
|
+
- without public tunnel: local n8n only, suitable for normal UI/API workflow work;
|
|
45
|
+
- with public tunnel: exposes the instance through a public URL, useful for webhooks/forms/chat triggers and remote callbacks.
|
|
46
|
+
|
|
47
|
+
Do not enable, refresh, or start a public tunnel unless the user explicitly requested public access, webhook testing, or approved the tunnel option. If public access is not needed, create/start the managed instance without `--tunnel`.
|
|
48
|
+
|
|
49
|
+
## Confirmed Setup Commands
|
|
50
|
+
|
|
51
|
+
Only run these commands after the user has explicitly chosen the corresponding option.
|
|
52
|
+
|
|
53
|
+
Managed local Docker without public tunnel:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
n8n-manager instances add --name <name> --mode managed-local-docker
|
|
57
|
+
n8n-manager instances setup <id-or-name>
|
|
58
|
+
n8n-manager instances start <id-or-name>
|
|
59
|
+
n8n-manager instances status <id-or-name>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Managed local Docker with public tunnel:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
n8n-manager instances add --name <name> --mode managed-local-docker --tunnel
|
|
66
|
+
n8n-manager instances setup <id-or-name> --tunnel
|
|
67
|
+
n8n-manager instances start <id-or-name>
|
|
68
|
+
n8n-manager instances tunnel status <id-or-name>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Remote or existing instances require user-provided credentials. Prefer stdin for API keys:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
n8n-manager auth set --url <url> --api-key-stdin --name <name>
|
|
75
|
+
n8n-manager auth test --instance <id-or-name>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Project selection is instance-level unless the context root explicitly needs a workspace override:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
n8n-manager projects list --instance <id-or-name>
|
|
82
|
+
n8n-manager projects select <project-id-or-name> --instance <id-or-name>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Self-hosted n8n may not expose the projects API or may return 401/403. In that case, do not retry project discovery. Use the n8n-architect workspace override path with the standard personal project unless the user gave another project:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx --yes n8nac workspace set-project --project-id personal --project-name Personal
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Runtime and tunnel operations are per instance:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
n8n-manager instances start <id-or-name>
|
|
95
|
+
n8n-manager instances stop <id-or-name>
|
|
96
|
+
n8n-manager instances restart <id-or-name>
|
|
97
|
+
n8n-manager instances tunnel status <id-or-name>
|
|
98
|
+
n8n-manager instances tunnel start <id-or-name>
|
|
99
|
+
n8n-manager instances tunnel refresh <id-or-name>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Present workflow results after creating, modifying, pushing, or running a workflow:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
n8n-manager presentWorkflowResult --workflow-id <workflowId> --workspace-root <contextRoot>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Guardrails
|
|
109
|
+
|
|
110
|
+
- Do not ask for host/API key before checking `instances list`.
|
|
111
|
+
- Do not ask for host/API key when the user wants a managed local Docker instance.
|
|
112
|
+
- Do not print API keys back to the user.
|
|
113
|
+
- Do not delete runtime data unless the user explicitly asks for destructive deletion.
|
|
114
|
+
- If Docker is unavailable or the daemon is stopped, report the backend diagnostic and stop. Do not loop.
|
|
115
|
+
- If a command fails repeatedly, stop after two attempts and explain the backend diagnostic.
|
|
116
|
+
- For workflow credentials, inspect the required credential type before asking for secret values.
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import { isWorkspaceInitialized } from "./workspace.js";
|
|
3
|
+
|
|
4
|
+
type CliProgram = Parameters<Parameters<OpenClawPluginApi["registerCli"]>[0]>[0]["program"];
|
|
5
|
+
|
|
6
|
+
type CliOpts = {
|
|
7
|
+
program: CliProgram;
|
|
8
|
+
workspaceDir: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function registerN8nAcCli({ program, workspaceDir }: CliOpts): void {
|
|
12
|
+
program
|
|
13
|
+
.command("n8nac:status")
|
|
14
|
+
.description("Show n8n-as-code workspace status")
|
|
15
|
+
.action(() => {
|
|
16
|
+
const initialized = isWorkspaceInitialized(workspaceDir);
|
|
17
|
+
console.log(`\nn8n-as-code workspace: ${workspaceDir}`);
|
|
18
|
+
console.log(`Status: ${initialized ? "✓ Initialized" : "✗ Not initialized"}`);
|
|
19
|
+
if (!initialized) {
|
|
20
|
+
console.log("\nUse the n8n-manager and n8n-architect skills to configure runtime access and workflow guidance.");
|
|
21
|
+
}
|
|
22
|
+
console.log();
|
|
23
|
+
});
|
|
24
|
+
}
|
package/src/workspace.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
|
|
5
|
+
export type WorkspaceBinding = {
|
|
6
|
+
projectId?: string;
|
|
7
|
+
projectName?: string;
|
|
8
|
+
syncFolder?: string;
|
|
9
|
+
activeInstanceId?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fixed context-root directory for V1.
|
|
14
|
+
* All n8nac context files (n8nac-config.json, AGENTS.md, .agents/skills, workflows/) live here.
|
|
15
|
+
* n8n instances and credentials are stored globally by n8n-manager.
|
|
16
|
+
*/
|
|
17
|
+
export function getWorkspaceDir(): string {
|
|
18
|
+
return join(homedir(), ".openclaw", "n8nac");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function readString(value: unknown): string {
|
|
22
|
+
return typeof value === "string" ? value.trim() : "";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function readWorkspaceBinding(workspaceDir: string): WorkspaceBinding {
|
|
26
|
+
const configPath = join(workspaceDir, "n8nac-config.json");
|
|
27
|
+
if (!existsSync(configPath)) {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
33
|
+
const config = JSON.parse(raw) as Record<string, unknown>;
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
projectId: readString(config.projectId) || undefined,
|
|
37
|
+
projectName: readString(config.projectName) || undefined,
|
|
38
|
+
syncFolder: readString(config.syncFolder) || undefined,
|
|
39
|
+
activeInstanceId: readString(config.activeInstanceId) || undefined,
|
|
40
|
+
};
|
|
41
|
+
} catch {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Returns true when n8nac has been initialized in the given directory,
|
|
48
|
+
* meaning the config exists and contains a selected project + sync folder.
|
|
49
|
+
*/
|
|
50
|
+
export function isWorkspaceInitialized(workspaceDir: string): boolean {
|
|
51
|
+
const binding = readWorkspaceBinding(workspaceDir);
|
|
52
|
+
return Boolean(binding.projectId && binding.projectName && binding.syncFolder);
|
|
53
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowImportingTsExtensions": true,
|
|
4
|
+
"allowSyntheticDefaultImports": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"lib": ["DOM", "DOM.Iterable", "ES2023"],
|
|
8
|
+
"module": "NodeNext",
|
|
9
|
+
"moduleResolution": "NodeNext",
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"target": "es2023"
|
|
15
|
+
},
|
|
16
|
+
"include": ["index.ts", "src/**/*", "tests/**/*.ts"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|