diff --git a/packages/opencode/src/kilocode/cli/cmd/run.ts b/packages/opencode/src/kilocode/cli/cmd/run.ts index 9ec78edc07..cc5b12ed3c 100644 --- a/packages/opencode/src/kilocode/cli/cmd/run.ts +++ b/packages/opencode/src/kilocode/cli/cmd/run.ts @@ -9,7 +9,7 @@ export namespace KiloRunDaemon { } export async function attach(input: Input) { - const daemon = await DaemonClient.maybe(DaemonClient.options()) + const daemon = await DaemonClient.maybe() if (!daemon) return false const dir = input.directory ?? Filesystem.resolve(process.cwd()) const client = createKiloClient({ baseUrl: daemon.url, directory: dir, headers: daemon.headers }) diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/thread.ts b/packages/opencode/src/kilocode/cli/cmd/tui/thread.ts index 477af503f4..053ed5f742 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/kilocode/cli/cmd/tui/thread.ts @@ -1,5 +1,5 @@ import { UI } from "@/cli/ui" -import { resolveNetworkOptionsNoConfig, type NetworkOptions } from "@/cli/network" +import type { NetworkOptions } from "@/cli/network" import { errorMessage } from "@/util/error" import { TuiConfig } from "@/cli/cmd/tui/config/tui" import { validateSession } from "@/cli/cmd/tui/validate-session" @@ -45,8 +45,7 @@ async function session(input: Input, daemon: DaemonClient.Connection) { export namespace KiloTuiThreadDaemon { export async function attach(input: Input) { - const net = resolveNetworkOptionsNoConfig(input.args) - const daemon = await DaemonClient.maybe(DaemonClient.options(net)) + const daemon = await DaemonClient.maybe() if (!daemon) return false const prompt = await input.input() diff --git a/packages/opencode/src/kilocode/daemon/client.ts b/packages/opencode/src/kilocode/daemon/client.ts index 305608edb0..5297201c28 100644 --- a/packages/opencode/src/kilocode/daemon/client.ts +++ b/packages/opencode/src/kilocode/daemon/client.ts @@ -14,25 +14,14 @@ export namespace DaemonClient { return !process.env.KILO_NO_DAEMON } - export function options(input: Partial = {}): Daemon.Options { - return { - hostname: "127.0.0.1", - port: 0, - mdns: false, - mdnsDomain: "kilo.local", - cors: ["http://127.0.0.1:3017", "http://localhost:3017"], - ...input, - } - } - export function headers(state: Daemon.State) { return { Authorization: `Basic ${state.token}` } } - export async function connect(input: Daemon.Options): Promise { + export async function connect(): Promise { if (!enabled()) return undefined - const daemon = await Daemon.start(input) - if (!daemon.running || !daemon.state) throw new Error(daemon.reason ?? "Daemon did not start") + const daemon = await Daemon.status() + if (!daemon.running || !daemon.state) return undefined return { url: daemon.state.url, headers: headers(daemon.state), @@ -40,8 +29,8 @@ export namespace DaemonClient { } } - export async function maybe(input: Daemon.Options): Promise { - return await connect(input).catch((err) => { + export async function maybe(): Promise { + return await connect().catch((err) => { log.warn("daemon unavailable, falling back to embedded server", { err }) return undefined }) diff --git a/packages/opencode/test/kilocode/daemon.test.ts b/packages/opencode/test/kilocode/daemon.test.ts index 1a9760b8b5..d1fb61efd0 100644 --- a/packages/opencode/test/kilocode/daemon.test.ts +++ b/packages/opencode/test/kilocode/daemon.test.ts @@ -123,22 +123,34 @@ describe("daemon manager", () => { expect(restarted.status).toBe(200) }, 20_000) - test("daemon client honors the escape hatch", async () => { + test("daemon client does not start a daemon while attaching", async () => { await using tmp = await tmpdir() - process.env.KILO_NO_DAEMON = "1" + dirs(tmp.path) - const daemon = await DaemonClient.connect(opts(tmp.path)) + const daemon = await DaemonClient.connect() expect(daemon).toBeUndefined() expect((await Daemon.status()).running).toBe(false) }) + test("daemon client honors the escape hatch", async () => { + await using tmp = await tmpdir() + const started = await Daemon.start(opts(tmp.path)) + process.env.KILO_NO_DAEMON = "1" + + const daemon = await DaemonClient.connect() + + expect(daemon).toBeUndefined() + expect((await Daemon.status()).state?.pid).toBe(started.state?.pid) + }, 20_000) + test("daemon client returns authenticated attach settings", async () => { await using tmp = await tmpdir() + const started = await Daemon.start(opts(tmp.path)) - const daemon = await DaemonClient.connect(opts(tmp.path)) + const daemon = await DaemonClient.connect() - expect(daemon?.url).toStartWith("http://127.0.0.1:") + expect(daemon?.url).toBe(started.state?.url) expect(daemon?.headers.Authorization).toBe(`Basic ${daemon?.state.token}`) }, 20_000) })