feat(core): add workspace-serve command (experimental) (#14960)
This commit is contained in:
59
packages/opencode/src/cli/cmd/workspace-serve.ts
Normal file
59
packages/opencode/src/cli/cmd/workspace-serve.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { cmd } from "./cmd"
|
||||||
|
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||||
|
import { Installation } from "../../installation"
|
||||||
|
|
||||||
|
export const WorkspaceServeCommand = cmd({
|
||||||
|
command: "workspace-serve",
|
||||||
|
builder: (yargs) => withNetworkOptions(yargs),
|
||||||
|
describe: "starts a remote workspace websocket server",
|
||||||
|
handler: async (args) => {
|
||||||
|
const opts = await resolveNetworkOptions(args)
|
||||||
|
const server = Bun.serve<{ id: string }>({
|
||||||
|
hostname: opts.hostname,
|
||||||
|
port: opts.port,
|
||||||
|
fetch(req, server) {
|
||||||
|
const url = new URL(req.url)
|
||||||
|
if (url.pathname === "/ws") {
|
||||||
|
const id = Bun.randomUUIDv7()
|
||||||
|
if (server.upgrade(req, { data: { id } })) return
|
||||||
|
return new Response("Upgrade failed", { status: 400 })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.pathname === "/health") {
|
||||||
|
return new Response("ok", {
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
"content-type": "text/plain; charset=utf-8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
service: "workspace-server",
|
||||||
|
ws: `ws://${server.hostname}:${server.port}/ws`,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json; charset=utf-8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
websocket: {
|
||||||
|
open(ws) {
|
||||||
|
ws.send(JSON.stringify({ type: "ready", id: ws.data.id }))
|
||||||
|
},
|
||||||
|
message(ws, msg) {
|
||||||
|
const text = typeof msg === "string" ? msg : msg.toString()
|
||||||
|
ws.send(JSON.stringify({ type: "message", id: ws.data.id, text }))
|
||||||
|
},
|
||||||
|
close() {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(`workspace websocket server listening on ws://${server.hostname}:${server.port}/ws`)
|
||||||
|
await new Promise(() => {})
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -13,6 +13,7 @@ import { Installation } from "./installation"
|
|||||||
import { NamedError } from "@opencode-ai/util/error"
|
import { NamedError } from "@opencode-ai/util/error"
|
||||||
import { FormatError } from "./cli/error"
|
import { FormatError } from "./cli/error"
|
||||||
import { ServeCommand } from "./cli/cmd/serve"
|
import { ServeCommand } from "./cli/cmd/serve"
|
||||||
|
import { WorkspaceServeCommand } from "./cli/cmd/workspace-serve"
|
||||||
import { Filesystem } from "./util/filesystem"
|
import { Filesystem } from "./util/filesystem"
|
||||||
import { DebugCommand } from "./cli/cmd/debug"
|
import { DebugCommand } from "./cli/cmd/debug"
|
||||||
import { StatsCommand } from "./cli/cmd/stats"
|
import { StatsCommand } from "./cli/cmd/stats"
|
||||||
@@ -45,7 +46,7 @@ process.on("uncaughtException", (e) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const cli = yargs(hideBin(process.argv))
|
let cli = yargs(hideBin(process.argv))
|
||||||
.parserConfiguration({ "populate--": true })
|
.parserConfiguration({ "populate--": true })
|
||||||
.scriptName("opencode")
|
.scriptName("opencode")
|
||||||
.wrap(100)
|
.wrap(100)
|
||||||
@@ -141,6 +142,12 @@ const cli = yargs(hideBin(process.argv))
|
|||||||
.command(PrCommand)
|
.command(PrCommand)
|
||||||
.command(SessionCommand)
|
.command(SessionCommand)
|
||||||
.command(DbCommand)
|
.command(DbCommand)
|
||||||
|
|
||||||
|
if (Installation.isLocal()) {
|
||||||
|
cli = cli.command(WorkspaceServeCommand)
|
||||||
|
}
|
||||||
|
|
||||||
|
cli = cli
|
||||||
.fail((msg, err) => {
|
.fail((msg, err) => {
|
||||||
if (
|
if (
|
||||||
msg?.startsWith("Unknown argument") ||
|
msg?.startsWith("Unknown argument") ||
|
||||||
|
|||||||
Reference in New Issue
Block a user