From 02aeff8efcd604bbab0effba3ed71b247ff00ebb Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 9 Jan 2026 14:43:46 +0100 Subject: [PATCH] style(gateway): multiline discovery output --- src/cli/gateway-cli.coverage.test.ts | 36 ++++++++++++++++++++++++++++ src/cli/gateway-cli.ts | 28 ++++++++++------------ 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/cli/gateway-cli.coverage.test.ts b/src/cli/gateway-cli.coverage.test.ts index 6e25780b7..6bec837da 100644 --- a/src/cli/gateway-cli.coverage.test.ts +++ b/src/cli/gateway-cli.coverage.test.ts @@ -168,6 +168,42 @@ describe("gateway-cli coverage", () => { expect(runtimeLogs.join("\n")).toContain("ws://"); }); + it("registers gateway discover and prints human output with details on new lines", async () => { + runtimeLogs.length = 0; + runtimeErrors.length = 0; + discoverGatewayBeacons.mockReset(); + discoverGatewayBeacons.mockResolvedValueOnce([ + { + instanceName: "Studio (Clawdbot)", + displayName: "Studio", + domain: "clawdbot.internal.", + host: "studio.clawdbot.internal", + lanHost: "studio.local", + tailnetDns: "studio.tailnet.ts.net", + gatewayPort: 18789, + bridgePort: 18790, + sshPort: 22, + }, + ]); + + const { registerGatewayCli } = await import("./gateway-cli.js"); + const program = new Command(); + program.exitOverride(); + registerGatewayCli(program); + + await program.parseAsync(["gateway", "discover", "--timeout", "1"], { + from: "user", + }); + + const out = runtimeLogs.join("\n"); + expect(out).toContain("Gateway Discovery"); + expect(out).toContain("Found 1 gateway(s)"); + expect(out).toContain("- Studio clawdbot.internal."); + expect(out).toContain(" tailnet: studio.tailnet.ts.net"); + expect(out).toContain(" host: studio.clawdbot.internal"); + expect(out).toContain(" ws: ws://studio.tailnet.ts.net:18789"); + }); + it("validates gateway discover timeout", async () => { runtimeLogs.length = 0; runtimeErrors.length = 0; diff --git a/src/cli/gateway-cli.ts b/src/cli/gateway-cli.ts index 8bde6b319..3888b5ff1 100644 --- a/src/cli/gateway-cli.ts +++ b/src/cli/gateway-cli.ts @@ -274,26 +274,24 @@ function renderBeaconLines( const title = colorize(rich, theme.accentBright, nameRaw); const domain = colorize(rich, theme.muted, domainRaw); - const parts: string[] = []; - if (beacon.tailnetDns) - parts.push( - `${colorize(rich, theme.info, "tailnet")}: ${beacon.tailnetDns}`, - ); - if (beacon.lanHost) - parts.push(`${colorize(rich, theme.info, "lan")}: ${beacon.lanHost}`); - if (beacon.host) - parts.push(`${colorize(rich, theme.info, "host")}: ${beacon.host}`); - const host = pickBeaconHost(beacon); const gatewayPort = pickGatewayPort(beacon); const wsUrl = host ? `ws://${host}:${gatewayPort}` : null; - const firstLine = - parts.length > 0 - ? `${title} ${domain} · ${parts.join(" · ")}` - : `${title} ${domain}`; + const lines = [`- ${title} ${domain}`]; + + if (beacon.tailnetDns) { + lines.push( + ` ${colorize(rich, theme.info, "tailnet")}: ${beacon.tailnetDns}`, + ); + } + if (beacon.lanHost) { + lines.push(` ${colorize(rich, theme.info, "lan")}: ${beacon.lanHost}`); + } + if (beacon.host) { + lines.push(` ${colorize(rich, theme.info, "host")}: ${beacon.host}`); + } - const lines = [`- ${firstLine}`]; if (wsUrl) { lines.push( ` ${colorize(rich, theme.muted, "ws")}: ${colorize(rich, theme.command, wsUrl)}`,