@alfe.ai/gateway 0.0.11 → 0.0.13

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/health.js CHANGED
@@ -3755,9 +3755,12 @@ var ReconciliationEngine = class {
3755
3755
  log$2.info(`Installing ${id}@${desired.version}`);
3756
3756
  await this.manager.install(id, desired.version, desired.config);
3757
3757
  report.installed.push(id);
3758
+ log$2.info(`Activating ${id}`);
3759
+ await this.manager.activate(id);
3760
+ report.activated.push(id);
3758
3761
  report.results.push({
3759
3762
  integrationId: id,
3760
- action: "installed",
3763
+ action: "activated",
3761
3764
  actualStatus: "active"
3762
3765
  });
3763
3766
  return;
@@ -3770,9 +3773,12 @@ var ReconciliationEngine = class {
3770
3773
  } catch {}
3771
3774
  await this.manager.install(id, desired.version, desired.config);
3772
3775
  report.installed.push(id);
3776
+ log$2.info(`Activating ${id}`);
3777
+ await this.manager.activate(id);
3778
+ report.activated.push(id);
3773
3779
  report.results.push({
3774
3780
  integrationId: id,
3775
- action: "installed",
3781
+ action: "activated",
3776
3782
  actualStatus: "active"
3777
3783
  });
3778
3784
  return;
@@ -3867,6 +3873,7 @@ var CloudClient = class {
3867
3873
  onCommand = null;
3868
3874
  onConnectionChange = null;
3869
3875
  onServiceRelay = null;
3876
+ onPluginsChanged = null;
3870
3877
  reconciliationEngine = null;
3871
3878
  constructor(config) {
3872
3879
  this.config = config;
@@ -3904,6 +3911,12 @@ var CloudClient = class {
3904
3911
  * Set the integration manager for reconciliation.
3905
3912
  * When set, the cloud client will handle DESIRED_STATE messages automatically.
3906
3913
  */
3914
+ /**
3915
+ * Set a callback for when plugins change (install/uninstall) — used to restart the runtime.
3916
+ */
3917
+ setPluginsChangedHandler(handler) {
3918
+ this.onPluginsChanged = handler;
3919
+ }
3907
3920
  setIntegrationManager(manager) {
3908
3921
  this.reconciliationEngine = new ReconciliationEngine(manager);
3909
3922
  }
@@ -4100,6 +4113,7 @@ var CloudClient = class {
4100
4113
  }, "Cloud: reconciliation complete");
4101
4114
  const reportMsg = createReconciliationReport(report.results);
4102
4115
  this.send(reportMsg);
4116
+ if ((report.installed.length > 0 || report.uninstalled.length > 0) && this.onPluginsChanged) this.onPluginsChanged();
4103
4117
  } catch (err) {
4104
4118
  const message = err instanceof Error ? err.message : String(err);
4105
4119
  logger$1.error({ err: message }, "Cloud: reconciliation failed");
@@ -4588,22 +4602,13 @@ function getSystemdServicePath() {
4588
4602
  return join(homedir(), ".config", "systemd", "user", `${SYSTEMD_SERVICE}.service`);
4589
4603
  }
4590
4604
  /**
4591
- * Resolve the path to the gateway binary.
4605
+ * Resolve the alfe CLI path. Globally installed via npm, always in PATH.
4592
4606
  */
4593
- function getGatewayBinPath() {
4594
- const globalBin = process.env.ALFE_GATEWAY_BIN;
4595
- if (globalBin) return globalBin;
4596
- for (const rel of ["../bin/gateway.js", "bin/gateway.js"]) {
4597
- const candidate = join(import.meta.dirname, rel);
4598
- if (existsSync(candidate)) return candidate;
4599
- }
4600
- return "alfe-gateway";
4601
- }
4602
- function getNodePath() {
4607
+ function getAlfeBinPath() {
4603
4608
  try {
4604
- return execSync("which node", { encoding: "utf-8" }).trim();
4609
+ return execSync("which alfe", { encoding: "utf-8" }).trim();
4605
4610
  } catch {
4606
- return "/usr/local/bin/node";
4611
+ return "alfe";
4607
4612
  }
4608
4613
  }
4609
4614
  /**
@@ -4618,8 +4623,8 @@ function generateLaunchdPlist() {
4618
4623
  <string>${LAUNCHD_LABEL}</string>
4619
4624
  <key>ProgramArguments</key>
4620
4625
  <array>
4621
- <string>${getNodePath()}</string>
4622
- <string>${getGatewayBinPath()}</string>
4626
+ <string>${getAlfeBinPath()}</string>
4627
+ <string>gateway</string>
4623
4628
  <string>daemon</string>
4624
4629
  </array>
4625
4630
  <key>RunAtLoad</key>
@@ -4647,8 +4652,7 @@ function generateLaunchdPlist() {
4647
4652
  * Root users get a system-level unit; non-root get a user-level unit.
4648
4653
  */
4649
4654
  function generateSystemdUnit() {
4650
- const nodePath = getNodePath();
4651
- const gatewayBin = getGatewayBinPath();
4655
+ const alfeBin = getAlfeBinPath();
4652
4656
  const root = isRootUser();
4653
4657
  const envLines = [
4654
4658
  "ALFE_MANAGED",
@@ -4662,7 +4666,7 @@ Wants=network-online.target
4662
4666
 
4663
4667
  [Service]
4664
4668
  Type=simple
4665
- ExecStart=${nodePath} ${gatewayBin} daemon
4669
+ ExecStart=${alfeBin} gateway daemon
4666
4670
  Restart=always
4667
4671
  RestartSec=10
4668
4672
  Environment=NODE_ENV=production${root ? "\nEnvironment=HOME=/root\nWorkingDirectory=/root" : ""}
@@ -19896,6 +19900,16 @@ var RuntimeProcess = class {
19896
19900
  });
19897
19901
  }
19898
19902
  /**
19903
+ * Restart the runtime process (stop then start with fresh backoff).
19904
+ */
19905
+ async restart() {
19906
+ log$1.info({ runtime: this.options.runtime }, "Restarting runtime...");
19907
+ await this.stop();
19908
+ this.stopped = false;
19909
+ this.backoffMs = BACKOFF_INITIAL_MS;
19910
+ this.start();
19911
+ }
19912
+ /**
19899
19913
  * Whether the runtime process is currently running.
19900
19914
  */
19901
19915
  get isRunning() {
@@ -20181,18 +20195,19 @@ async function startDaemon() {
20181
20195
  const { createProxyServer, DEFAULT_AI_PROXY_PORT } = await import("@alfe.ai/ai-proxy-local");
20182
20196
  const { getAiServiceUrlFromToken } = await import("@alfe.ai/config");
20183
20197
  const proxyUrl = getAiServiceUrlFromToken(config.apiKey);
20198
+ const port = DEFAULT_AI_PROXY_PORT ?? 18193;
20184
20199
  aiProxyServer = createProxyServer({
20185
- port: DEFAULT_AI_PROXY_PORT,
20200
+ port,
20186
20201
  apiKey: config.apiKey,
20187
20202
  proxyUrl
20188
20203
  });
20189
20204
  const server = aiProxyServer;
20190
20205
  await new Promise((resolve, reject) => {
20191
- server.listen(DEFAULT_AI_PROXY_PORT, "127.0.0.1", () => {
20206
+ server.listen(port, "127.0.0.1", () => {
20192
20207
  aiProxyRunning = true;
20193
- aiProxyUrl = `http://127.0.0.1:${String(DEFAULT_AI_PROXY_PORT)}`;
20208
+ aiProxyUrl = `http://127.0.0.1:${String(port)}`;
20194
20209
  logger$1.info({
20195
- port: DEFAULT_AI_PROXY_PORT,
20210
+ port,
20196
20211
  upstream: proxyUrl
20197
20212
  }, "AI proxy started");
20198
20213
  resolve();
@@ -20262,6 +20277,14 @@ async function startDaemon() {
20262
20277
  });
20263
20278
  const integrationAdapter = new IntegrationManagerAdapter(integrationManager);
20264
20279
  cloudClient.setIntegrationManager(integrationAdapter);
20280
+ cloudClient.setPluginsChangedHandler(() => {
20281
+ if (runtimeProcess) {
20282
+ logger$1.info("Plugins changed — restarting runtime to load new plugins");
20283
+ runtimeProcess.restart().catch((err) => {
20284
+ logger$1.error({ err: err instanceof Error ? err.message : String(err) }, "Failed to restart runtime");
20285
+ });
20286
+ }
20287
+ });
20265
20288
  cloudClient.start();
20266
20289
  logger$1.debug("Cloud client started");
20267
20290
  if (config.autoStartRuntime && config.runtime) {
@@ -20283,6 +20306,8 @@ async function startDaemon() {
20283
20306
  ALFE_AGENT_ID: config.agentId,
20284
20307
  ANTHROPIC_BASE_URL: aiProxyUrl ?? "http://127.0.0.1:18193",
20285
20308
  OPENAI_BASE_URL: aiProxyUrl ?? "http://127.0.0.1:18193",
20309
+ ANTHROPIC_API_KEY: config.apiKey,
20310
+ OPENAI_API_KEY: config.apiKey,
20286
20311
  OPENCLAW_GATEWAY_TOKEN: runtimeToken
20287
20312
  }
20288
20313
  });
package/dist/upgrade.js CHANGED
@@ -27,6 +27,7 @@ async function spawnUpgradeScript(version) {
27
27
  const scriptPath = `/tmp/alfe-upgrade-${String(Date.now())}.sh`;
28
28
  await writeFile(scriptPath, `#!/bin/bash
29
29
  set -euo pipefail
30
+ exec > /tmp/alfe-upgrade.log 2>&1
30
31
 
31
32
  # Wait for daemon to finish sending COMMAND_ACK
32
33
  sleep 2
@@ -37,10 +38,7 @@ systemctl stop alfe-gateway
37
38
  # Upgrade CLI to target version
38
39
  npm install -g @alfe.ai/cli@${version}
39
40
 
40
- # Re-run setup to regenerate systemd unit with new binary path
41
- alfe setup --managed
42
-
43
- # Start the service — daemon will reconnect with new version
41
+ # Restart systemd ExecStart resolves the new binary automatically
44
42
  systemctl start alfe-gateway
45
43
 
46
44
  # Clean up
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,10 +22,10 @@
22
22
  "pino-roll": "^1.2.0",
23
23
  "smol-toml": ">=1.6.1",
24
24
  "ws": "^8.18.0",
25
- "@alfe.ai/ai-proxy-local": "^0.0.2",
26
- "@alfe.ai/config": "^0.0.2",
27
- "@alfe.ai/doctor": "^0.0.2",
28
- "@alfe.ai/integrations": "^0.0.4"
25
+ "@alfe.ai/ai-proxy-local": "^0.0.3",
26
+ "@alfe.ai/config": "^0.0.3",
27
+ "@alfe.ai/doctor": "^0.0.3",
28
+ "@alfe.ai/integrations": "^0.0.6"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/ws": "^8.5.13",