@yagr/agent 0.2.9 → 0.2.11
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/cli.js +251 -9
- package/dist/cli.js.map +1 -1
- package/dist/config/n8n-config-service.d.ts +2 -1
- package/dist/config/n8n-config-service.d.ts.map +1 -1
- package/dist/config/n8n-config-service.js +2 -1
- package/dist/config/n8n-config-service.js.map +1 -1
- package/dist/config/yagr-config-service.d.ts +1 -1
- package/dist/config/yagr-config-service.d.ts.map +1 -1
- package/dist/config/yagr-home.d.ts +7 -0
- package/dist/config/yagr-home.d.ts.map +1 -1
- package/dist/config/yagr-home.js +19 -0
- package/dist/config/yagr-home.js.map +1 -1
- package/dist/gateway/format-message.d.ts +3 -0
- package/dist/gateway/format-message.d.ts.map +1 -1
- package/dist/gateway/format-message.js +63 -10
- package/dist/gateway/format-message.js.map +1 -1
- package/dist/gateway/interactive-ui.d.ts.map +1 -1
- package/dist/gateway/interactive-ui.js +49 -4
- package/dist/gateway/interactive-ui.js.map +1 -1
- package/dist/gateway/local-open-bridge.d.ts +3 -0
- package/dist/gateway/local-open-bridge.d.ts.map +1 -0
- package/dist/gateway/local-open-bridge.js +54 -0
- package/dist/gateway/local-open-bridge.js.map +1 -0
- package/dist/gateway/webui.d.ts.map +1 -1
- package/dist/gateway/webui.js +50 -53
- package/dist/gateway/webui.js.map +1 -1
- package/dist/gateway/workflow-links.d.ts +12 -0
- package/dist/gateway/workflow-links.d.ts.map +1 -0
- package/dist/gateway/workflow-links.js +53 -0
- package/dist/gateway/workflow-links.js.map +1 -0
- package/dist/llm/anthropic-account.d.ts +20 -0
- package/dist/llm/anthropic-account.d.ts.map +1 -0
- package/dist/llm/anthropic-account.js +111 -0
- package/dist/llm/anthropic-account.js.map +1 -0
- package/dist/llm/copilot-account.d.ts +36 -0
- package/dist/llm/copilot-account.d.ts.map +1 -0
- package/dist/llm/copilot-account.js +573 -0
- package/dist/llm/copilot-account.js.map +1 -0
- package/dist/llm/create-language-model.d.ts +2 -2
- package/dist/llm/create-language-model.d.ts.map +1 -1
- package/dist/llm/create-language-model.js +187 -38
- package/dist/llm/create-language-model.js.map +1 -1
- package/dist/llm/google-account.d.ts +31 -0
- package/dist/llm/google-account.d.ts.map +1 -0
- package/dist/llm/google-account.js +851 -0
- package/dist/llm/google-account.js.map +1 -0
- package/dist/llm/model-catalog-cache.d.ts +4 -0
- package/dist/llm/model-catalog-cache.d.ts.map +1 -0
- package/dist/llm/model-catalog-cache.js +46 -0
- package/dist/llm/model-catalog-cache.js.map +1 -0
- package/dist/llm/openai-account.d.ts +33 -0
- package/dist/llm/openai-account.d.ts.map +1 -0
- package/dist/llm/openai-account.js +578 -0
- package/dist/llm/openai-account.js.map +1 -0
- package/dist/llm/provider-discovery.d.ts +3 -0
- package/dist/llm/provider-discovery.d.ts.map +1 -0
- package/dist/llm/provider-discovery.js +40 -0
- package/dist/llm/provider-discovery.js.map +1 -0
- package/dist/llm/provider-registry.d.ts +37 -0
- package/dist/llm/provider-registry.d.ts.map +1 -0
- package/dist/llm/provider-registry.js +186 -0
- package/dist/llm/provider-registry.js.map +1 -0
- package/dist/llm/proxy-runtime.d.ts +37 -0
- package/dist/llm/proxy-runtime.d.ts.map +1 -0
- package/dist/llm/proxy-runtime.js +462 -0
- package/dist/llm/proxy-runtime.js.map +1 -0
- package/dist/llm/test-model-policy.d.ts +3 -0
- package/dist/llm/test-model-policy.d.ts.map +1 -0
- package/dist/llm/test-model-policy.js +16 -0
- package/dist/llm/test-model-policy.js.map +1 -0
- package/dist/n8n-local/bootstrap.d.ts +12 -0
- package/dist/n8n-local/bootstrap.d.ts.map +1 -0
- package/dist/n8n-local/bootstrap.js +281 -0
- package/dist/n8n-local/bootstrap.js.map +1 -0
- package/dist/n8n-local/browser-auth.d.ts +12 -0
- package/dist/n8n-local/browser-auth.d.ts.map +1 -0
- package/dist/n8n-local/browser-auth.js +159 -0
- package/dist/n8n-local/browser-auth.js.map +1 -0
- package/dist/n8n-local/detect.d.ts +50 -0
- package/dist/n8n-local/detect.d.ts.map +1 -0
- package/dist/n8n-local/detect.js +207 -0
- package/dist/n8n-local/detect.js.map +1 -0
- package/dist/n8n-local/direct-manager.d.ts +15 -0
- package/dist/n8n-local/direct-manager.d.ts.map +1 -0
- package/dist/n8n-local/direct-manager.js +232 -0
- package/dist/n8n-local/direct-manager.js.map +1 -0
- package/dist/n8n-local/docker-manager.d.ts +18 -0
- package/dist/n8n-local/docker-manager.d.ts.map +1 -0
- package/dist/n8n-local/docker-manager.js +217 -0
- package/dist/n8n-local/docker-manager.js.map +1 -0
- package/dist/n8n-local/managed-runtime.d.ts +17 -0
- package/dist/n8n-local/managed-runtime.d.ts.map +1 -0
- package/dist/n8n-local/managed-runtime.js +122 -0
- package/dist/n8n-local/managed-runtime.js.map +1 -0
- package/dist/n8n-local/owner-credentials.d.ts +15 -0
- package/dist/n8n-local/owner-credentials.d.ts.map +1 -0
- package/dist/n8n-local/owner-credentials.js +50 -0
- package/dist/n8n-local/owner-credentials.js.map +1 -0
- package/dist/n8n-local/plan.d.ts +16 -0
- package/dist/n8n-local/plan.d.ts.map +1 -0
- package/dist/n8n-local/plan.js +48 -0
- package/dist/n8n-local/plan.js.map +1 -0
- package/dist/n8n-local/state.d.ts +42 -0
- package/dist/n8n-local/state.d.ts.map +1 -0
- package/dist/n8n-local/state.js +108 -0
- package/dist/n8n-local/state.js.map +1 -0
- package/dist/n8n-local/workflow-open.d.ts +21 -0
- package/dist/n8n-local/workflow-open.d.ts.map +1 -0
- package/dist/n8n-local/workflow-open.js +50 -0
- package/dist/n8n-local/workflow-open.js.map +1 -0
- package/dist/runtime/context-compaction.d.ts.map +1 -1
- package/dist/runtime/context-compaction.js +7 -0
- package/dist/runtime/context-compaction.js.map +1 -1
- package/dist/runtime/run-engine.d.ts.map +1 -1
- package/dist/runtime/run-engine.js +52 -1
- package/dist/runtime/run-engine.js.map +1 -1
- package/dist/setup/setup-wizard.d.ts +36 -3
- package/dist/setup/setup-wizard.d.ts.map +1 -1
- package/dist/setup/setup-wizard.js +470 -62
- package/dist/setup/setup-wizard.js.map +1 -1
- package/dist/setup.d.ts +2 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +204 -89
- package/dist/setup.js.map +1 -1
- package/dist/system/open-external.d.ts +2 -0
- package/dist/system/open-external.d.ts.map +1 -0
- package/dist/system/open-external.js +25 -0
- package/dist/system/open-external.js.map +1 -0
- package/dist/system/package-manager.d.ts +6 -0
- package/dist/system/package-manager.d.ts.map +1 -0
- package/dist/system/package-manager.js +13 -0
- package/dist/system/package-manager.js.map +1 -0
- package/dist/tools/build-tools.d.ts +110 -65
- package/dist/tools/build-tools.d.ts.map +1 -1
- package/dist/tools/deploy.d.ts +14 -14
- package/dist/tools/generate-workflow.d.ts +5 -5
- package/dist/tools/n8nac.d.ts +96 -53
- package/dist/tools/n8nac.d.ts.map +1 -1
- package/dist/tools/n8nac.js +52 -20
- package/dist/tools/n8nac.js.map +1 -1
- package/dist/tools/observer.d.ts +1 -0
- package/dist/tools/observer.d.ts.map +1 -1
- package/dist/tools/observer.js.map +1 -1
- package/dist/tools/present-workflow-result.d.ts +2 -0
- package/dist/tools/present-workflow-result.d.ts.map +1 -1
- package/dist/tools/present-workflow-result.js +11 -2
- package/dist/tools/present-workflow-result.js.map +1 -1
- package/dist/tools/request-required-action.d.ts +7 -7
- package/dist/tools/request-required-action.js +4 -4
- package/dist/tools/request-required-action.js.map +1 -1
- package/dist/tools/validate.d.ts +14 -14
- package/dist/tools/write-workspace-file.d.ts +5 -5
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/webui/app.js +14 -1
- package/dist/webui/app.js.map +2 -2
- package/package.json +15 -2
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import net from 'node:net';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
export const DEFAULT_N8N_PORT = 5678;
|
|
6
|
+
export const MAX_PORT_SCAN_ATTEMPTS = 10;
|
|
7
|
+
export const MINIMUM_DIRECT_RUNTIME_NODE_VERSION = '22.16.0';
|
|
8
|
+
export function normalizeCommandVersion(output) {
|
|
9
|
+
const value = output?.trim();
|
|
10
|
+
return value ? value.split(/\s+/)[0] : undefined;
|
|
11
|
+
}
|
|
12
|
+
export function parseNodeMajorVersion(version) {
|
|
13
|
+
if (!version) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const match = version.match(/^v?(\d+)/);
|
|
17
|
+
return match ? Number(match[1]) : undefined;
|
|
18
|
+
}
|
|
19
|
+
export function parseNodeVersion(version) {
|
|
20
|
+
if (!version) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const match = version.trim().match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
24
|
+
if (!match) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
major: Number(match[1]),
|
|
29
|
+
minor: Number(match[2]),
|
|
30
|
+
patch: Number(match[3]),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function isSupportedDirectRuntimeNodeVersion(version) {
|
|
34
|
+
const parsed = parseNodeVersion(version);
|
|
35
|
+
if (!parsed) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (parsed.major > 22) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (parsed.major < 22) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (parsed.minor > 16) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
if (parsed.minor < 16) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return parsed.patch >= 0;
|
|
51
|
+
}
|
|
52
|
+
export function chooseLocalN8nBootstrapStrategy(input) {
|
|
53
|
+
if (input.dockerAvailable) {
|
|
54
|
+
return 'docker';
|
|
55
|
+
}
|
|
56
|
+
if (isSupportedDirectRuntimeNodeVersion(input.nodeVersion)) {
|
|
57
|
+
return 'direct';
|
|
58
|
+
}
|
|
59
|
+
return 'manual';
|
|
60
|
+
}
|
|
61
|
+
export function buildLocalN8nBootstrapAssessment(input) {
|
|
62
|
+
const nodeMajorVersion = parseNodeMajorVersion(input.node.version);
|
|
63
|
+
const supportedForDirectRuntime = isSupportedDirectRuntimeNodeVersion(input.node.version);
|
|
64
|
+
const recommendedStrategy = chooseLocalN8nBootstrapStrategy({
|
|
65
|
+
dockerAvailable: input.docker.available && input.docker.reachable !== false,
|
|
66
|
+
nodeVersion: input.node.version,
|
|
67
|
+
});
|
|
68
|
+
const blockers = [];
|
|
69
|
+
const notes = [];
|
|
70
|
+
if (!input.docker.available) {
|
|
71
|
+
notes.push('Docker is not available. Yagr will need a direct runtime or a manual prerequisite step.');
|
|
72
|
+
}
|
|
73
|
+
else if (input.docker.reachable === false) {
|
|
74
|
+
notes.push(input.docker.statusMessage ?? 'Docker is installed, but the Docker engine is not running.');
|
|
75
|
+
}
|
|
76
|
+
if (!input.node.available) {
|
|
77
|
+
notes.push('Node.js is not available.');
|
|
78
|
+
}
|
|
79
|
+
else if (!supportedForDirectRuntime) {
|
|
80
|
+
blockers.push(`Detected Node.js ${input.node.version ?? 'unknown'}, but direct local n8n bootstrap requires Node.js ${MINIMUM_DIRECT_RUNTIME_NODE_VERSION} or newer.`);
|
|
81
|
+
}
|
|
82
|
+
if (recommendedStrategy === 'manual') {
|
|
83
|
+
blockers.push('No supported automatic local bootstrap strategy is currently available on this machine.');
|
|
84
|
+
}
|
|
85
|
+
else if (recommendedStrategy === 'docker') {
|
|
86
|
+
notes.push('Docker is available. This is the preferred local n8n strategy.');
|
|
87
|
+
}
|
|
88
|
+
else if (recommendedStrategy === 'direct') {
|
|
89
|
+
notes.push('A compatible local Node.js runtime is available. Yagr can fall back to a direct local n8n runtime.');
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
platform: input.platform,
|
|
93
|
+
docker: input.docker,
|
|
94
|
+
node: {
|
|
95
|
+
...input.node,
|
|
96
|
+
supportedForDirectRuntime,
|
|
97
|
+
majorVersion: nodeMajorVersion,
|
|
98
|
+
},
|
|
99
|
+
preferredPort: input.preferredPort,
|
|
100
|
+
preferredUrl: `http://127.0.0.1:${input.preferredPort}`,
|
|
101
|
+
recommendedStrategy,
|
|
102
|
+
blockers,
|
|
103
|
+
notes,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
export function formatLocalN8nBootstrapAssessment(assessment) {
|
|
107
|
+
const availableManagedRuntimes = [
|
|
108
|
+
assessment.docker.available && assessment.docker.reachable !== false ? 'docker' : null,
|
|
109
|
+
assessment.node.supportedForDirectRuntime ? 'direct' : null,
|
|
110
|
+
].filter((value) => Boolean(value));
|
|
111
|
+
const lines = [
|
|
112
|
+
'Local n8n bootstrap assessment',
|
|
113
|
+
`Platform: ${assessment.platform}`,
|
|
114
|
+
`Suggested runtime: ${assessment.recommendedStrategy}`,
|
|
115
|
+
`Available managed runtimes: ${availableManagedRuntimes.length > 0 ? availableManagedRuntimes.join(', ') : 'none'}`,
|
|
116
|
+
`Preferred URL: ${assessment.preferredUrl}`,
|
|
117
|
+
`Docker: ${assessment.docker.available
|
|
118
|
+
? `yes${assessment.docker.version ? ` (${assessment.docker.version})` : ''}${assessment.docker.reachable === false ? ' · daemon not reachable' : ''}`
|
|
119
|
+
: 'no'}`,
|
|
120
|
+
`Node.js: ${assessment.node.available ? `yes${assessment.node.version ? ` (${assessment.node.version})` : ''}` : 'no'}`,
|
|
121
|
+
];
|
|
122
|
+
if (assessment.notes.length > 0) {
|
|
123
|
+
lines.push('');
|
|
124
|
+
lines.push('Notes:');
|
|
125
|
+
for (const note of assessment.notes) {
|
|
126
|
+
lines.push(`- ${note}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (assessment.blockers.length > 0) {
|
|
130
|
+
lines.push('');
|
|
131
|
+
lines.push('Blockers:');
|
|
132
|
+
for (const blocker of assessment.blockers) {
|
|
133
|
+
lines.push(`- ${blocker}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return `${lines.join('\n')}\n`;
|
|
137
|
+
}
|
|
138
|
+
export async function inspectLocalN8nBootstrap(dependencies = {}) {
|
|
139
|
+
const deps = {
|
|
140
|
+
platform: dependencies.platform ?? process.platform,
|
|
141
|
+
detectCommand: dependencies.detectCommand ?? detectCommandAvailability,
|
|
142
|
+
isPortAvailable: dependencies.isPortAvailable ?? checkPortAvailability,
|
|
143
|
+
};
|
|
144
|
+
const [docker, node, preferredPort] = await Promise.all([
|
|
145
|
+
deps.detectCommand('docker', ['--version']),
|
|
146
|
+
deps.detectCommand('node', ['--version']),
|
|
147
|
+
findPreferredPort(DEFAULT_N8N_PORT, deps.isPortAvailable),
|
|
148
|
+
]);
|
|
149
|
+
return buildLocalN8nBootstrapAssessment({
|
|
150
|
+
platform: deps.platform,
|
|
151
|
+
docker,
|
|
152
|
+
node,
|
|
153
|
+
preferredPort,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
async function detectCommandAvailability(command, versionArgs) {
|
|
157
|
+
try {
|
|
158
|
+
const { stdout, stderr } = await execFileAsync(command, versionArgs, { timeout: 5000 });
|
|
159
|
+
const availability = {
|
|
160
|
+
available: true,
|
|
161
|
+
version: normalizeCommandVersion(stdout || stderr),
|
|
162
|
+
};
|
|
163
|
+
if (command === 'docker') {
|
|
164
|
+
availability.reachable = await isDockerDaemonReachable();
|
|
165
|
+
if (availability.reachable === false) {
|
|
166
|
+
availability.statusMessage = 'Docker is installed, but Docker is not started. Please start Docker and try again.';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return availability;
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return { available: false };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function isDockerDaemonReachable() {
|
|
176
|
+
try {
|
|
177
|
+
await execFileAsync('docker', ['info', '--format', '{{.ServerVersion}}'], { timeout: 5000 });
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async function findPreferredPort(startPort, isPortAvailable) {
|
|
185
|
+
for (let offset = 0; offset < MAX_PORT_SCAN_ATTEMPTS; offset += 1) {
|
|
186
|
+
const port = startPort + offset;
|
|
187
|
+
if (await isPortAvailable(port)) {
|
|
188
|
+
return port;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return startPort;
|
|
192
|
+
}
|
|
193
|
+
async function checkPortAvailability(port) {
|
|
194
|
+
return new Promise((resolve) => {
|
|
195
|
+
const server = net.createServer();
|
|
196
|
+
const finalize = (available) => {
|
|
197
|
+
server.removeAllListeners();
|
|
198
|
+
resolve(available);
|
|
199
|
+
};
|
|
200
|
+
server.once('error', () => finalize(false));
|
|
201
|
+
server.once('listening', () => {
|
|
202
|
+
server.close(() => finalize(true));
|
|
203
|
+
});
|
|
204
|
+
server.listen(port, '127.0.0.1');
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/n8n-local/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ManagedN8nInstanceState } from './state.js';
|
|
2
|
+
export declare function installManagedDirectN8n(options?: {
|
|
3
|
+
port?: number;
|
|
4
|
+
}): Promise<ManagedN8nInstanceState>;
|
|
5
|
+
export declare function startManagedDirectN8n(): Promise<ManagedN8nInstanceState>;
|
|
6
|
+
export declare function stopManagedDirectN8n(): Promise<ManagedN8nInstanceState>;
|
|
7
|
+
export declare function getManagedDirectN8nLogs(): Promise<string>;
|
|
8
|
+
export declare function getManagedDirectN8nStatus(): Promise<{
|
|
9
|
+
installed: boolean;
|
|
10
|
+
running: boolean;
|
|
11
|
+
healthy: boolean;
|
|
12
|
+
url?: string;
|
|
13
|
+
state?: ManagedN8nInstanceState;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=direct-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-manager.d.ts","sourceRoot":"","sources":["../../src/n8n-local/direct-manager.ts"],"names":[],"mappings":"AAKA,OAAO,EAML,KAAK,uBAAuB,EAC7B,MAAM,YAAY,CAAC;AAOpB,wBAAsB,uBAAuB,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAgE/G;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAO9E;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAmB7E;AAED,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC,CAO/D;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC,CAAC,CAmBD"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { DEFAULT_N8N_PORT, inspectLocalN8nBootstrap } from './detect.js';
|
|
5
|
+
import { resolvePackageManagerCommand, resolvePackageManagerSpawnOptions } from '../system/package-manager.js';
|
|
6
|
+
import { buildManagedN8nState, ensureManagedN8nDirs, readManagedN8nState, resolveManagedN8nBootstrapStage, updateManagedN8nState, } from './state.js';
|
|
7
|
+
const DEFAULT_HEALTH_TIMEOUT_MS = 180_000;
|
|
8
|
+
const DEFAULT_STARTUP_TIMEOUT_MS = 600_000;
|
|
9
|
+
const DEFAULT_EDITOR_TIMEOUT_MS = 90_000;
|
|
10
|
+
const N8N_PACKAGE_SPEC = 'n8n@latest';
|
|
11
|
+
export async function installManagedDirectN8n(options = {}) {
|
|
12
|
+
const assessment = await inspectLocalN8nBootstrap();
|
|
13
|
+
if (!assessment.node.supportedForDirectRuntime) {
|
|
14
|
+
throw new Error('A supported local Node.js runtime is required for direct n8n bootstrap. Run `yagr n8n doctor` for details.');
|
|
15
|
+
}
|
|
16
|
+
const paths = ensureManagedN8nDirs();
|
|
17
|
+
const npmCacheDir = path.join(paths.rootDir, 'npm-cache');
|
|
18
|
+
fs.mkdirSync(npmCacheDir, { recursive: true });
|
|
19
|
+
const existingState = readManagedN8nState();
|
|
20
|
+
const port = options.port ?? existingState?.port ?? assessment.preferredPort ?? DEFAULT_N8N_PORT;
|
|
21
|
+
const bootstrapStage = resolveManagedN8nBootstrapStage(`http://127.0.0.1:${port}`);
|
|
22
|
+
const state = updateManagedN8nState(() => buildManagedN8nState({
|
|
23
|
+
strategy: 'direct',
|
|
24
|
+
image: '',
|
|
25
|
+
port,
|
|
26
|
+
status: 'starting',
|
|
27
|
+
bootstrapStage,
|
|
28
|
+
logFile: paths.logFile,
|
|
29
|
+
}));
|
|
30
|
+
const child = spawn(resolvePackageManagerCommand('npm'), [
|
|
31
|
+
'exec',
|
|
32
|
+
'--yes',
|
|
33
|
+
N8N_PACKAGE_SPEC,
|
|
34
|
+
'--',
|
|
35
|
+
'start',
|
|
36
|
+
], {
|
|
37
|
+
cwd: paths.rootDir,
|
|
38
|
+
detached: true,
|
|
39
|
+
stdio: ['ignore', fs.openSync(paths.logFile, 'a'), fs.openSync(paths.logFile, 'a')],
|
|
40
|
+
...resolvePackageManagerSpawnOptions(),
|
|
41
|
+
env: {
|
|
42
|
+
...process.env,
|
|
43
|
+
N8N_PORT: String(port),
|
|
44
|
+
N8N_HOST: '127.0.0.1',
|
|
45
|
+
N8N_LISTEN_ADDRESS: '0.0.0.0',
|
|
46
|
+
N8N_PROTOCOL: 'http',
|
|
47
|
+
N8N_EDITOR_BASE_URL: `http://127.0.0.1:${port}`,
|
|
48
|
+
N8N_SECURE_COOKIE: 'false',
|
|
49
|
+
N8N_USER_FOLDER: paths.dataDir,
|
|
50
|
+
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: 'true',
|
|
51
|
+
GENERIC_TIMEZONE: 'UTC',
|
|
52
|
+
TZ: 'UTC',
|
|
53
|
+
npm_config_cache: npmCacheDir,
|
|
54
|
+
npm_config_update_notifier: 'false',
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
const startupWatch = waitForManagedN8nStartup(child, state.url, paths.logFile);
|
|
58
|
+
child.unref();
|
|
59
|
+
await startupWatch;
|
|
60
|
+
await waitForManagedN8nEditorReadyBestEffort(state.url);
|
|
61
|
+
return updateManagedN8nState((current) => ({
|
|
62
|
+
...(current ?? state),
|
|
63
|
+
strategy: 'direct',
|
|
64
|
+
port,
|
|
65
|
+
url: state.url,
|
|
66
|
+
logFile: paths.logFile,
|
|
67
|
+
pid: child.pid,
|
|
68
|
+
status: 'ready',
|
|
69
|
+
bootstrapStage: current?.bootstrapStage ?? bootstrapStage,
|
|
70
|
+
lastError: undefined,
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
export async function startManagedDirectN8n() {
|
|
74
|
+
const state = readManagedN8nState();
|
|
75
|
+
if (!state || state.strategy !== 'direct') {
|
|
76
|
+
throw new Error('No Yagr-managed direct local n8n instance is installed yet. Run `yagr n8n local install` first.');
|
|
77
|
+
}
|
|
78
|
+
return installManagedDirectN8n({ port: state.port });
|
|
79
|
+
}
|
|
80
|
+
export async function stopManagedDirectN8n() {
|
|
81
|
+
const state = readManagedN8nState();
|
|
82
|
+
if (!state || state.strategy !== 'direct') {
|
|
83
|
+
throw new Error('No Yagr-managed direct local n8n instance is installed yet.');
|
|
84
|
+
}
|
|
85
|
+
if (state.pid) {
|
|
86
|
+
try {
|
|
87
|
+
process.kill(state.pid, 'SIGTERM');
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// ignore missing process
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return updateManagedN8nState((current) => ({
|
|
94
|
+
...(current ?? state),
|
|
95
|
+
status: 'stopped',
|
|
96
|
+
lastError: undefined,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
export async function getManagedDirectN8nLogs() {
|
|
100
|
+
const state = readManagedN8nState();
|
|
101
|
+
if (!state?.logFile || !fs.existsSync(state.logFile)) {
|
|
102
|
+
return '';
|
|
103
|
+
}
|
|
104
|
+
return fs.readFileSync(state.logFile, 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
export async function getManagedDirectN8nStatus() {
|
|
107
|
+
const state = readManagedN8nState();
|
|
108
|
+
if (!state || state.strategy !== 'direct') {
|
|
109
|
+
return {
|
|
110
|
+
installed: false,
|
|
111
|
+
running: false,
|
|
112
|
+
healthy: false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const running = isPidAlive(state.pid);
|
|
116
|
+
const healthy = running ? await isManagedN8nHealthy(state.url) : false;
|
|
117
|
+
return {
|
|
118
|
+
installed: true,
|
|
119
|
+
running,
|
|
120
|
+
healthy,
|
|
121
|
+
url: state.url,
|
|
122
|
+
state,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function isManagedN8nHealthy(url) {
|
|
126
|
+
try {
|
|
127
|
+
const response = await fetch(`${url}/healthz`);
|
|
128
|
+
return response.ok;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function isManagedN8nEditorReady(url) {
|
|
135
|
+
try {
|
|
136
|
+
const response = await fetch(url);
|
|
137
|
+
if (!response.ok) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
const body = await response.text();
|
|
141
|
+
return body.trim().length > 0 && !body.toLowerCase().includes('n8n is starting up');
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function waitForManagedN8nHealth(url, timeoutMs = DEFAULT_HEALTH_TIMEOUT_MS) {
|
|
148
|
+
const deadline = Date.now() + timeoutMs;
|
|
149
|
+
while (Date.now() < deadline) {
|
|
150
|
+
if (await isManagedN8nHealthy(url)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
await delay(1500);
|
|
154
|
+
}
|
|
155
|
+
throw new Error(`Timed out waiting for ${url} to become healthy.`);
|
|
156
|
+
}
|
|
157
|
+
async function waitForManagedN8nEditorReady(url, timeoutMs = DEFAULT_EDITOR_TIMEOUT_MS) {
|
|
158
|
+
const deadline = Date.now() + timeoutMs;
|
|
159
|
+
while (Date.now() < deadline) {
|
|
160
|
+
if (await isManagedN8nEditorReady(url)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
await delay(1500);
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`Timed out waiting for the n8n editor at ${url} to become ready.`);
|
|
166
|
+
}
|
|
167
|
+
async function waitForManagedN8nEditorReadyBestEffort(url) {
|
|
168
|
+
try {
|
|
169
|
+
await waitForManagedN8nEditorReady(url);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// best effort only
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async function waitForManagedN8nStartup(child, url, logFile, timeoutMs = DEFAULT_STARTUP_TIMEOUT_MS) {
|
|
176
|
+
let childError;
|
|
177
|
+
let exitCode;
|
|
178
|
+
let exitSignal;
|
|
179
|
+
let exited = false;
|
|
180
|
+
child.once('error', (error) => {
|
|
181
|
+
childError = error;
|
|
182
|
+
});
|
|
183
|
+
child.once('exit', (code, signal) => {
|
|
184
|
+
exited = true;
|
|
185
|
+
exitCode = code;
|
|
186
|
+
exitSignal = signal;
|
|
187
|
+
});
|
|
188
|
+
const deadline = Date.now() + timeoutMs;
|
|
189
|
+
while (Date.now() < deadline) {
|
|
190
|
+
if (childError) {
|
|
191
|
+
throw new Error(`Failed to start managed n8n runtime: ${childError.message}`);
|
|
192
|
+
}
|
|
193
|
+
if (await isManagedN8nHealthy(url)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (exited) {
|
|
197
|
+
const logTail = readLogTail(logFile);
|
|
198
|
+
const suffix = logTail ? `\n\nRecent runtime log:\n${logTail}` : '';
|
|
199
|
+
throw new Error(`Managed n8n runtime exited before becoming healthy (code ${exitCode ?? 'null'}, signal ${exitSignal ?? 'none'}).${suffix}`);
|
|
200
|
+
}
|
|
201
|
+
await delay(1500);
|
|
202
|
+
}
|
|
203
|
+
const logTail = readLogTail(logFile);
|
|
204
|
+
const suffix = logTail ? `\n\nRecent runtime log:\n${logTail}` : '';
|
|
205
|
+
throw new Error(`Timed out waiting for ${url} to become healthy after ${Math.round(timeoutMs / 1000)}s.${suffix}`);
|
|
206
|
+
}
|
|
207
|
+
function readLogTail(logFile, maxChars = 4000) {
|
|
208
|
+
if (!fs.existsSync(logFile)) {
|
|
209
|
+
return '';
|
|
210
|
+
}
|
|
211
|
+
const content = fs.readFileSync(logFile, 'utf-8').trim();
|
|
212
|
+
if (!content) {
|
|
213
|
+
return '';
|
|
214
|
+
}
|
|
215
|
+
return content.slice(-maxChars);
|
|
216
|
+
}
|
|
217
|
+
async function delay(ms) {
|
|
218
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
219
|
+
}
|
|
220
|
+
function isPidAlive(pid) {
|
|
221
|
+
if (!pid) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
process.kill(pid, 0);
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=direct-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"direct-manager.js","sourceRoot":"","sources":["../../src/n8n-local/direct-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ManagedN8nInstanceState } from './state.js';
|
|
2
|
+
export interface InstallManagedDockerN8nOptions {
|
|
3
|
+
image?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ManagedDockerN8nStatus {
|
|
7
|
+
installed: boolean;
|
|
8
|
+
running: boolean;
|
|
9
|
+
healthy: boolean;
|
|
10
|
+
url?: string;
|
|
11
|
+
state?: ManagedN8nInstanceState;
|
|
12
|
+
}
|
|
13
|
+
export declare function installManagedDockerN8n(options?: InstallManagedDockerN8nOptions): Promise<ManagedN8nInstanceState>;
|
|
14
|
+
export declare function startManagedDockerN8n(): Promise<ManagedN8nInstanceState>;
|
|
15
|
+
export declare function getManagedDockerN8nStatus(): Promise<ManagedDockerN8nStatus>;
|
|
16
|
+
export declare function stopManagedDockerN8n(): Promise<ManagedN8nInstanceState>;
|
|
17
|
+
export declare function getManagedDockerN8nLogs(tail?: number): Promise<string>;
|
|
18
|
+
//# sourceMappingURL=docker-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-manager.d.ts","sourceRoot":"","sources":["../../src/n8n-local/docker-manager.ts"],"names":[],"mappings":"AAKA,OAAO,EAML,KAAK,uBAAuB,EAC7B,MAAM,YAAY,CAAC;AAQpB,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC;AAED,wBAAsB,uBAAuB,CAAC,OAAO,GAAE,8BAAmC,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAsC5H;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAqB9E;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAgBjF;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAa7E;AAED,wBAAsB,uBAAuB,CAAC,IAAI,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQzE"}
|