opencode_offline/packages/opencode/src/cli/cmd/web.ts

76 lines
2.2 KiB
TypeScript
Raw Normal View History

import { Config } from "../../config/config"
2025-11-04 05:10:13 +08:00
import { Server } from "../../server/server"
import { UI } from "../ui"
import { cmd } from "./cmd"
import { withNetworkOptions, resolveNetworkOptions } from "../network"
2025-11-04 05:10:13 +08:00
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
}
2025-11-04 05:10:13 +08:00
export const WebCommand = cmd({
command: "web",
builder: (yargs) => withNetworkOptions(yargs),
2025-11-04 05:10:13 +08:00
describe: "starts a headless opencode server",
handler: async (args) => {
const config = await Config.get()
const opts = resolveNetworkOptions(args, config)
const server = Server.listen(opts)
2025-11-04 05:10:13 +08:00
UI.empty()
UI.println(UI.logo(" "))
UI.empty()
if (opts.hostname === "0.0.0.0") {
// Show localhost for local access
const localhostUrl = `http://localhost:${server.port}`
2025-11-08 09:59:02 +08:00
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}`,
)
}
}
if (opts.mdns) {
UI.println(UI.Style.TEXT_INFO_BOLD + " mDNS: ", UI.Style.TEXT_NORMAL, "opencode.local")
}
// 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(() => {})
}
2025-11-04 05:10:13 +08:00
await new Promise(() => {})
await server.stop()
},
})