@n8n-as-code/n8nac 2026.4.1 → 2026.5.0-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/index.ts +4 -12
- package/package.json +1 -1
- package/src/workspace.ts +61 -11
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Restart the gateway, then run the setup wizard:
|
|
|
23
23
|
openclaw n8nac:setup
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
The wizard asks for your n8n host URL and API key once, saves
|
|
26
|
+
The wizard asks for your n8n host URL and API key once, saves an instance config via
|
|
27
27
|
`n8nac init-auth`, selects your project, and generates an AI context file
|
|
28
28
|
(`AGENTS.md`) in the workspace (`~/.openclaw/n8nac/`).
|
|
29
29
|
|
|
@@ -63,7 +63,7 @@ All files live in `~/.openclaw/n8nac/`:
|
|
|
63
63
|
|
|
64
64
|
```
|
|
65
65
|
~/.openclaw/n8nac/
|
|
66
|
-
n8nac-config.json ←
|
|
66
|
+
n8nac-config.json ← saved instance configs + active selection
|
|
67
67
|
AGENTS.md ← AI context (written by n8nac update-ai)
|
|
68
68
|
workflows/ ← .workflow.ts files (your n8n workflows)
|
|
69
69
|
```
|
|
@@ -119,7 +119,7 @@ openclaw n8nac:setup
|
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
Enter your n8n host and API key when prompted. The wizard writes
|
|
122
|
-
`~/.openclaw/n8nac/n8nac-config.json` and generates `AGENTS.md`.
|
|
122
|
+
`~/.openclaw/n8nac/n8nac-config.json` with the saved instance configs and active selection, then generates `AGENTS.md`.
|
|
123
123
|
|
|
124
124
|
### 4. Iterate on the code
|
|
125
125
|
|
|
@@ -141,7 +141,7 @@ The plugin prefixes all `api.logger` calls with `[n8nac]`.
|
|
|
141
141
|
|
|
142
142
|
```
|
|
143
143
|
~/.openclaw/n8nac/
|
|
144
|
-
n8nac-config.json ←
|
|
144
|
+
n8nac-config.json ← saved instance configs + active selection
|
|
145
145
|
AGENTS.md ← written by update-ai
|
|
146
146
|
workflows/ ← .workflow.ts files
|
|
147
147
|
```
|
package/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { accessSync, constants,
|
|
1
|
+
import { accessSync, constants, mkdirSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
4
4
|
import { registerN8nAcCli } from "./src/cli.js";
|
|
5
5
|
import { createN8nAcTool } from "./src/tool.js";
|
|
6
|
-
import { getWorkspaceDir, isWorkspaceInitialized } from "./src/workspace.js";
|
|
6
|
+
import { getWorkspaceDir, isWorkspaceInitialized, readWorkspaceBinding } from "./src/workspace.js";
|
|
7
7
|
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
9
|
// Lightweight prompt context
|
|
@@ -21,17 +21,8 @@ Once you have both, call the \`n8nac\` tool with \`action: "init_auth"\`, then
|
|
|
21
21
|
\`action: "init_project"\` to finish setup.
|
|
22
22
|
`;
|
|
23
23
|
|
|
24
|
-
function readConfig(workspaceDir: string): Record<string, string> {
|
|
25
|
-
try {
|
|
26
|
-
const raw = readFileSync(join(workspaceDir, "n8nac-config.json"), "utf-8");
|
|
27
|
-
return JSON.parse(raw) as Record<string, string>;
|
|
28
|
-
} catch {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
24
|
function buildStatusHeader(workspaceDir: string): string {
|
|
34
|
-
const cfg =
|
|
25
|
+
const cfg = readWorkspaceBinding(workspaceDir);
|
|
35
26
|
const host = cfg.host ?? "(unknown)";
|
|
36
27
|
const project = cfg.projectName ?? cfg.projectId ?? "(unknown)";
|
|
37
28
|
return [
|
|
@@ -40,6 +31,7 @@ function buildStatusHeader(workspaceDir: string): string {
|
|
|
40
31
|
"**The workspace is already fully initialized. Do NOT ask the user for credentials.**",
|
|
41
32
|
"",
|
|
42
33
|
`- Workspace directory: \`${workspaceDir}\``,
|
|
34
|
+
`- Active instance: \`${cfg.activeInstanceName ?? cfg.activeInstanceId ?? "(unknown)"}\``,
|
|
43
35
|
`- n8n host: \`${host}\``,
|
|
44
36
|
`- Active project: \`${project}\``,
|
|
45
37
|
].join("\n");
|
package/package.json
CHANGED
package/src/workspace.ts
CHANGED
|
@@ -2,6 +2,15 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
5
|
+
export type WorkspaceBinding = {
|
|
6
|
+
host?: string;
|
|
7
|
+
projectId?: string;
|
|
8
|
+
projectName?: string;
|
|
9
|
+
syncFolder?: string;
|
|
10
|
+
activeInstanceId?: string;
|
|
11
|
+
activeInstanceName?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
5
14
|
/**
|
|
6
15
|
* Fixed workspace directory for V1.
|
|
7
16
|
* All n8nac files (n8nac-config.json, AGENTS.md, workflows/) live here.
|
|
@@ -10,22 +19,63 @@ export function getWorkspaceDir(): string {
|
|
|
10
19
|
return join(homedir(), ".openclaw", "n8nac");
|
|
11
20
|
}
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
function readString(value: unknown): string {
|
|
23
|
+
return typeof value === "string" ? value.trim() : "";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolveActiveInstance(config: Record<string, unknown>): Record<string, unknown> | undefined {
|
|
27
|
+
if (!Array.isArray(config.instances)) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const instances = config.instances.filter((value): value is Record<string, unknown> => !!value && typeof value === "object");
|
|
32
|
+
if (!instances.length) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const activeInstanceId = readString(config.activeInstanceId);
|
|
37
|
+
if (activeInstanceId) {
|
|
38
|
+
return instances.find((instance) => readString(instance.id) === activeInstanceId) || instances[0];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return instances[0];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function readWorkspaceBinding(workspaceDir: string): WorkspaceBinding {
|
|
18
45
|
const configPath = join(workspaceDir, "n8nac-config.json");
|
|
19
|
-
if (!existsSync(configPath))
|
|
46
|
+
if (!existsSync(configPath)) {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
20
49
|
|
|
21
50
|
try {
|
|
22
51
|
const raw = readFileSync(configPath, "utf-8");
|
|
23
52
|
const config = JSON.parse(raw) as Record<string, unknown>;
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
53
|
+
const activeInstance = resolveActiveInstance(config);
|
|
54
|
+
const configActiveInstanceId = readString(config.activeInstanceId);
|
|
55
|
+
const resolvedActiveInstanceId = readString(activeInstance?.id);
|
|
56
|
+
const activeInstanceId =
|
|
57
|
+
resolvedActiveInstanceId && resolvedActiveInstanceId === configActiveInstanceId
|
|
58
|
+
? configActiveInstanceId
|
|
59
|
+
: resolvedActiveInstanceId || undefined;
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
host: readString(activeInstance?.host) || readString(config.host) || undefined,
|
|
63
|
+
projectId: readString(activeInstance?.projectId) || readString(config.projectId) || undefined,
|
|
64
|
+
projectName: readString(activeInstance?.projectName) || readString(config.projectName) || undefined,
|
|
65
|
+
syncFolder: readString(activeInstance?.syncFolder) || readString(config.syncFolder) || undefined,
|
|
66
|
+
activeInstanceId,
|
|
67
|
+
activeInstanceName: readString(activeInstance?.name) || undefined,
|
|
68
|
+
};
|
|
28
69
|
} catch {
|
|
29
|
-
return
|
|
70
|
+
return {};
|
|
30
71
|
}
|
|
31
72
|
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Returns true when n8nac has been initialized in the given directory,
|
|
76
|
+
* meaning the config exists and contains a selected project + sync folder.
|
|
77
|
+
*/
|
|
78
|
+
export function isWorkspaceInitialized(workspaceDir: string): boolean {
|
|
79
|
+
const binding = readWorkspaceBinding(workspaceDir);
|
|
80
|
+
return Boolean(binding.projectId && binding.projectName && binding.syncFolder);
|
|
81
|
+
}
|