import { app } from "electron" import { DEFAULT_SERVER_URL_KEY, WSL_ENABLED_KEY } from "./constants" import { getUserShell, loadShellEnv } from "./shell-env" import { store } from "./store" export type WslConfig = { enabled: boolean } export type HealthCheck = { wait: Promise } export function getDefaultServerUrl(): string | null { const value = store.get(DEFAULT_SERVER_URL_KEY) return typeof value === "string" ? value : null } export function setDefaultServerUrl(url: string | null) { if (url) { store.set(DEFAULT_SERVER_URL_KEY, url) return } store.delete(DEFAULT_SERVER_URL_KEY) } export function getWslConfig(): WslConfig { const value = store.get(WSL_ENABLED_KEY) return { enabled: typeof value === "boolean" ? value : false } } export function setWslConfig(config: WslConfig) { store.set(WSL_ENABLED_KEY, config.enabled) } export async function spawnLocalServer(hostname: string, port: number, password: string) { prepareServerEnv(password) const { Log, Server } = await import("virtual:opencode-server") await Log.init({ level: "WARN" }) const listener = await Server.listen({ port, hostname, username: "opencode", password, }) const wait = (async () => { const url = `http://${hostname}:${port}` const ready = async () => { while (true) { await new Promise((resolve) => setTimeout(resolve, 100)) if (await checkHealth(url, password)) return } } await ready() })() return { listener, health: { wait } } } function prepareServerEnv(password: string) { const shell = process.platform === "win32" ? null : getUserShell() const shellEnv = shell ? (loadShellEnv(shell) ?? {}) : {} const env = { ...process.env, ...shellEnv, OPENCODE_EXPERIMENTAL_ICON_DISCOVERY: "true", OPENCODE_EXPERIMENTAL_FILEWATCHER: "true", OPENCODE_CLIENT: "desktop", OPENCODE_SERVER_USERNAME: "opencode", OPENCODE_SERVER_PASSWORD: password, XDG_STATE_HOME: app.getPath("userData"), } Object.assign(process.env, env) } export async function checkHealth(url: string, password?: string | null): Promise { let healthUrl: URL try { healthUrl = new URL("/global/health", url) } catch { return false } const headers = new Headers() if (password) { const auth = Buffer.from(`opencode:${password}`).toString("base64") headers.set("authorization", `Basic ${auth}`) } try { const res = await fetch(healthUrl, { method: "GET", headers, signal: AbortSignal.timeout(3000), }) return res.ok } catch { return false } }