@alfe.ai/gateway 0.9.17 → 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.
@@ -1,38 +1,31 @@
1
- import { n as logger } from "./logger.js";
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 — install/update the runtime binary then cycle the RuntimeProcess.
10
+ * Runtime upgrade — safely replace a runtime binary and cycle its child.
7
11
  *
8
- * Unlike CLI upgrade (which exits the daemon for systemd restart),
9
- * runtime upgrade keeps the daemon running and just restarts the child process.
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
- * Flow (generic across runtimes):
12
- * 1. Stop the RuntimeProcess child (SIGTERM + grace period)
13
- * 2. Run the per-runtime upgrade command (see `resolveUpgradeCommand`)
14
- * 3. Restart the RuntimeProcess child
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
- * Resolve the per-runtime upgrade command.
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
- async function upgradeRuntime(runtime, version, runtimeProcess) {
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
- if (runtimeProcess) {
85
- logger.info("Stopping runtime for upgrade...");
86
- await runtimeProcess.stopWhenIdle();
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
- const { stdout, stderr } = await execFileAsync(cmd.command, cmd.args, { timeout: 12e4 });
90
- if (stdout) logger.debug({ stdout: stdout.trim() }, "runtime upgrade stdout");
91
- if (stderr) logger.debug({ stderr: stderr.trim() }, "runtime upgrade stderr");
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 install command failed");
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 };
@@ -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
- * - the managed Docker image (`services/compute/Dockerfile` — build args can't import
48
- * TypeScript, so it hardcodes this same value; keep them in sync)
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.6.11";
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 { _ as loadDaemonConfig, a as installService, b as PINNED_OPENCLAW_VERSION, 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";
2
- import { n as logger } from "../logger.js";
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 { n as logger } from "./logger.js";
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.17",
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.0",
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.1",
30
- "@alfe.ai/integrations": "^0.6.5",
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 };