2025-12-26 20:24:44 +00:00
|
|
|
import type { Argv, InferredOptionTypes } from "yargs"
|
2026-06-03 02:42:13 +00:00
|
|
|
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
|
2026-06-02 19:20:25 +00:00
|
|
|
import type { Config } from "@/config/config"
|
2026-05-06 15:02:08 +00:00
|
|
|
import { Effect } from "effect"
|
2025-12-26 20:24:44 +00:00
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
|
port: {
|
|
|
|
|
type: "number" as const,
|
|
|
|
|
describe: "port to listen on",
|
|
|
|
|
default: 0,
|
|
|
|
|
},
|
|
|
|
|
hostname: {
|
|
|
|
|
type: "string" as const,
|
|
|
|
|
describe: "hostname to listen on",
|
|
|
|
|
default: "127.0.0.1",
|
|
|
|
|
},
|
|
|
|
|
mdns: {
|
|
|
|
|
type: "boolean" as const,
|
|
|
|
|
describe: "enable mDNS service discovery (defaults hostname to 0.0.0.0)",
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
2026-02-02 20:52:32 +00:00
|
|
|
"mdns-domain": {
|
|
|
|
|
type: "string" as const,
|
|
|
|
|
describe: "custom domain name for mDNS service (default: opencode.local)",
|
|
|
|
|
default: "opencode.local",
|
|
|
|
|
},
|
2025-12-31 09:50:29 +00:00
|
|
|
cors: {
|
|
|
|
|
type: "string" as const,
|
|
|
|
|
array: true,
|
|
|
|
|
describe: "additional domains to allow for CORS",
|
|
|
|
|
default: [] as string[],
|
|
|
|
|
},
|
2025-12-26 20:24:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type NetworkOptions = InferredOptionTypes<typeof options>
|
|
|
|
|
|
|
|
|
|
export function withNetworkOptions<T>(yargs: Argv<T>) {
|
|
|
|
|
return yargs.options(options)
|
|
|
|
|
}
|
2026-07-01 21:12:00 +00:00
|
|
|
|
|
|
|
|
export function hasArg(name: string) {
|
|
|
|
|
return networkArgs().some((arg) => arg === name || arg.startsWith(name + "="))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hasBooleanArg(name: string) {
|
|
|
|
|
return networkArgs().some(
|
|
|
|
|
(arg) => arg === name || arg === name + "=true" || arg === name + "=false" || arg === "--no-" + name.slice(2),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function networkArgs() {
|
|
|
|
|
const separator = process.argv.indexOf("--")
|
|
|
|
|
return process.argv.slice(2, separator === -1 ? undefined : separator)
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 15:02:08 +00:00
|
|
|
export const resolveNetworkOptions = Effect.fn("Cli.resolveNetworkOptions")(function* (args: NetworkOptions) {
|
2026-06-02 19:20:25 +00:00
|
|
|
const { Config } = yield* Effect.promise(() => import("@/config/config"))
|
2026-05-06 15:02:08 +00:00
|
|
|
const config = yield* Config.Service.use((cfg) => cfg.getGlobal())
|
2026-04-16 06:03:03 +00:00
|
|
|
return resolveNetworkOptionsNoConfig(args, config)
|
2026-05-06 15:02:08 +00:00
|
|
|
})
|
2026-04-16 06:03:03 +00:00
|
|
|
|
2026-06-03 02:42:13 +00:00
|
|
|
export function resolveNetworkOptionsNoConfig(args: NetworkOptions, config?: ConfigV1.Info) {
|
2026-07-01 21:12:00 +00:00
|
|
|
const portExplicitlySet = hasArg("--port")
|
|
|
|
|
const hostnameExplicitlySet = hasArg("--hostname")
|
|
|
|
|
const mdnsExplicitlySet = hasBooleanArg("--mdns")
|
|
|
|
|
const mdnsDomainExplicitlySet = hasArg("--mdns-domain")
|
2025-12-26 20:24:44 +00:00
|
|
|
const mdns = mdnsExplicitlySet ? args.mdns : (config?.server?.mdns ?? args.mdns)
|
2026-02-02 20:52:32 +00:00
|
|
|
const mdnsDomain = mdnsDomainExplicitlySet ? args["mdns-domain"] : (config?.server?.mdnsDomain ?? args["mdns-domain"])
|
2025-12-26 20:24:44 +00:00
|
|
|
const port = portExplicitlySet ? args.port : (config?.server?.port ?? args.port)
|
|
|
|
|
const hostname = hostnameExplicitlySet
|
|
|
|
|
? args.hostname
|
|
|
|
|
: mdns && !config?.server?.hostname
|
|
|
|
|
? "0.0.0.0"
|
|
|
|
|
: (config?.server?.hostname ?? args.hostname)
|
2025-12-31 09:50:29 +00:00
|
|
|
const configCors = config?.server?.cors ?? []
|
|
|
|
|
const argsCors = Array.isArray(args.cors) ? args.cors : args.cors ? [args.cors] : []
|
|
|
|
|
const cors = [...configCors, ...argsCors]
|
2025-12-26 20:24:44 +00:00
|
|
|
|
2026-02-02 20:52:32 +00:00
|
|
|
return { hostname, port, mdns, mdnsDomain, cors }
|
2025-12-26 20:24:44 +00:00
|
|
|
}
|