From 4b26b43855ce00d197345c802144c67eeddc35a6 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Tue, 24 Jun 2025 20:52:09 -0400 Subject: [PATCH] added opencode serve command --- packages/opencode/src/cli/cmd/serve.ts | 50 ++++++++++++++++++++++++++ packages/opencode/src/index.ts | 11 ++++-- packages/opencode/src/server/server.ts | 6 ++-- 3 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 packages/opencode/src/cli/cmd/serve.ts diff --git a/packages/opencode/src/cli/cmd/serve.ts b/packages/opencode/src/cli/cmd/serve.ts new file mode 100644 index 00000000..ef09e794 --- /dev/null +++ b/packages/opencode/src/cli/cmd/serve.ts @@ -0,0 +1,50 @@ +import { App } from "../../app/app" +import { Provider } from "../../provider/provider" +import { Server } from "../../server/server" +import { Share } from "../../share/share" +import { cmd } from "./cmd" + +export const ServeCommand = cmd({ + command: "serve", + builder: (yargs) => + yargs + .option("port", { + alias: ["p"], + type: "number", + describe: "port to listen on", + default: 4096, + }) + .option("hostname", { + alias: ["h"], + type: "string", + describe: "hostname to listen on", + default: "127.0.0.1", + }), + describe: "starts a headless opencode server", + handler: async (args) => { + const cwd = process.cwd() + await App.provide({ cwd }, async () => { + const providers = await Provider.list() + if (Object.keys(providers).length === 0) { + return "needs_provider" + } + + const hostname = args.hostname + const port = args.port + + await Share.init() + const server = Server.listen({ + port, + hostname, + }) + + console.log( + `opencode server listening on http://${server.hostname}:${server.port}`, + ) + + await new Promise(() => {}) + + server.stop() + }) + }, +}) diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 73dd1d20..a19eeac5 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -21,13 +21,13 @@ import { Bus } from "./bus" import { Config } from "./config/config" import { NamedError } from "./util/error" import { FormatError } from "./cli/error" +import { ServeCommand } from "./cli/cmd/serve" const cancel = new AbortController() const cli = yargs(hideBin(process.argv)) .scriptName("opencode") .help("help", "show help") - .alias("help", "h") .version("version", "show version number", Installation.VERSION) .alias("version", "v") .option("print-logs", { @@ -61,10 +61,14 @@ const cli = yargs(hideBin(process.argv)) } await Share.init() - const server = Server.listen() + const server = Server.listen({ + port: 0, + }) let cmd = ["go", "run", "./main.go"] - let cwd = url.fileURLToPath(new URL("../../tui/cmd/opencode", import.meta.url)) + let cwd = url.fileURLToPath( + new URL("../../tui/cmd/opencode", import.meta.url), + ) if (Bun.embeddedFiles.length > 0) { const blob = Bun.embeddedFiles[0] as File let binaryName = blob.name @@ -134,6 +138,7 @@ const cli = yargs(hideBin(process.argv)) .command(ScrapCommand) .command(AuthCommand) .command(UpgradeCommand) + .command(ServeCommand) .fail((msg) => { if ( msg.startsWith("Unknown argument") || diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 34e95d06..c1aaadeb 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -579,10 +579,10 @@ export namespace Server { return result } - export function listen() { + export function listen(opts: { port: number; hostname: string }) { const server = Bun.serve({ - port: 0, - hostname: "0.0.0.0", + port: opts.port, + hostname: opts.hostname, idleTimeout: 0, fetch: app().fetch, })