From a2dfddec3db739aef05fd05929c4100f1808e913 Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Sat, 21 Feb 2026 16:01:47 -0800 Subject: [PATCH] fix: add keepalive to fly ssh + stop suppressing install output (#1641) Two fixes for "session forcibly closed" during openclaw install: 1. The openclaw install command piped all output to /dev/null, so flyctl saw zero bytes flowing and killed the session. Removed the >/dev/null 2>&1 redirect. 2. Added a background keepalive to runServer that prints a dot to stderr every 10s. This prevents flyctl from tearing down silent SSH sessions even if the command itself produces no output for a while. Co-authored-by: lab <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) --- cli/src/fly/fly.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cli/src/fly/fly.ts b/cli/src/fly/fly.ts index c98608e5..90c749ce 100644 --- a/cli/src/fly/fly.ts +++ b/cli/src/fly/fly.ts @@ -630,7 +630,12 @@ export async function runServer( const fullCmd = `export PATH="$HOME/.local/bin:$HOME/.bun/bin:$PATH" && ${cmd}`; const flyCmd = getCmd()!; - const escapedCmd = fullCmd.replace(/'/g, "'\\''"); + // Wrap command with a background keepalive that prints a dot to stderr every + // 10s. Without this, flyctl tears down silent SSH sessions ("session forcibly + // closed") when no data flows for too long (e.g. during bun install). + const wrappedCmd = `(while true; do sleep 10; printf '.' >&2; done) & _ka=$!; (${fullCmd}); _rc=$?; kill $_ka 2>/dev/null; wait $_ka 2>/dev/null; exit $_rc`; + + const escapedCmd = wrappedCmd.replace(/'/g, "'\\''"); // Use fly ssh console (WireGuard) instead of fly machine exec (HTTP) to avoid // 408 deadline_exceeded on long-running commands. const args = [flyCmd, "ssh", "console", "-a", flyAppName, "-C", `bash -c '${escapedCmd}'`];