From dc6991e5a8efd963a43e8834a35706ec67f6a903 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Mon, 27 Apr 2026 12:52:48 -0400 Subject: [PATCH] fix(httpapi): mount workspace bridge routes (#24626) --- .../server/routes/instance/httpapi/config.ts | 5 ++--- .../server/routes/instance/httpapi/project.ts | 2 +- .../src/server/routes/instance/index.ts | 7 +++++++ .../test/server/httpapi-workspace.test.ts | 18 ++++++++---------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/opencode/src/server/routes/instance/httpapi/config.ts b/packages/opencode/src/server/routes/instance/httpapi/config.ts index 7e0664b3d6..d7808c78d3 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/config.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/config.ts @@ -67,10 +67,9 @@ export const configHandlers = Layer.unwrap( }) const update = Effect.fn("ConfigHttpApi.update")(function* (ctx) { - const payload = Config.Info.zod.parse(ctx.payload) - yield* configSvc.update(payload, { dispose: false }) + yield* configSvc.update(ctx.payload, { dispose: false }) yield* markInstanceForDisposal(yield* InstanceState.context) - return payload + return ctx.payload }) const providers = Effect.fn("ConfigHttpApi.providers")(function* () { diff --git a/packages/opencode/src/server/routes/instance/httpapi/project.ts b/packages/opencode/src/server/routes/instance/httpapi/project.ts index 63190180cc..73152de0e6 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/project.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/project.ts @@ -99,7 +99,7 @@ export const projectHandlers = Layer.unwrap( params: { projectID: ProjectID } payload: Project.UpdatePayload }) { - return yield* svc.update({ ...Project.UpdatePayload.zod.parse(ctx.payload), projectID: ctx.params.projectID }) + return yield* svc.update({ ...ctx.payload, projectID: ctx.params.projectID }) }) return HttpApiBuilder.group(ProjectApi, "project", (handlers) => diff --git a/packages/opencode/src/server/routes/instance/index.ts b/packages/opencode/src/server/routes/instance/index.ts index 90151c9a81..24328bde7c 100644 --- a/packages/opencode/src/server/routes/instance/index.ts +++ b/packages/opencode/src/server/routes/instance/index.ts @@ -25,6 +25,7 @@ import { McpPaths } from "./httpapi/mcp" import { SessionPaths } from "./httpapi/session" import { SyncPaths } from "./httpapi/sync" import { TuiPaths } from "./httpapi/tui" +import { WorkspacePaths } from "./httpapi/workspace" import { ProjectRoutes } from "./project" import { SessionRoutes } from "./session" import { PtyRoutes } from "./pty" @@ -144,6 +145,12 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono => { app.post(TuiPaths.selectSession, (c) => handler(c.req.raw, context)) app.get(TuiPaths.controlNext, (c) => handler(c.req.raw, context)) app.post(TuiPaths.controlResponse, (c) => handler(c.req.raw, context)) + app.get(WorkspacePaths.adaptors, (c) => handler(c.req.raw, context)) + app.post(WorkspacePaths.list, (c) => handler(c.req.raw, context)) + app.get(WorkspacePaths.list, (c) => handler(c.req.raw, context)) + app.get(WorkspacePaths.status, (c) => handler(c.req.raw, context)) + app.delete(WorkspacePaths.remove, (c) => handler(c.req.raw, context)) + app.post(WorkspacePaths.sessionRestore, (c) => handler(c.req.raw, context)) } return app diff --git a/packages/opencode/test/server/httpapi-workspace.test.ts b/packages/opencode/test/server/httpapi-workspace.test.ts index 8fee8a8034..75f3bd9ef6 100644 --- a/packages/opencode/test/server/httpapi-workspace.test.ts +++ b/packages/opencode/test/server/httpapi-workspace.test.ts @@ -1,13 +1,14 @@ import { afterEach, describe, expect, test } from "bun:test" import { mkdir } from "node:fs/promises" import path from "node:path" -import { Context, Effect } from "effect" +import { Effect } from "effect" +import type { UpgradeWebSocket } from "hono/ws" import { Flag } from "@opencode-ai/core/flag/flag" import { registerAdaptor } from "../../src/control-plane/adaptors" import type { WorkspaceAdaptor } from "../../src/control-plane/types" import { Workspace } from "../../src/control-plane/workspace" -import { ExperimentalHttpApiServer } from "../../src/server/routes/instance/httpapi/server" import { WorkspacePaths } from "../../src/server/routes/instance/httpapi/workspace" +import { InstanceRoutes } from "../../src/server/routes/instance" import { Session } from "../../src/session" import { Log } from "../../src/util" import { resetDatabase } from "../fixture/db" @@ -16,19 +17,15 @@ import { Instance } from "../../src/project/instance" void Log.init({ print: false }) -const context = Context.empty() as Context.Context const originalWorkspaces = Flag.OPENCODE_EXPERIMENTAL_WORKSPACES +const originalHttpApi = Flag.OPENCODE_EXPERIMENTAL_HTTPAPI +const websocket = (() => () => new Response(null, { status: 501 })) as unknown as UpgradeWebSocket function request(path: string, directory: string, init: RequestInit = {}) { + Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = true const headers = new Headers(init.headers) headers.set("x-opencode-directory", directory) - return ExperimentalHttpApiServer.webHandler().handler( - new Request(`http://localhost${path}`, { - ...init, - headers, - }), - context, - ) + return InstanceRoutes(websocket).request(path, { ...init, headers }) } function runSession(fx: Effect.Effect) { @@ -61,6 +58,7 @@ function localAdaptor(directory: string): WorkspaceAdaptor { afterEach(async () => { Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = originalWorkspaces + Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = originalHttpApi await Instance.disposeAll() await resetDatabase() })