Skip to content

Commit 0e22efe

Browse files
committed
feat(tui): add --no-server flag for headless instance bootstrap
Adds a --no-server flag to opencode tui that runs only the HTTP server without launching the TUI, useful for headless environments and remote attach workflows.
1 parent 2d7b954 commit 0e22efe

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

packages/opencode/src/cli/cmd/tui/thread.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import {
2323
} from "@opencode-ai/core/util/opencode-process"
2424
import { validateSession } from "./validate-session"
2525
import { Provider } from "@/provider/provider"
26+
import { bootstrap } from "@/cli/bootstrap"
27+
import { Server } from "@/server/server"
2628

2729
declare global {
2830
const OPENCODE_WORKER_PATH: string
@@ -117,6 +119,11 @@ export const TuiThreadCommand = cmd({
117119
.option("variant", {
118120
type: "string",
119121
describe: "model variant (provider-specific reasoning effort, e.g., high, max, minimal)",
122+
})
123+
.option("no-server", {
124+
type: "boolean",
125+
default: false,
126+
describe: "run headless server without TUI (full instance bootstrap)",
120127
}),
121128
handler: async (args) => {
122129
// Keep ENABLE_PROCESSED_INPUT cleared even if other code flips it.
@@ -136,17 +143,31 @@ export const TuiThreadCommand = cmd({
136143
// Resolve relative --project paths from PWD, then use the real cwd after
137144
// chdir so the thread and worker share the same directory key.
138145
const next = resolveThreadDirectory(args.project)
139-
const file = await target()
140146
try {
141147
process.chdir(next)
142148
} catch {
143149
UI.error("Failed to change directory to " + next)
144150
return
145151
}
146152
const cwd = Filesystem.resolve(process.cwd())
153+
154+
if (args.noServer) {
155+
const network = resolveNetworkOptionsNoConfig(args)
156+
await bootstrap(cwd, async () => {
157+
const server = await Server.listen(network)
158+
Log.Default.info("opencode server (headless) listening", {
159+
url: server.url.toString(),
160+
})
161+
await new Promise(() => {})
162+
await server.stop()
163+
})
164+
return
165+
}
166+
147167
const pick = await Provider.resolveSelection(args.model, args.variant)
148168
const model = pick.model
149169
const variant = pick.variant
170+
const file = await target()
150171
const env = sanitizedProcessEnv({
151172
[OPENCODE_PROCESS_ROLE]: "worker",
152173
[OPENCODE_RUN_ID]: ensureRunID(),

packages/opencode/test/cli/tui/thread.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ describe("tui thread", () => {
9797
"mdns-domain": "opencode.local",
9898
mdnsDomain: "opencode.local",
9999
cors: [],
100+
"no-server": false,
101+
noServer: false,
100102
}
101103
return TuiThreadCommand.handler(args)
102104
}

0 commit comments

Comments
 (0)