@alfe.ai/gateway 0.5.0 → 0.6.1

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.
Files changed (2) hide show
  1. package/dist/health.js +112 -16
  2. package/package.json +3 -3
package/dist/health.js CHANGED
@@ -5824,16 +5824,48 @@ var ReconciliationEngine = class {
5824
5824
  return;
5825
5825
  }
5826
5826
  if (local.version !== desired.version && desired.version !== "" && local.version !== "unknown") {
5827
- await this.ensureSuspended();
5828
- log$3.info(`Upgrading ${id}: ${local.version} → ${desired.version}`);
5829
- if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5830
- report.installed.push(id);
5831
- report.activated.push(id);
5832
- report.results.push({
5833
- integrationId: id,
5834
- action: "activated",
5835
- actualStatus: "active"
5836
- });
5827
+ if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
5828
+ await this.ensureSuspended();
5829
+ log$3.info(`Reinstalling ${id} on version change (reinstall requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt}): ${local.version} ${desired.version}`);
5830
+ this.manager.resetReinstallAttempts(id);
5831
+ this.activateAttempts.delete(id);
5832
+ if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5833
+ report.installed.push(id);
5834
+ report.activated.push(id);
5835
+ report.results.push({
5836
+ integrationId: id,
5837
+ action: "installed",
5838
+ actualStatus: "active"
5839
+ });
5840
+ return;
5841
+ }
5842
+ log$3.info(`Upgrading ${id} in place: ${local.version} → ${desired.version}`);
5843
+ try {
5844
+ if ((await this.manager.upgrade(id, desired.version, desired.config, desired.customSource, { onBeforeRuntimeMutation: () => this.ensureSuspended() })).configApplied) report.configApplied = true;
5845
+ this.manager.resetReinstallAttempts(id);
5846
+ this.activateAttempts.delete(id);
5847
+ report.installed.push(id);
5848
+ report.activated.push(id);
5849
+ report.results.push({
5850
+ integrationId: id,
5851
+ action: "activated",
5852
+ actualStatus: "active"
5853
+ });
5854
+ } catch (upgradeErr) {
5855
+ const upgradeMsg = upgradeErr instanceof Error ? upgradeErr.message : String(upgradeErr);
5856
+ log$3.error({ err: upgradeErr }, `Upgrade failed for ${id}`);
5857
+ captureIntegrationFailure(id, "upgrade", upgradeErr);
5858
+ report.errors.push({
5859
+ integrationId: id,
5860
+ error: upgradeMsg
5861
+ });
5862
+ report.results.push({
5863
+ integrationId: id,
5864
+ action: "error",
5865
+ actualStatus: "error",
5866
+ errorMessage: upgradeMsg
5867
+ });
5868
+ }
5837
5869
  return;
5838
5870
  }
