@vama/openclaw 2026.5.5-7 → 2026.5.5-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.
@@ -3,7 +3,7 @@ import { i as dispatchStarted, r as dispatchEnded } from "./monitor-BlnFXk24.js"
3
3
  //#region extensions/vama/src/cli-metadata.ts
4
4
  function registerVamaCliMetadata(api) {
5
5
  api.registerCli(async ({ program }) => {
6
- const { registerVamaCli } = await import("./cli-uxMxzdnO.js");
6
+ const { registerVamaCli } = await import("./cli-Cvvx81W1.js");
7
7
  registerVamaCli({ program });
8
8
  }, { descriptors: [{
9
9
  name: "vama",
package/dist/api.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-CBt1Mjce.js";
1
+ import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-BrUg_tjH.js";
2
2
  import { n as probeVama } from "./probe-COpuChEq.js";
3
3
  import { n as sendMessageVama, t as monitorVamaProvider } from "./monitor-BlnFXk24.js";
4
4
  export { monitorVamaProvider, probeVama, registerVamaCliMetadata, registerVamaSubagentKeepaliveHooks, sendMessageVama };
@@ -4,8 +4,10 @@ import { t as getVamaRuntime } from "./runtime-CQ9kld4S.js";
4
4
  import { t as parseVamaConnectCode } from "./connect-code-Bbp9J6TH.js";
5
5
  import fs from "node:fs";
6
6
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
7
- import { spawn } from "node:child_process";
7
+ import { execFile, spawn } from "node:child_process";
8
+ import { promisify } from "node:util";
8
9
  //#region extensions/vama/src/connect-verify.ts
10
+ const execFileAsync = promisify(execFile);
9
11
  /**
10
12
  * Post-connect verification: make `openclaw vama connect` end with a TRUE
11
13
  * statement about liveness instead of "credentials look right, good luck".
@@ -134,6 +136,86 @@ async function ensureGatewayRunning(params, deps = {}) {
134
136
  detail: (install.output || start.output).split("\n").slice(-4).join("\n").trim() || void 0
135
137
  };
136
138
  }
139
+ /** lsof-based lookup of whoever LISTENs on the gateway port (POSIX only). */
140
+ async function findGatewayPortOwner(port) {
141
+ try {
142
+ const { stdout } = await execFileAsync("lsof", [
143
+ "-ti",
144
+ `tcp:${port}`,
145
+ "-sTCP:LISTEN"
146
+ ], { timeout: 5e3 });
147
+ const pid = Number.parseInt(stdout.trim().split("\n")[0] ?? "", 10);
148
+ if (!Number.isInteger(pid) || pid <= 0) return null;
149
+ const { stdout: comm } = await execFileAsync("ps", [
150
+ "-p",
151
+ String(pid),
152
+ "-o",
153
+ "comm="
154
+ ], { timeout: 5e3 });
155
+ return {
156
+ pid,
157
+ command: comm.trim()
158
+ };
159
+ } catch {
160
+ return null;
161
+ }
162
+ }
163
+ const OPENCLAW_PROCESS_RE = /openclaw|node|bun/i;
164
+ /**
165
+ * Kill a wedged gateway process squatting the port. Real-world case (seen on
166
+ * a user machine): a days-old `openclaw gateway run` whose HTTP side still
167
+ * answers /health but whose WS stack hangs up every connection — config
168
+ * reloads can't reach it, and it never dials BotHub. Killing it is the only
169
+ * way to one-step that machine. Refuses to touch processes that don't look
170
+ * like an OpenClaw/Node gateway.
171
+ */
172
+ async function killStaleGateway(port, deps = {}) {
173
+ const findOwner = deps.findOwner ?? findGatewayPortOwner;
174
+ const probe = deps.probe ?? isGatewayUp;
175
+ const sleep = deps.sleep ?? defaultSleep;
176
+ const kill = deps.kill ?? ((pid, signal) => process.kill(pid, signal));
177
+ const owner = await findOwner(port);
178
+ if (!owner) return {
179
+ killed: false,
180
+ reason: `could not identify the process on port ${port}`
181
+ };
182
+ if (!OPENCLAW_PROCESS_RE.test(owner.command)) return {
183
+ killed: false,
184
+ pid: owner.pid,
185
+ reason: `port ${port} is held by "${owner.command}" (pid ${owner.pid}), which does not look like an OpenClaw gateway — not touching it`
186
+ };
187
+ try {
188
+ kill(owner.pid, "SIGTERM");
189
+ } catch (err) {
190
+ return {
191
+ killed: false,
192
+ pid: owner.pid,
193
+ reason: err instanceof Error ? err.message : String(err)
194
+ };
195
+ }
196
+ for (let i = 0; i < 8; i += 1) {
197
+ await sleep(500);
198
+ if (!await probe(port)) return {
199
+ killed: true,
200
+ pid: owner.pid
201
+ };
202
+ }
203
+ try {
204
+ kill(owner.pid, "SIGKILL");
205
+ } catch {}
206
+ for (let i = 0; i < 4; i += 1) {
207
+ await sleep(500);
208
+ if (!await probe(port)) return {
209
+ killed: true,
210
+ pid: owner.pid
211
+ };
212
+ }
213
+ return {
214
+ killed: false,
215
+ pid: owner.pid,
216
+ reason: `process ${owner.pid} survived SIGTERM+SIGKILL or the port did not free up`
217
+ };
218
+ }
137
219
  /**
138
220
  * Poll GET /v1/bot/me until `ws_connected` is true. "unsupported" means the
139
221
  * server doesn't report the field yet (BotHub older than this feature) —
@@ -233,6 +315,7 @@ async function runVamaConnect(params, deps = {}) {
233
315
  const probe = deps.probe ?? probeVama;
234
316
  const ensureGateway = deps.ensureGateway ?? ensureGatewayRunning;
235
317
  const waitForLive = deps.waitForLive ?? waitForWSConnected;
318
+ const killStale = deps.killStale ?? killStaleGateway;
236
319
  const log = deps.log ?? ((msg) => console.log(msg));
237
320
  const parsed = parseVamaConnectCode(params.rawCode);
238
321
  const runtime = getVamaRuntime();
@@ -282,8 +365,9 @@ async function runVamaConnect(params, deps = {}) {
282
365
  result.liveCheck = "skipped";
283
366
  return result;
284
367
  }
368
+ const port = resolveGatewayPort(updated);
285
369
  const gateway = await ensureGateway({
286
- port: resolveGatewayPort(updated),
370
+ port,
287
371
  log
288
372
  });
289
373
  result.gatewayAction = gateway.action;
@@ -298,10 +382,30 @@ async function runVamaConnect(params, deps = {}) {
298
382
  return result;
299
383
  }
300
384
  log("Waiting for your agent to come online…");
301
- const live = await waitForLive({
385
+ let live = await waitForLive({
302
386
  bothubUrl,
303
387
  botToken: exchanged.bot_token
304
388
  });
389
+ if (live.status !== "live" && live.status !== "unsupported" && gateway.action === "already-running") {
390
+ log("A gateway is running but never connected to Vama — replacing it…");
391
+ const killed = await killStale(port);
392
+ if (killed.killed) {
393
+ result.staleGatewayKilled = true;
394
+ const retry = await ensureGateway({
395
+ port,
396
+ log
397
+ });
398
+ result.gatewayAction = retry.action;
399
+ if (retry.detail) result.gatewayDetail = retry.detail;
400
+ if (retry.up) {
401
+ log("Waiting for your agent to come online…");
402
+ live = await waitForLive({
403
+ bothubUrl,
404
+ botToken: exchanged.bot_token
405
+ });
406
+ }
407
+ } else if (killed.reason) result.gatewayDetail = killed.reason;
408
+ }
305
409
  result.liveCheck = live.status;
306
410
  result.live = live.status === "live";
307
411
  if (live.error) result.liveError = live.error;
@@ -321,6 +425,7 @@ function printConnectResult(result) {
321
425
  if (result.websocketEnabled) console.log(" Transport: WebSocket — no tunnel or public URL needed.");
322
426
  else console.log(" Transport: webhook — set channels.vama.webhookUrl to a public URL (or mint a new code from Vama settings to enable WebSocket).");
323
427
  if (result.gatewayAction) console.log(` Gateway: ${GATEWAY_ACTION_LABEL[result.gatewayAction]}`);
428
+ if (result.staleGatewayKilled) console.log(" Replaced a stale gateway process that was holding the port.");
324
429
  if (result.probeOk === false && result.probeError) console.log(` Verification warning: ${result.probeError}`);
325
430
  console.log("");
326
431
  if (result.live) {
@@ -347,6 +452,7 @@ function printConnectResult(result) {
347
452
  default:
348
453
  console.log("⚠ NOT live yet — gateway is up but BotHub hasn't seen its connection.");
349
454
  if (result.liveError) console.log(` Last error: ${result.liveError}`);
455
+ if (result.gatewayDetail) console.log(` ${result.gatewayDetail}`);
350
456
  console.log(" It may just be slow. Check again with: openclaw channels status --probe");
351
457
  console.log(" Gateway logs: openclaw gateway status");
352
458
  return;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-CBt1Mjce.js";
1
+ import { n as registerVamaCliMetadata, t as registerVamaSubagentKeepaliveHooks } from "./api-BrUg_tjH.js";
2
2
  import { n as probeVama } from "./probe-COpuChEq.js";
3
3
  import { n as sendMessageVama, t as monitorVamaProvider } from "./monitor-BlnFXk24.js";
4
4
  import { n as setVamaRuntime } from "./runtime-CQ9kld4S.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vama/openclaw",
3
- "version": "2026.5.5-7",
3
+ "version": "2026.5.5-8",
4
4
  "description": "OpenClaw Vama channel plugin via BotHub",
5
5
  "homepage": "https://web.vama.com/connect-guide",
6
6
  "repository": {