@alfe.ai/gateway 0.9.18 → 0.9.19
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/bin/gateway.js +1 -1
- package/dist/health.js +395 -16095
- package/dist/runtime-process.js +15742 -0
- package/dist/runtime-upgrade.js +154 -52
- package/dist/sentry.js +46 -1
- package/dist/src/index.d.ts +11 -4
- package/dist/src/index.js +4 -4
- package/dist/upgrade.js +1 -2
- package/package.json +4 -4
- package/dist/logger.js +0 -46
package/dist/runtime-upgrade.js
CHANGED
|
@@ -1,38 +1,31 @@
|
|
|
1
|
-
import { n as
|
|
1
|
+
import { d as supportsOpenClawNode, l as OPENCLAW_NODE_REQUIREMENT, n as OPENCLAW_EXTERNAL_SUPERVISOR_ENV } from "./runtime-process.js";
|
|
2
|
+
import { m as logger } from "./sentry.js";
|
|
3
|
+
import { mkdir } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { homedir } from "node:os";
|
|
2
6
|
import { execFile } from "node:child_process";
|
|
3
7
|
import { promisify } from "node:util";
|
|
4
8
|
//#region src/runtime-upgrade.ts
|
|
5
9
|
/**
|
|
6
|
-
* Runtime upgrade —
|
|
10
|
+
* Runtime upgrade — safely replace a runtime binary and cycle its child.
|
|
7
11
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
12
|
+
* OpenClaw upgrades are a state migration, not just an npm install:
|
|
13
|
+
* 1. prove the host Node.js version can run the target;
|
|
14
|
+
* 2. drain/suspend the runtime and serialize against every OpenClaw CLI writer;
|
|
15
|
+
* 3. create and verify an OpenClaw backup (workspace excluded; sync owns it);
|
|
16
|
+
* 4. install and verify the exact package version;
|
|
17
|
+
* 5. run the non-interactive doctor migration and post-upgrade audit;
|
|
18
|
+
* 6. resume the runtime under Alfe's external supervisor.
|
|
10
19
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* On install failure, the runtime is restarted on the old version.
|
|
20
|
+
* If package replacement fails before doctor starts, the previous exact version
|
|
21
|
+
* is reinstalled. Once doctor has begun, automatic package rollback is unsafe:
|
|
22
|
+
* OpenClaw 2 may already have migrated session/state storage. The verified
|
|
23
|
+
* archive is retained for operator recovery and the new runtime is resumed so
|
|
24
|
+
* its idempotent doctor can be retried.
|
|
17
25
|
*/
|
|
18
26
|
const execFileAsync = promisify(execFile);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*
|
|
22
|
-
* - `openclaw`: `npm install -g openclaw@<version>` — version-pinned.
|
|
23
|
-
* - `claude-code`: `npm install -g @alfe.ai/claude-code-host@<version>` — the
|
|
24
|
-
* runtime child is the host binary; mirrors openclaw. The
|
|
25
|
-
* caller defaults a missing version to the pin.
|
|
26
|
-
* - `hermes`: `hermes update --yes` — Hermes self-updates from its own
|
|
27
|
-
* channel. A pinned version does not map to a Hermes CLI flag,
|
|
28
|
-
* so the `version` arg is intentionally ignored on this branch.
|
|
29
|
-
*
|
|
30
|
-
* Returns `undefined` for an unknown runtime (or openclaw/claude-code with no
|
|
31
|
-
* version), which the caller treats as a failed upgrade (restart on the old
|
|
32
|
-
* version). `upgradeRuntime` restarts the RuntimeProcess child regardless of
|
|
33
|
-
* runtime, so a new branch here is all that's needed to cycle onto the new
|
|
34
|
-
* version.
|
|
35
|
-
*/
|
|
27
|
+
const OPENCLAW_UPGRADE_TIMEOUT_MS = 3e5;
|
|
28
|
+
const OPENCLAW_DOCTOR_TIMEOUT_MS = 3e5;
|
|
36
29
|
function resolveUpgradeCommand(runtime, version) {
|
|
37
30
|
switch (runtime) {
|
|
38
31
|
case "openclaw":
|
|
@@ -62,7 +55,25 @@ function resolveUpgradeCommand(runtime, version) {
|
|
|
62
55
|
default: return;
|
|
63
56
|
}
|
|
64
57
|
}
|
|
65
|
-
|
|
58
|
+
/** Extract the semver-like version token printed by `openclaw --version`. */
|
|
59
|
+
function parseOpenClawVersion(output) {
|
|
60
|
+
return /(?:^|\s)(\d{4}\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)(?:\s|$)/u.exec(output.trim())?.[1];
|
|
61
|
+
}
|
|
62
|
+
async function upgradeRuntime(runtime, version, runtimeProcess, options = {}) {
|
|
63
|
+
const runCommand = options.runCommand ?? (async (command, args, commandOptions) => {
|
|
64
|
+
const result = await execFileAsync(command, args, commandOptions);
|
|
65
|
+
return {
|
|
66
|
+
stdout: result.stdout,
|
|
67
|
+
stderr: result.stderr
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
const commandOptions = (timeout) => runtime === "openclaw" ? {
|
|
71
|
+
timeout,
|
|
72
|
+
env: {
|
|
73
|
+
...process.env,
|
|
74
|
+
...OPENCLAW_EXTERNAL_SUPERVISOR_ENV
|
|
75
|
+
}
|
|
76
|
+
} : { timeout };
|
|
66
77
|
const cmd = resolveUpgradeCommand(runtime, version);
|
|
67
78
|
if (!cmd) {
|
|
68
79
|
const message = `No upgrade command for runtime '${runtime}'`;
|
|
@@ -77,52 +88,143 @@ async function upgradeRuntime(runtime, version, runtimeProcess) {
|
|
|
77
88
|
error: message
|
|
78
89
|
};
|
|
79
90
|
}
|
|
91
|
+
let previousOpenClawVersion;
|
|
92
|
+
if (runtime === "openclaw") try {
|
|
93
|
+
const [{ stdout: nodeOutput }, { stdout: openClawOutput }] = await Promise.all([runCommand("node", ["--version"], commandOptions(1e4)), runCommand("openclaw", ["--version"], commandOptions(1e4))]);
|
|
94
|
+
const nodeVersion = nodeOutput.trim();
|
|
95
|
+
if (!supportsOpenClawNode(nodeVersion)) {
|
|
96
|
+
const message = `OpenClaw ${version ?? "2.x"} requires Node.js ${OPENCLAW_NODE_REQUIREMENT}; this host resolves ${nodeVersion}. Upgrade Node.js or rebuild the agent before retrying.`;
|
|
97
|
+
logger.error({
|
|
98
|
+
runtime,
|
|
99
|
+
version,
|
|
100
|
+
nodeVersion
|
|
101
|
+
}, message);
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
runtime,
|
|
105
|
+
version,
|
|
106
|
+
error: message
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
previousOpenClawVersion = parseOpenClawVersion(openClawOutput);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
const message = `OpenClaw upgrade preflight failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
112
|
+
logger.error({
|
|
113
|
+
runtime,
|
|
114
|
+
version
|
|
115
|
+
}, message);
|
|
116
|
+
return {
|
|
117
|
+
success: false,
|
|
118
|
+
runtime,
|
|
119
|
+
version,
|
|
120
|
+
error: message
|
|
121
|
+
};
|
|
122
|
+
}
|
|
80
123
|
logger.info({
|
|
81
124
|
runtime,
|
|
82
125
|
version
|
|
83
126
|
}, "Upgrading runtime...");
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
127
|
+
let gateSuspended = false;
|
|
128
|
+
let packageInstallAttempted = false;
|
|
129
|
+
let doctorStarted = false;
|
|
130
|
+
let runtimeChanged = false;
|
|
131
|
+
const performUpgrade = async () => {
|
|
132
|
+
try {
|
|
133
|
+
if (runtime === "openclaw") {
|
|
134
|
+
const backupDirectory = options.backupDirectory ?? join(homedir(), ".alfe", "backups", "openclaw");
|
|
135
|
+
await mkdir(backupDirectory, {
|
|
136
|
+
recursive: true,
|
|
137
|
+
mode: 448
|
|
138
|
+
});
|
|
139
|
+
const backup = await runCommand("openclaw", [
|
|
140
|
+
"backup",
|
|
141
|
+
"create",
|
|
142
|
+
"--output",
|
|
143
|
+
backupDirectory,
|
|
144
|
+
"--verify",
|
|
145
|
+
"--no-include-workspace",
|
|
146
|
+
"--json"
|
|
147
|
+
], commandOptions(OPENCLAW_UPGRADE_TIMEOUT_MS));
|
|
148
|
+
if (backup.stdout) logger.info({ backup: backup.stdout.trim() }, "Verified pre-upgrade OpenClaw backup created");
|
|
149
|
+
}
|
|
150
|
+
packageInstallAttempted = true;
|
|
151
|
+
const { stdout, stderr } = await runCommand(cmd.command, cmd.args, commandOptions(OPENCLAW_UPGRADE_TIMEOUT_MS));
|
|
152
|
+
if (stdout) logger.debug({ stdout: stdout.trim() }, "runtime upgrade stdout");
|
|
153
|
+
if (stderr) logger.debug({ stderr: stderr.trim() }, "runtime upgrade stderr");
|
|
154
|
+
if (runtime === "openclaw" && version) {
|
|
155
|
+
const installedVersion = parseOpenClawVersion((await runCommand("openclaw", ["--version"], commandOptions(1e4))).stdout);
|
|
156
|
+
if (installedVersion !== version) throw new Error(`OpenClaw package verification failed: requested ${version}, resolved ${installedVersion ?? "unknown"}`);
|
|
157
|
+
runtimeChanged = installedVersion !== previousOpenClawVersion;
|
|
158
|
+
doctorStarted = true;
|
|
159
|
+
await runCommand("openclaw", [
|
|
160
|
+
"doctor",
|
|
161
|
+
"--fix",
|
|
162
|
+
"--non-interactive",
|
|
163
|
+
"--yes",
|
|
164
|
+
"--json"
|
|
165
|
+
], commandOptions(OPENCLAW_DOCTOR_TIMEOUT_MS));
|
|
166
|
+
const audit = await runCommand("openclaw", [
|
|
167
|
+
"doctor",
|
|
168
|
+
"--post-upgrade",
|
|
169
|
+
"--json"
|
|
170
|
+
], commandOptions(OPENCLAW_DOCTOR_TIMEOUT_MS));
|
|
171
|
+
if (audit.stdout) logger.info({ audit: audit.stdout.trim() }, "OpenClaw post-upgrade audit completed");
|
|
172
|
+
}
|
|
173
|
+
} catch (err) {
|
|
174
|
+
if (runtime === "openclaw" && packageInstallAttempted && !doctorStarted && previousOpenClawVersion) try {
|
|
175
|
+
logger.warn({ previousOpenClawVersion }, "OpenClaw package replacement failed before state migration — restoring previous package");
|
|
176
|
+
await runCommand("npm", [
|
|
177
|
+
"install",
|
|
178
|
+
"-g",
|
|
179
|
+
`openclaw@${previousOpenClawVersion}`
|
|
180
|
+
], commandOptions(OPENCLAW_UPGRADE_TIMEOUT_MS));
|
|
181
|
+
if (parseOpenClawVersion((await runCommand("openclaw", ["--version"], commandOptions(1e4))).stdout) !== previousOpenClawVersion) throw new Error("restored OpenClaw version did not verify");
|
|
182
|
+
runtimeChanged = false;
|
|
183
|
+
} catch (rollbackError) {
|
|
184
|
+
logger.error({ err: rollbackError instanceof Error ? rollbackError.message : String(rollbackError) }, "Failed to restore the previous OpenClaw package after upgrade failure");
|
|
185
|
+
}
|
|
186
|
+
throw err;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
88
189
|
try {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
190
|
+
if (options.gate) {
|
|
191
|
+
gateSuspended = true;
|
|
192
|
+
await options.gate.suspend();
|
|
193
|
+
} else if (runtimeProcess) await runtimeProcess.stopWhenIdle();
|
|
194
|
+
if (runtime === "openclaw" && options.cliLock) await options.cliLock.run(performUpgrade);
|
|
195
|
+
else await performUpgrade();
|
|
92
196
|
logger.info({
|
|
93
197
|
runtime,
|
|
94
198
|
version
|
|
95
199
|
}, "Runtime upgraded successfully");
|
|
200
|
+
return {
|
|
201
|
+
success: true,
|
|
202
|
+
runtime,
|
|
203
|
+
version,
|
|
204
|
+
runtimeChanged
|
|
205
|
+
};
|
|
96
206
|
} catch (err) {
|
|
97
207
|
const message = err instanceof Error ? err.message : String(err);
|
|
98
208
|
logger.error({
|
|
99
209
|
err: message,
|
|
100
210
|
runtime,
|
|
101
211
|
version
|
|
102
|
-
}, "Runtime upgrade
|
|
103
|
-
if (runtimeProcess) try {
|
|
104
|
-
logger.info("Restarting runtime on previous version after failed upgrade...");
|
|
105
|
-
await runtimeProcess.restart();
|
|
106
|
-
} catch (restartErr) {
|
|
107
|
-
const restartMsg = restartErr instanceof Error ? restartErr.message : String(restartErr);
|
|
108
|
-
logger.error({ err: restartMsg }, "Failed to restart runtime after failed upgrade");
|
|
109
|
-
}
|
|
212
|
+
}, "Runtime upgrade failed");
|
|
110
213
|
return {
|
|
111
214
|
success: false,
|
|
112
215
|
runtime,
|
|
113
216
|
version,
|
|
217
|
+
runtimeChanged,
|
|
114
218
|
error: message
|
|
115
219
|
};
|
|
220
|
+
} finally {
|
|
221
|
+
try {
|
|
222
|
+
if (gateSuspended && options.gate) await options.gate.resume();
|
|
223
|
+
else if (!options.gate && runtimeProcess) await runtimeProcess.restart();
|
|
224
|
+
} catch (restartErr) {
|
|
225
|
+
logger.error({ err: restartErr instanceof Error ? restartErr.message : String(restartErr) }, "Failed to resume runtime after upgrade attempt");
|
|
226
|
+
}
|
|
116
227
|
}
|
|
117
|
-
if (runtimeProcess) {
|
|
118
|
-
logger.info("Restarting runtime after upgrade...");
|
|
119
|
-
await runtimeProcess.restart();
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
success: true,
|
|
123
|
-
runtime,
|
|
124
|
-
version
|
|
125
|
-
};
|
|
126
228
|
}
|
|
127
229
|
//#endregion
|
|
128
230
|
export { upgradeRuntime };
|
package/dist/sentry.js
CHANGED
|
@@ -1,4 +1,49 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import pino from "pino";
|
|
4
|
+
import { mkdirSync } from "node:fs";
|
|
1
5
|
import { readConfig, resolveConfig } from "@alfe.ai/config";
|
|
6
|
+
//#region src/logger.ts
|
|
7
|
+
/**
|
|
8
|
+
* Daemon logger — pino with rolling file output.
|
|
9
|
+
*
|
|
10
|
+
* Writes to ~/.alfe/logs/gateway.log with 10MB rotation, keep 5 files.
|
|
11
|
+
* In managed mode (ECS Fargate): always stdout for CloudWatch capture.
|
|
12
|
+
* In development: stdout.
|
|
13
|
+
*/
|
|
14
|
+
const LOG_DIR = join(homedir(), ".alfe", "logs");
|
|
15
|
+
const LOG_FILE = join(LOG_DIR, "gateway.log");
|
|
16
|
+
const isDev = process.env.NODE_ENV !== "production";
|
|
17
|
+
const isManaged = process.env.ALFE_MANAGED === "true";
|
|
18
|
+
if (!isManaged) try {
|
|
19
|
+
mkdirSync(LOG_DIR, { recursive: true });
|
|
20
|
+
} catch {}
|
|
21
|
+
/**
|
|
22
|
+
* Create the daemon logger.
|
|
23
|
+
* Managed mode (ECS): JSON to stdout (CloudWatch captures via awslogs driver).
|
|
24
|
+
* Development: JSON to stdout.
|
|
25
|
+
* Production (local): JSON to rolling file.
|
|
26
|
+
*/
|
|
27
|
+
function createLogger() {
|
|
28
|
+
if (isDev || isManaged) return pino({
|
|
29
|
+
level: process.env.LOG_LEVEL ?? (isDev ? "debug" : "info"),
|
|
30
|
+
transport: {
|
|
31
|
+
target: "pino/file",
|
|
32
|
+
options: { destination: 1 }
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const transport = pino.transport({
|
|
36
|
+
target: "pino-roll",
|
|
37
|
+
options: {
|
|
38
|
+
file: LOG_FILE,
|
|
39
|
+
size: "10m",
|
|
40
|
+
limit: { count: 5 }
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return pino({ level: process.env.LOG_LEVEL ?? "info" }, transport);
|
|
44
|
+
}
|
|
45
|
+
const logger = createLogger();
|
|
46
|
+
//#endregion
|
|
2
47
|
//#region src/sentry.ts
|
|
3
48
|
/**
|
|
4
49
|
* Agent-side error reporting (Sentry) for the Alfe CLI + gateway daemon.
|
|
@@ -383,4 +428,4 @@ function captureFatal(cause) {
|
|
|
383
428
|
} catch {}
|
|
384
429
|
}
|
|
385
430
|
//#endregion
|
|
386
|
-
export { captureFatal as a, captureRuntimeCrash as c, initAgentSentry as d, setAgentContext as f, captureCliFailure as i, captureRuntimeErrorOutput as l, AGENT_MCP_SENTRY_DSN as n, captureIntegrationFailure as o, AGENT_RUNTIME_SENTRY_DSN as r, captureMcpFailure as s, AGENT_DAEMON_SENTRY_DSN as t, flushSentry as u };
|
|
431
|
+
export { captureFatal as a, captureRuntimeCrash as c, initAgentSentry as d, setAgentContext as f, captureCliFailure as i, captureRuntimeErrorOutput as l, logger as m, AGENT_MCP_SENTRY_DSN as n, captureIntegrationFailure as o, LOG_FILE as p, AGENT_RUNTIME_SENTRY_DSN as r, captureMcpFailure as s, AGENT_DAEMON_SENTRY_DSN as t, flushSentry as u };
|
package/dist/src/index.d.ts
CHANGED
|
@@ -44,8 +44,8 @@ declare function startDaemon(): Promise<void>;
|
|
|
44
44
|
* truth for every install path:
|
|
45
45
|
* - `@alfe.ai/cli` `installRuntime` (fresh `alfe setup`)
|
|
46
46
|
* - the daemon `runtime.update` default (this package)
|
|
47
|
-
* -
|
|
48
|
-
*
|
|
47
|
+
* - managed provisioning (`services/compute/src/lib/provisioner.ts` installs a
|
|
48
|
+
* compatible Node.js 22 before the CLI consumes this pin)
|
|
49
49
|
*
|
|
50
50
|
* Pinning (rather than floating `npm install -g openclaw` → `latest`) is deliberate:
|
|
51
51
|
* OpenClaw runs on every managed agent, so a `latest` that changes runtime semantics —
|
|
@@ -53,7 +53,14 @@ declare function startDaemon(): Promise<void>;
|
|
|
53
53
|
* silent fleet outage with no Alfe deploy. Bump deliberately after validating a new
|
|
54
54
|
* OpenClaw, then cut a CLI release so the pin travels with the CLI version.
|
|
55
55
|
*/
|
|
56
|
-
declare const PINNED_OPENCLAW_VERSION = "2026.
|
|
56
|
+
declare const PINNED_OPENCLAW_VERSION = "2026.8.1";
|
|
57
|
+
/** OpenClaw 2026.8.1's published Node.js engine floor. */
|
|
58
|
+
declare const OPENCLAW_NODE_REQUIREMENT = ">=22.22.3 <23 || >=24.15.0 <25 || >=25.9.0";
|
|
59
|
+
/**
|
|
60
|
+
* Whether a concrete Node.js version satisfies OpenClaw 2.x's engine range.
|
|
61
|
+
* Accepts `process.versions.node` (`22.22.3`) or CLI output (`v22.22.3`).
|
|
62
|
+
*/
|
|
63
|
+
declare function supportsOpenClawNode(nodeVersion: string): boolean;
|
|
57
64
|
//#endregion
|
|
58
65
|
//#region src/claude-code-host-version.d.ts
|
|
59
66
|
/**
|
|
@@ -407,4 +414,4 @@ declare function checkExistingDaemon(): Promise<number | null>;
|
|
|
407
414
|
*/
|
|
408
415
|
declare function stopExistingDaemon(): Promise<boolean>;
|
|
409
416
|
//#endregion
|
|
410
|
-
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, type AgentIdentity, type AgentWorkspaceConfig, type DaemonConfig, type DaemonHealth, type IPCEvent, type IPCRequest, type IPCResponse, type InitAgentSentryOptions, PID_PATH, PINNED_CLAUDE_CODE_HOST_VERSION, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, type RuntimeOutputLine, SOCKET_PATH, type SentrySurface, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, isServiceInstalled, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, restartService, setAgentContext, startDaemon, startService, stopExistingDaemon, stopService, uninstallService };
|
|
417
|
+
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, type AgentIdentity, type AgentWorkspaceConfig, type DaemonConfig, type DaemonHealth, type IPCEvent, type IPCRequest, type IPCResponse, type InitAgentSentryOptions, OPENCLAW_NODE_REQUIREMENT, PID_PATH, PINNED_CLAUDE_CODE_HOST_VERSION, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, type RuntimeOutputLine, SOCKET_PATH, type SentrySurface, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, isServiceInstalled, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, restartService, setAgentContext, startDaemon, startService, stopExistingDaemon, stopService, supportsOpenClawNode, uninstallService };
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
import { a as captureFatal, c as captureRuntimeCrash, d as initAgentSentry, f as setAgentContext, i as captureCliFailure, l as captureRuntimeErrorOutput, n as AGENT_MCP_SENTRY_DSN, o as captureIntegrationFailure, r as AGENT_RUNTIME_SENTRY_DSN, s as captureMcpFailure, t as AGENT_DAEMON_SENTRY_DSN, u as flushSentry } from "../sentry.js";
|
|
4
|
-
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, PID_PATH, PINNED_CLAUDE_CODE_HOST_VERSION, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, SOCKET_PATH, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, isServiceInstalled, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, restartService, setAgentContext, startDaemon, startService, stopExistingDaemon, stopService, uninstallService };
|
|
1
|
+
import { d as supportsOpenClawNode, l as OPENCLAW_NODE_REQUIREMENT, u as PINNED_OPENCLAW_VERSION } from "../runtime-process.js";
|
|
2
|
+
import { _ as loadDaemonConfig, a as installService, c as startService, d as uninstallService, f as PROTOCOL_VERSION, g as fetchAgentConfig, h as SOCKET_PATH, i as checkExistingDaemon, l as stopExistingDaemon, m as PID_PATH, n as queryDaemonHealth, o as isServiceInstalled, p as ALFE_DIR, r as startDaemon, s as restartService, t as formatHealthReport, u as stopService, v as resolveAgentIdentity, y as PINNED_CLAUDE_CODE_HOST_VERSION } from "../health.js";
|
|
3
|
+
import { a as captureFatal, c as captureRuntimeCrash, d as initAgentSentry, f as setAgentContext, i as captureCliFailure, l as captureRuntimeErrorOutput, m as logger, n as AGENT_MCP_SENTRY_DSN, o as captureIntegrationFailure, r as AGENT_RUNTIME_SENTRY_DSN, s as captureMcpFailure, t as AGENT_DAEMON_SENTRY_DSN, u as flushSentry } from "../sentry.js";
|
|
4
|
+
export { AGENT_DAEMON_SENTRY_DSN, AGENT_MCP_SENTRY_DSN, AGENT_RUNTIME_SENTRY_DSN, ALFE_DIR, OPENCLAW_NODE_REQUIREMENT, PID_PATH, PINNED_CLAUDE_CODE_HOST_VERSION, PINNED_OPENCLAW_VERSION, PROTOCOL_VERSION, SOCKET_PATH, captureCliFailure, captureFatal, captureIntegrationFailure, captureMcpFailure, captureRuntimeCrash, captureRuntimeErrorOutput, checkExistingDaemon, fetchAgentConfig, flushSentry, formatHealthReport, initAgentSentry, installService, isServiceInstalled, loadDaemonConfig, logger, queryDaemonHealth, resolveAgentIdentity, restartService, setAgentContext, startDaemon, startService, stopExistingDaemon, stopService, supportsOpenClawNode, uninstallService };
|
package/dist/upgrade.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as captureCliFailure } from "./sentry.js";
|
|
1
|
+
import { i as captureCliFailure, m as logger } from "./sentry.js";
|
|
3
2
|
import { existsSync } from "node:fs";
|
|
4
3
|
import { execFile } from "node:child_process";
|
|
5
4
|
import { promisify } from "node:util";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/gateway",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.19",
|
|
4
4
|
"description": "Alfe local gateway daemon — persistent control plane for agent integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"pino-roll": "^1.2.0",
|
|
24
24
|
"smol-toml": ">=1.6.1",
|
|
25
25
|
"ws": "^8.18.0",
|
|
26
|
-
"@alfe.ai/agent-api-client": "^0.19.
|
|
26
|
+
"@alfe.ai/agent-api-client": "^0.19.1",
|
|
27
27
|
"@alfe.ai/ai-proxy-local": "^0.0.17",
|
|
28
28
|
"@alfe.ai/config": "^0.4.1",
|
|
29
|
-
"@alfe.ai/integration-manifest": "^0.4.
|
|
30
|
-
"@alfe.ai/integrations": "^0.6.
|
|
29
|
+
"@alfe.ai/integration-manifest": "^0.4.2",
|
|
30
|
+
"@alfe.ai/integrations": "^0.6.6",
|
|
31
31
|
"@alfe.ai/mcp-bundler": "^0.4.2"
|
|
32
32
|
},
|
|
33
33
|
"license": "UNLICENSED",
|
package/dist/logger.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import pino from "pino";
|
|
4
|
-
import { mkdirSync } from "node:fs";
|
|
5
|
-
//#region src/logger.ts
|
|
6
|
-
/**
|
|
7
|
-
* Daemon logger — pino with rolling file output.
|
|
8
|
-
*
|
|
9
|
-
* Writes to ~/.alfe/logs/gateway.log with 10MB rotation, keep 5 files.
|
|
10
|
-
* In managed mode (ECS Fargate): always stdout for CloudWatch capture.
|
|
11
|
-
* In development: stdout.
|
|
12
|
-
*/
|
|
13
|
-
const LOG_DIR = join(homedir(), ".alfe", "logs");
|
|
14
|
-
const LOG_FILE = join(LOG_DIR, "gateway.log");
|
|
15
|
-
const isDev = process.env.NODE_ENV !== "production";
|
|
16
|
-
const isManaged = process.env.ALFE_MANAGED === "true";
|
|
17
|
-
if (!isManaged) try {
|
|
18
|
-
mkdirSync(LOG_DIR, { recursive: true });
|
|
19
|
-
} catch {}
|
|
20
|
-
/**
|
|
21
|
-
* Create the daemon logger.
|
|
22
|
-
* Managed mode (ECS): JSON to stdout (CloudWatch captures via awslogs driver).
|
|
23
|
-
* Development: JSON to stdout.
|
|
24
|
-
* Production (local): JSON to rolling file.
|
|
25
|
-
*/
|
|
26
|
-
function createLogger() {
|
|
27
|
-
if (isDev || isManaged) return pino({
|
|
28
|
-
level: process.env.LOG_LEVEL ?? (isDev ? "debug" : "info"),
|
|
29
|
-
transport: {
|
|
30
|
-
target: "pino/file",
|
|
31
|
-
options: { destination: 1 }
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
const transport = pino.transport({
|
|
35
|
-
target: "pino-roll",
|
|
36
|
-
options: {
|
|
37
|
-
file: LOG_FILE,
|
|
38
|
-
size: "10m",
|
|
39
|
-
limit: { count: 5 }
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
return pino({ level: process.env.LOG_LEVEL ?? "info" }, transport);
|
|
43
|
-
}
|
|
44
|
-
const logger = createLogger();
|
|
45
|
-
//#endregion
|
|
46
|
-
export { logger as n, LOG_FILE as t };
|