From 729ae64822391fdd1ffeaa7ca92648db86095313 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 25 Nov 2025 05:47:06 +0100 Subject: [PATCH] feat: add relay:tmux helper for relay watcher --- src/cli/program.ts | 14 ++++++++++++++ src/cli/relay_tmux.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/cli/relay_tmux.ts diff --git a/src/cli/program.ts b/src/cli/program.ts index 233f1ce03..b4444e71d 100644 --- a/src/cli/program.ts +++ b/src/cli/program.ts @@ -11,6 +11,7 @@ import { pickProvider } from "../provider-web.js"; import type { Provider } from "../utils.js"; import { createDefaultDeps, logWebSelfId, logTwilioFrom, monitorTwilio } from "./deps.js"; import { ensureTwilioEnv } from "../env.js"; +import { spawnRelayTmux } from "./relay_tmux.js"; export function buildProgram() { const program = new Command(); @@ -250,5 +251,18 @@ With Tailscale: } }); + program + .command("relay:tmux") + .description("Run relay --verbose inside tmux (session warelay-relay), restarting if already running") + .action(async () => { + try { + const session = await spawnRelayTmux(); + defaultRuntime.log(info(`tmux session started: ${session} (pane running "pnpm warelay relay --verbose")`)); + } catch (err) { + defaultRuntime.error(danger(`Failed to start relay tmux session: ${String(err)}`)); + defaultRuntime.exit(1); + } + }); + return program; } diff --git a/src/cli/relay_tmux.ts b/src/cli/relay_tmux.ts new file mode 100644 index 000000000..049d88809 --- /dev/null +++ b/src/cli/relay_tmux.ts @@ -0,0 +1,29 @@ +import { spawn } from "node:child_process"; + +const SESSION = "warelay-relay"; + +export async function spawnRelayTmux(cmd = "pnpm warelay relay --verbose") { + await killSession(SESSION); + await new Promise((resolve, reject) => { + const child = spawn("tmux", ["new", "-d", "-s", SESSION, cmd], { + stdio: "inherit", + shell: false, + }); + child.on("error", reject); + child.on("exit", (code) => { + if (code === 0) resolve(); + else reject(new Error(`tmux exited with code ${code}`)); + }); + }); + return SESSION; +} + +async function killSession(name: string) { + await new Promise((resolve) => { + const child = spawn("tmux", ["kill-session", "-t", name], { + stdio: "ignore", + }); + child.on("exit", () => resolve()); + child.on("error", () => resolve()); + }); +}