@alfe.ai/gateway 0.10.7 → 0.10.8

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 +20 -1
  2. package/package.json +4 -4
package/dist/health.js CHANGED
@@ -5931,6 +5931,13 @@ const log$6 = logger.child({ component: "RuntimeGate" });
5931
5931
  var RuntimeGate = class {
5932
5932
  depth = 0;
5933
5933
  wasRunning = false;
5934
+ /**
5935
+ * True once the OUTERMOST `enter()` has finished stopping the runtime child
5936
+ * (its `stopWhenIdle()` resolved, i.e. the process exited), until the gate
5937
+ * fully reopens. `depth > 0` alone is not enough: depth is bumped before the
5938
+ * stop is awaited, so it is already set while the old child is draining.
5939
+ */
5940
+ stopSettled = false;
5934
5941
  exclusive = false;
5935
5942
  /** Brackets parked behind an exclusive hold (or an exclusive request parked behind open brackets). */
5936
5943
  waiters = [];
@@ -5945,6 +5952,14 @@ var RuntimeGate = class {
5945
5952
  get isSuspended() {
5946
5953
  return this.depth > 0;
5947
5954
  }
5955
+ /**
5956
+ * Whether the runtime child is PROVABLY down right now: a bracket is open and
5957
+ * its stop has completed. The OpenClaw applier's one direct openclaw.json
5958
+ * write (the dangling channel-ref repair) is allow-listed on this.
5959
+ */
5960
+ get isRuntimeStopped() {
5961
+ return this.depth > 0 && this.stopSettled;
5962
+ }
5948
5963
  /** True while an exclusive bracket is open. */
5949
5964
  get isExclusive() {
5950
5965
  return this.exclusive;
@@ -5997,12 +6012,14 @@ var RuntimeGate = class {
5997
6012
  }
5998
6013
  async enter() {
5999
6014
  if (this.depth++ > 0) return;
6015
+ this.stopSettled = false;
6000
6016
  const rp = this.getRuntime();
6001
6017
  this.wasRunning = rp?.isActive ?? false;
6002
6018
  if (rp && this.wasRunning) {
6003
6019
  log$6.info("Suspending runtime for mutating reconcile (avoid concurrent SQLite writers)");
6004
6020
  await rp.stopWhenIdle();
6005
6021
  }
6022
+ if (this.depth > 0) this.stopSettled = true;
6006
6023
  }
6007
6024
  /**
6008
6025
  * Resume the runtime child. Only the outermost call (depth 1 → 0) actually
@@ -6019,6 +6036,7 @@ var RuntimeGate = class {
6019
6036
  rp.resume();
6020
6037
  }
6021
6038
  this.wasRunning = false;
6039
+ this.stopSettled = false;
6022
6040
  if (this.exclusive) this.exclusive = false;
6023
6041
  this.wakeWaiters();
6024
6042
  return Promise.resolve();
@@ -10147,7 +10165,8 @@ async function startDaemon() {
10147
10165
  runtimeAppliers.set(name, new OpenClawApplier({
10148
10166
  home: runtimeCfg.workspace,
10149
10167
  agentWorkspace: runtimeCfg.agentWorkspace,
10150
- cliLock: openclawCliLock
10168
+ cliLock: openclawCliLock,
10169
+ isRuntimeStopped: () => name === config.runtime && runtimeGateRef instanceof RuntimeGate && runtimeGateRef.isRuntimeStopped && runtimeProcess !== null && !runtimeProcess.isActive
10151
10170
  }));
10152
10171
  logger.info({
10153
10172
  runtime: name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.10.7",
3
+ "version": "0.10.8",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,11 +24,11 @@
24
24
  "smol-toml": ">=1.6.1",
25
25
  "ws": "^8.18.0",
26
26
  "@alfe.ai/agent-api-client": "^0.19.2",
27
+ "@alfe.ai/ai-proxy-local": "^0.0.17",
27
28
  "@alfe.ai/config": "^0.4.1",
28
29
  "@alfe.ai/integration-manifest": "^0.4.2",
29
- "@alfe.ai/integrations": "^0.6.13",
30
- "@alfe.ai/mcp-bundler": "^0.4.2",
31
- "@alfe.ai/ai-proxy-local": "^0.0.17"
30
+ "@alfe.ai/integrations": "^0.6.15",
31
+ "@alfe.ai/mcp-bundler": "^0.4.3"
32
32
  },
33
33
  "license": "UNLICENSED",
34
34
  "homepage": "https://alfe.ai",