5839
5871
  if (local.status === "error") {
@@ -5906,7 +5938,7 @@ var ReconciliationEngine = class {
5906
5938
  await this.ensureSuspended();
5907
5939
  log$3.info(`Re-activating ${id} from error state (attempt ${String(activateAttempts + 1)}/${String(MAX_ERROR_ACTIVATE_ATTEMPTS)})`);
5908
5940
  try {
5909
- if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
5941
+ if ((await this.manager.activate(id, { forcePlugins: true })).configApplied) report.configApplied = true;
5910
5942
  this.activateAttempts.delete(id);
5911
5943
  report.activated.push(id);
5912
5944
  report.results.push({
@@ -5946,10 +5978,74 @@ var ReconciliationEngine = class {
5946
5978
  });
5947
5979
  return;
5948
5980
  }
5981
+ if (local.status === "installing") {
5982
+ if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
5983
+ await this.ensureSuspended();
5984
+ log$3.info(`Reinstalling ${id} from stale installing state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
5985
+ this.manager.resetReinstallAttempts(id);
5986
+ this.activateAttempts.delete(id);
5987
+ if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
5988
+ report.installed.push(id);
5989
+ report.activated.push(id);
5990
+ report.results.push({
5991
+ integrationId: id,
5992
+ action: "installed",
5993
+ actualStatus: "active"
5994
+ });
5995
+ return;
5996
+ }
5997
+ const attempts = this.manager.getReinstallAttempts(id);
5998
+ if (attempts >= 3) {
5999
+ const errorMessage = `Stale installing state — max auto-reinstall attempts (${String(attempts)}) reached — manual reinstall required`;
6000
+ log$3.error(`Auto-reinstall blocked for ${id} — stuck in "installing", ${String(attempts)} consecutive failures. Manual reinstall required.`);
6001
+ captureIntegrationFailure(id, "reinstall", errorMessage);
6002
+ report.errors.push({
6003
+ integrationId: id,
6004
+ error: `Max auto-reinstall attempts (${String(attempts)}) reached`
6005
+ });
6006
+ report.results.push({
6007
+ integrationId: id,
6008
+ action: "error",
6009
+ actualStatus: "error",
6010
+ errorMessage
6011
+ });
6012
+ return;
6013
+ }
6014
+ await this.ensureSuspended();
6015
+ log$3.info(`Recovering ${id} from stale installing state via reinstall (attempt ${String(attempts + 1)}/3)`);
6016
+ this.manager.incrementReinstallAttempts(id);
6017
+ try {
6018
+ if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
6019
+ this.manager.resetReinstallAttempts(id);
6020
+ this.activateAttempts.delete(id);
6021
+ report.installed.push(id);
6022
+ report.activated.push(id);
6023
+ report.results.push({
6024
+ integrationId: id,
6025
+ action: "installed",
6026
+ actualStatus: "active"
6027
+ });
6028
+ } catch (reinstallErr) {
6029
+ const reinstallMsg = reinstallErr instanceof Error ? reinstallErr.message : String(reinstallErr);
6030
+ log$3.error({ err: reinstallErr }, `Reinstall from stale installing state failed for ${id}`);
6031
+ captureIntegrationFailure(id, "reinstall", reinstallErr);
6032
+ report.errors.push({
6033
+ integrationId: id,
6034
+ error: reinstallMsg
6035
+ });
6036
+ report.results.push({
6037
+ integrationId: id,
6038
+ action: "error",
6039
+ actualStatus: "error",
6040
+ errorMessage: reinstallMsg
6041
+ });
6042
+ }
6043
+ return;
6044
+ }
5949
6045
  if (local.status !== "active") {
5950
6046
  await this.ensureSuspended();
5951
6047
  log$3.info(`Activating ${id}`);
5952
- if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
6048
+ if ((await this.manager.activate(id, { forcePlugins: true })).configApplied) report.configApplied = true;
5953
6049
  report.activated.push(id);
5954
6050
  report.results.push({
5955
6051
  integrationId: id,
@@ -24277,10 +24373,6 @@ function handleIntegrationReport(params, pluginId) {
24277
24373
  */
24278
24374
  async function queryDaemonHealth(socketPath, timeoutMs = 5e3) {
24279
24375
  return new Promise((resolve, reject) => {
24280
- const timer = setTimeout(() => {
24281
- socket.destroy();
24282
- reject(/* @__PURE__ */ new Error("Health check timed out"));
24283
- }, timeoutMs);
24284
24376
  let buffer = "";
24285
24377
  const requestId = randomUUID();
24286
24378
  const socket = createConnection(socketPath, () => {
@@ -24292,6 +24384,10 @@ async function queryDaemonHealth(socketPath, timeoutMs = 5e3) {
24292
24384
  }) + "\n";
24293
24385
  socket.write(request);
24294
24386
  });
24387
+ const timer = setTimeout(() => {
24388
+ socket.destroy();
24389
+ reject(/* @__PURE__ */ new Error("Health check timed out"));
24390
+ }, timeoutMs);
24295
24391
  socket.on("data", (data) => {
24296
24392
  buffer += data.toString();
24297
24393
  const newlineIdx = buffer.indexOf("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
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.8.0",
27
26
  "@alfe.ai/ai-proxy-local": "^0.0.13",
27
+ "@alfe.ai/agent-api-client": "^0.8.0",
28
28
  "@alfe.ai/config": "^0.3.0",
29
29
  "@alfe.ai/integration-manifest": "^0.3.1",
30
- "@alfe.ai/integrations": "^0.2.10",
30
+ "@alfe.ai/integrations": "^0.3.2",
31
31
  "@alfe.ai/mcp-bundler": "^0.3.0"
32
32
  },
33
33
  "license": "UNLICENSED",