summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-05-02 09:35:39 -0400
committerGitHub <[email protected]>2026-05-02 09:35:39 -0400
commit075f876e6fbaf3e02223e1add69d8b8e2901d5af (patch)
tree555765da2635d21b64bca103eb1cc3fb08446e85 /packages
parenta849812e9f2ea3089cea45673ec10ecc80d93136 (diff)
downloadopencode-075f876e6fbaf3e02223e1add69d8b8e2901d5af.tar.gz
opencode-075f876e6fbaf3e02223e1add69d8b8e2901d5af.zip
fix(httpapi): re-land workspace create payload accepts missing extra (#25412)
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts5
-rw-r--r--packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts1
-rw-r--r--packages/opencode/test/server/httpapi-workspace.test.ts53
3 files changed, 56 insertions, 3 deletions
diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts
index 112b8a329..08e9e044b 100644
--- a/packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts
+++ b/packages/opencode/src/server/routes/instance/httpapi/groups/workspace.ts
@@ -9,7 +9,10 @@ import { WorkspaceRoutingMiddleware } from "../middleware/workspace-routing"
import { described } from "./metadata"
const root = "/experimental/workspace"
-export const CreatePayload = Schema.Struct(Struct.omit(Workspace.CreateInput.fields, ["projectID"]))
+export const CreatePayload = Schema.Struct({
+ ...Struct.omit(Workspace.CreateInput.fields, ["projectID", "extra"]),
+ extra: Schema.optional(Workspace.CreateInput.fields.extra),
+})
export const SessionRestorePayload = Schema.Struct(Struct.omit(Workspace.SessionRestoreInput.fields, ["workspaceID"]))
export const SessionRestoreResponse = Schema.Struct({
total: NonNegativeInt,
diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts
index 03e8ee74b..570f355e5 100644
--- a/packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts
+++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/workspace.ts
@@ -24,6 +24,7 @@ export const workspaceHandlers = HttpApiBuilder.group(InstanceHttpApi, "workspac
return yield* workspace
.create({
...ctx.payload,
+ extra: ctx.payload.extra ?? null,
projectID: instance.project.id,
})
.pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
diff --git a/packages/opencode/test/server/httpapi-workspace.test.ts b/packages/opencode/test/server/httpapi-workspace.test.ts
index e44a5ee3c..48dcd885b 100644
--- a/packages/opencode/test/server/httpapi-workspace.test.ts
+++ b/packages/opencode/test/server/httpapi-workspace.test.ts
@@ -27,9 +27,9 @@ const it = testEffect(
Layer.mergeAll(NodeServices.layer, Project.defaultLayer, Session.defaultLayer, Workspace.defaultLayer),
)
-function request(path: string, directory: string, init: RequestInit = {}) {
+function request(path: string, directory: string, init: RequestInit = {}, httpApi = true) {
return Effect.promise(() => {
- Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = true
+ Flag.OPENCODE_EXPERIMENTAL_HTTPAPI = httpApi
const headers = new Headers(init.headers)
headers.set("x-opencode-directory", directory)
return Promise.resolve(Server.Default().app.request(path, { ...init, headers }))
@@ -195,6 +195,55 @@ describe("workspace HttpApi", () => {
}),
)
+ it.live("creates workspace with the TUI payload shape", () =>
+ Effect.gen(function* () {
+ Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = true
+ const dir = yield* tmpdirScoped({ git: true })
+ const project = yield* Project.use.fromDirectory(dir)
+ registerAdapter(project.project.id, "local-test", localAdapter(path.join(dir, ".workspace")))
+
+ const created = yield* request(WorkspacePaths.list, dir, {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({ type: "local-test", branch: null }),
+ })
+
+ expect(created.status).toBe(200)
+ expect((yield* Effect.promise(() => created.json())) as Workspace.Info).toMatchObject({
+ type: "local-test",
+ name: "local-test",
+ extra: null,
+ })
+ }),
+ )
+
+ it.live("documents legacy Hono accepting the TUI payload shape", () =>
+ Effect.gen(function* () {
+ Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = true
+ const dir = yield* tmpdirScoped({ git: true })
+ const project = yield* Project.use.fromDirectory(dir)
+ registerAdapter(project.project.id, "local-test", localAdapter(path.join(dir, ".workspace")))
+
+ const created = yield* request(
+ WorkspacePaths.list,
+ dir,
+ {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({ type: "local-test", branch: null }),
+ },
+ false,
+ )
+
+ expect(created.status).toBe(200)
+ expect((yield* Effect.promise(() => created.json())) as Workspace.Info).toMatchObject({
+ type: "local-test",
+ name: "local-test",
+ extra: null,
+ })
+ }),
+ )
+
it.live("routes local workspace requests through the workspace target directory", () =>
Effect.gen(function* () {
Flag.OPENCODE_EXPERIMENTAL_WORKSPACES = true