summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-08-21 17:12:31 -0400
committerDax Raad <[email protected]>2025-08-21 17:13:24 -0400
commitd9233872b97b23a52827569df693dd3ff702313c (patch)
tree5e53d4a9351f1fd0f300904a0beca59ff0675068
parentaa4dba1541c4f220417bd715e1b944b005d80d46 (diff)
downloadopencode-d9233872b97b23a52827569df693dd3ff702313c.tar.gz
opencode-d9233872b97b23a52827569df693dd3ff702313c.zip
add `createOpencodeServer` to js sdk and wait for readiness. always use random port for `opencode serve`. add `/client` and `/server` imports for js sdk
-rw-r--r--packages/opencode/src/cli/cmd/serve.ts2
-rw-r--r--packages/sdk/js/src/server.ts55
-rw-r--r--tsconfig.json6
3 files changed, 57 insertions, 6 deletions
diff --git a/packages/opencode/src/cli/cmd/serve.ts b/packages/opencode/src/cli/cmd/serve.ts
index 0e13ddbd3..1d6a73277 100644
--- a/packages/opencode/src/cli/cmd/serve.ts
+++ b/packages/opencode/src/cli/cmd/serve.ts
@@ -11,7 +11,7 @@ export const ServeCommand = cmd({
alias: ["p"],
type: "number",
describe: "port to listen on",
- default: 4096,
+ default: 0,
})
.option("hostname", {
alias: ["h"],
diff --git a/packages/sdk/js/src/server.ts b/packages/sdk/js/src/server.ts
index edaa4cf63..08bf12908 100644
--- a/packages/sdk/js/src/server.ts
+++ b/packages/sdk/js/src/server.ts
@@ -1,21 +1,68 @@
import { spawn } from "node:child_process"
export type ServerConfig = {
- host?: string
+ hostname?: string
port?: number
+ signal?: AbortSignal
+ timeout?: number
}
export async function createOpencodeServer(config?: ServerConfig) {
config = Object.assign(
{
- host: "127.0.0.1",
+ hostname: "127.0.0.1",
port: 4096,
+ timeout: 5000,
},
config ?? {},
)
- const proc = spawn(`opencode`, [`serve`, `--host=${config.host}`, `--port=${config.port}`])
- const url = `http://${config.host}:${config.port}`
+ const proc = spawn(`opencode`, [`servel`, `--hostname=${config.hostname}`, `--port=${config.port}`], {
+ signal: config.signal,
+ })
+
+ const url = await new Promise<string>((resolve, reject) => {
+ const id = setTimeout(() => {
+ reject(new Error(`Timeout waiting for server to start after ${config.timeout}ms`))
+ }, config.timeout)
+ let output = ""
+ proc.stdout?.on("data", (chunk) => {
+ output += chunk.toString()
+ const lines = output.split("\n")
+ for (const line of lines) {
+ if (line.startsWith("opencode server listening")) {
+ const match = line.match(/on\s+(https?:\/\/[^\s]+)/)
+ if (!match) {
+ throw new Error(`Failed to parse server url from output: ${line}`)
+ }
+ clearTimeout(id)
+ resolve(match[1])
+ return
+ }
+ }
+ })
+ proc.stderr?.on("data", (chunk) => {
+ output += chunk.toString()
+ })
+ proc.on("exit", (code) => {
+ clearTimeout(id)
+ let msg = `Server exited with code ${code}`
+ if (output.trim()) {
+ msg += `\nServer output: ${output}`
+ }
+ reject(new Error(msg))
+ })
+ proc.on("error", (error) => {
+ clearTimeout(id)
+ reject(error)
+ })
+ if (config.signal) {
+ config.signal.addEventListener("abort", () => {
+ clearTimeout(id)
+ reject(new Error("Aborted"))
+ })
+ }
+ })
return {
url,
diff --git a/tsconfig.json b/tsconfig.json
index 65fa6c7f3..75ddeff3e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,5 +1,9 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/bun/tsconfig.json",
- "compilerOptions": {}
+ "compilerOptions": {
+ "customConditions": [
+ "development"
+ ],
+ }
}