web.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { Server } from "../../server/server"
  2. import { UI } from "../ui"
  3. import { cmd } from "./cmd"
  4. import open from "open"
  5. import { networkInterfaces } from "os"
  6. function getNetworkIPs() {
  7. const nets = networkInterfaces()
  8. const results: string[] = []
  9. for (const name of Object.keys(nets)) {
  10. const net = nets[name]
  11. if (!net) continue
  12. for (const netInfo of net) {
  13. // Skip internal and non-IPv4 addresses
  14. if (netInfo.internal || netInfo.family !== "IPv4") continue
  15. // Skip Docker bridge networks (typically 172.x.x.x)
  16. if (netInfo.address.startsWith("172.")) continue
  17. results.push(netInfo.address)
  18. }
  19. }
  20. return results
  21. }
  22. export const WebCommand = cmd({
  23. command: "web",
  24. builder: (yargs) =>
  25. yargs
  26. .option("port", {
  27. alias: ["p"],
  28. type: "number",
  29. describe: "port to listen on",
  30. default: 0,
  31. })
  32. .option("hostname", {
  33. type: "string",
  34. describe: "hostname to listen on",
  35. default: "127.0.0.1",
  36. }),
  37. describe: "starts a headless opencode server",
  38. handler: async (args) => {
  39. const hostname = args.hostname
  40. const port = args.port
  41. const server = Server.listen({
  42. port,
  43. hostname,
  44. })
  45. UI.empty()
  46. UI.println(UI.logo(" "))
  47. UI.empty()
  48. if (hostname === "0.0.0.0") {
  49. // Show localhost for local access
  50. const localhostUrl = `http://localhost:${server.port}/web`
  51. UI.println(UI.Style.TEXT_INFO_BOLD + " Local access: ", UI.Style.TEXT_NORMAL, localhostUrl)
  52. // Show network IPs for remote access
  53. const networkIPs = getNetworkIPs()
  54. if (networkIPs.length > 0) {
  55. for (const ip of networkIPs) {
  56. UI.println(
  57. UI.Style.TEXT_INFO_BOLD + " Network access: ",
  58. UI.Style.TEXT_NORMAL,
  59. `http://${ip}:${server.port}`,
  60. )
  61. }
  62. }
  63. // Open localhost in browser
  64. open(localhostUrl.toString()).catch(() => {})
  65. } else {
  66. const displayUrl = server.url.toString() + "web"
  67. UI.println(UI.Style.TEXT_INFO_BOLD + " Web interface: ", UI.Style.TEXT_NORMAL, displayUrl)
  68. open(displayUrl).catch(() => {})
  69. }
  70. await new Promise(() => {})
  71. await server.stop()
  72. },
  73. })