From bdb43b1b8192c94574d8b5e3a7306b866bf94f26 Mon Sep 17 00:00:00 2001 From: James Long Date: Fri, 27 Feb 2026 17:05:18 -0500 Subject: [PATCH] feat(core): add WorkspaceContext --- .../src/control-plane/workspace-context.ts | 23 ++++++++++++++++ packages/opencode/src/server/server.ts | 26 +++++++++++++++---- 2 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 packages/opencode/src/control-plane/workspace-context.ts diff --git a/packages/opencode/src/control-plane/workspace-context.ts b/packages/opencode/src/control-plane/workspace-context.ts new file mode 100644 index 00000000000..f7297b3f4b4 --- /dev/null +++ b/packages/opencode/src/control-plane/workspace-context.ts @@ -0,0 +1,23 @@ +import { Context } from "../util/context" + +interface Context { + workspaceID?: string +} + +const context = Context.create("workspace") + +export const WorkspaceContext = { + async provide(input: { workspaceID?: string; fn: () => R }): Promise { + return context.provide({ workspaceID: input.workspaceID }, async () => { + return input.fn() + }) + }, + + get workspaceID() { + try { + return context.use().workspaceID + } catch (e) { + return undefined + } + }, +} diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 9fba9c1fe1a..85049650c1f 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -21,6 +21,7 @@ import { Auth } from "../auth" import { Flag } from "../flag/flag" import { Command } from "../command" import { Global } from "../global" +import { WorkspaceContext } from "../control-plane/workspace-context" import { ProjectRoutes } from "./routes/project" import { SessionRoutes } from "./routes/session" import { PtyRoutes } from "./routes/pty" @@ -194,6 +195,7 @@ export namespace Server { ) .use(async (c, next) => { if (c.req.path === "/log") return next() + const workspaceID = c.req.query("workspace") || c.req.header("x-opencode-workspace") const raw = c.req.query("directory") || c.req.header("x-opencode-directory") || process.cwd() const directory = (() => { try { @@ -202,11 +204,17 @@ export namespace Server { return raw } })() - return Instance.provide({ - directory, - init: InstanceBootstrap, + + return WorkspaceContext.provide({ + workspaceID, async fn() { - return next() + return Instance.provide({ + directory, + init: InstanceBootstrap, + async fn() { + return next() + }, + }) }, }) }) @@ -223,7 +231,15 @@ export namespace Server { }, }), ) - .use(validator("query", z.object({ directory: z.string().optional() }))) + .use( + validator( + "query", + z.object({ + directory: z.string().optional(), + workspace: z.string().optional(), + }), + ), + ) .route("/project", ProjectRoutes()) .route("/pty", PtyRoutes()) .route("/config", ConfigRoutes())