diff --git a/packages/opencode/src/cli/cmd/tui/thread.ts b/packages/opencode/src/cli/cmd/tui/thread.ts index 04037a50f3..8449216f5d 100644 --- a/packages/opencode/src/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/cli/cmd/tui/thread.ts @@ -198,7 +198,7 @@ export const TuiThreadCommand = cmd({ } catch (error) { UI.error(errorMessage(error)) process.exitCode = 1 - return + return false } const config = await TuiConfig.get() @@ -221,6 +221,7 @@ export const TuiThreadCommand = cmd({ fork: args.fork, }, }).done + return true } finally { await input.stop?.() } @@ -233,12 +234,15 @@ export const TuiThreadCommand = cmd({ frame: args.debugFrame, directory: cwd, }) - await launch({ - url: "http://opencode.debug", - sessionID: transport.sessionID, - fetch: transport.fetch, - events: transport.events, - }) + if ( + !(await launch({ + url: "http://opencode.debug", + sessionID: transport.sessionID, + fetch: transport.fetch, + events: transport.events, + })) + ) + return process.exit(0) return } @@ -310,17 +314,20 @@ export const TuiThreadCommand = cmd({ client.call("checkUpgrade", { directory: cwd }).catch(() => {}) }, 1000).unref?.() - await launch({ - ...transport, - sessionID: args.session, - prompt, - stop, - onSnapshot: async () => { - const tui = writeHeapSnapshot("tui.heapsnapshot") - const server = await client.call("snapshot", undefined) - return [tui, server] - }, - }) + if ( + !(await launch({ + ...transport, + sessionID: args.session, + prompt, + stop, + onSnapshot: async () => { + const tui = writeHeapSnapshot("tui.heapsnapshot") + const server = await client.call("snapshot", undefined) + return [tui, server] + }, + })) + ) + return } finally { unguard?.() } diff --git a/packages/opencode/test/cli/tui/thread.test.ts b/packages/opencode/test/cli/tui/thread.test.ts index 53b7488c26..c5dfbb8414 100644 --- a/packages/opencode/test/cli/tui/thread.test.ts +++ b/packages/opencode/test/cli/tui/thread.test.ts @@ -1,7 +1,9 @@ import { describe, expect, test } from "bun:test" +import { Effect } from "effect" import fs from "fs/promises" import path from "path" import { tmpdir } from "../../fixture/fixture" +import { cliIt } from "../../lib/cli-process" import { resolveThreadDirectory } from "../../../src/cli/cmd/tui/thread" describe("tui thread", () => { @@ -25,4 +27,13 @@ describe("tui thread", () => { test("uses the real cwd after resolving a relative project from PWD", async () => { await check(".") }) + + cliIt.live("exits nonzero when a requested session ID is invalid", ({ opencode }) => + Effect.gen(function* () { + const result = yield* opencode.spawn(["--session", "invalid", "--pure"]) + + expect(result.exitCode).not.toBe(0) + expect(result.stderr).toContain("Invalid session ID") + }), + ) })