diff --git a/packages/opencode/src/cli/cmd/web.ts b/packages/opencode/src/cli/cmd/web.ts index 8fc8a991..9d3a4253 100644 --- a/packages/opencode/src/cli/cmd/web.ts +++ b/packages/opencode/src/cli/cmd/web.ts @@ -2,6 +2,29 @@ import { Server } from "../../server/server" import { UI } from "../ui" import { cmd } from "./cmd" import open from "open" +import { networkInterfaces } from "os" + +function getNetworkIPs() { + const nets = networkInterfaces() + const results: string[] = [] + + for (const name of Object.keys(nets)) { + const net = nets[name] + if (!net) continue + + for (const netInfo of net) { + // Skip internal and non-IPv4 addresses + if (netInfo.internal || netInfo.family !== "IPv4") continue + + // Skip Docker bridge networks (typically 172.x.x.x) + if (netInfo.address.startsWith("172.")) continue + + results.push(netInfo.address) + } + } + + return results +} export const WebCommand = cmd({ command: "web", @@ -29,12 +52,36 @@ export const WebCommand = cmd({ UI.empty() UI.println(UI.logo(" ")) UI.empty() - UI.println( - UI.Style.TEXT_INFO_BOLD + " Web interface: ", - UI.Style.TEXT_NORMAL, - server.url.toString(), - ) - open(server.url.toString()).catch(() => {}) + + if (hostname === "0.0.0.0") { + // Show localhost for local access + const localhostUrl = `http://localhost:${server.port}` + UI.println( + UI.Style.TEXT_INFO_BOLD + " Local access: ", + UI.Style.TEXT_NORMAL, + localhostUrl, + ) + + // Show network IPs for remote access + const networkIPs = getNetworkIPs() + if (networkIPs.length > 0) { + for (const ip of networkIPs) { + UI.println( + UI.Style.TEXT_INFO_BOLD + " Network access: ", + UI.Style.TEXT_NORMAL, + `http://${ip}:${server.port}`, + ) + } + } + + // Open localhost in browser + open(localhostUrl.toString()).catch(() => {}) + } else { + const displayUrl = server.url.toString() + UI.println(UI.Style.TEXT_INFO_BOLD + " Web interface: ", UI.Style.TEXT_NORMAL, displayUrl) + open(displayUrl).catch(() => {}) + } + await new Promise(() => {}) await server.stop() },