From b43d3f1b7087608a9802fc24b8f8567f3d19e664 Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Sat, 21 Feb 2026 16:16:08 -0800 Subject: [PATCH] fix: combine gateway start + port wait into single SSH session (#1642) The old flow opened up to 60+ separate fly ssh console sessions to poll port 18789 after starting the gateway daemon. Each session opens a new WireGuard tunnel which is slow and flaky. Now: one SSH session starts the daemon, then polls the port in-band with a simple for loop. Output from the loop also serves as a keepalive for flyctl. Co-authored-by: lab <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) --- cli/package.json | 2 +- cli/src/fly/agents.ts | 35 ++++++----------------------------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/cli/package.json b/cli/package.json index f3d45f1b..d1fae0a5 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.5.28", + "version": "0.5.29", "type": "module", "bin": { "spawn": "cli.js" diff --git a/cli/src/fly/agents.ts b/cli/src/fly/agents.ts index 9adb0473..c00c2f45 100644 --- a/cli/src/fly/agents.ts +++ b/cli/src/fly/agents.ts @@ -13,7 +13,6 @@ import { } from "./ui"; import { runServer, - runServerCapture, uploadFile, runWithRetry, } from "./fly"; @@ -277,33 +276,14 @@ async function setupOpenclawConfig( await uploadConfigFile(config, "$HOME/.openclaw/openclaw.json"); } -async function startOpenclawGateway(): Promise { +async function startGateway(): Promise { logStep("Starting OpenClaw gateway daemon..."); await runServer( - "source ~/.spawnrc 2>/dev/null; export PATH=$(npm prefix -g 2>/dev/null)/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; if command -v setsid >/dev/null 2>&1; then setsid openclaw gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & else nohup openclaw gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & fi", + `source ~/.spawnrc 2>/dev/null; export PATH=$(npm prefix -g 2>/dev/null)/bin:$HOME/.bun/bin:$HOME/.local/bin:$PATH; ` + + `if command -v setsid >/dev/null 2>&1; then setsid openclaw gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & ` + + `else nohup openclaw gateway > /tmp/openclaw-gateway.log 2>&1 < /dev/null & fi`, ); -} - -async function waitForOpenclawGateway(): Promise { - logStep("Waiting for OpenClaw gateway to start..."); - const maxWait = 60; - for (let elapsed = 0; elapsed < maxWait; elapsed++) { - try { - await runServerCapture( - `nc -z 127.0.0.1 18789 2>/dev/null || (command -v telnet >/dev/null && timeout 1 telnet 127.0.0.1 18789 2>&1 | grep -q Connected)`, - 5, - ); - logInfo(`Gateway ready after ${elapsed}s`); - return; - } catch { /* not ready */ } - await new Promise((r) => setTimeout(r, 1000)); - } - logError(`OpenClaw gateway failed to start after ${maxWait}s`); - logInfo("Check gateway logs: cat /tmp/openclaw-gateway.log"); - try { - await runServer("tail -10 /tmp/openclaw-gateway.log 2>/dev/null || true"); - } catch { /* ignore */ } - throw new Error("OpenClaw gateway timeout"); + logInfo("OpenClaw gateway started"); } // ─── OpenCode Install Command ──────────────────────────────────────────────── @@ -358,10 +338,7 @@ export const agents: Record = { ], configure: (apiKey, modelId) => setupOpenclawConfig(apiKey, modelId || "openrouter/auto"), - preLaunch: async () => { - await startOpenclawGateway(); - await waitForOpenclawGateway(); - }, + preLaunch: startGateway, launchCmd: () => "source ~/.spawnrc 2>/dev/null; source ~/.zshrc 2>/dev/null; openclaw tui", },