web.ts 2.5 KB

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