Quellcode durchsuchen

fix(httpapi): model optional worktree payload as no content (#29246)

Kit Langton vor 2 Monaten
Ursprung
Commit
b46cec2a7d

+ 2 - 2
packages/opencode/src/server/routes/instance/httpapi/groups/experimental.ts

@@ -5,7 +5,7 @@ import { Session } from "@/session/session"
 import { Worktree } from "@/worktree"
 import { Worktree } from "@/worktree"
 import { NonNegativeInt } from "@opencode-ai/core/schema"
 import { NonNegativeInt } from "@opencode-ai/core/schema"
 import { Schema } from "effect"
 import { Schema } from "effect"
-import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
+import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
 import { Authorization } from "../middleware/authorization"
 import { Authorization } from "../middleware/authorization"
 import { InstanceContextMiddleware } from "../middleware/instance-context"
 import { InstanceContextMiddleware } from "../middleware/instance-context"
 import {
 import {
@@ -168,7 +168,7 @@ export const ExperimentalApi = HttpApi.make("experimental")
         HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
         HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
           disableCodecs: true,
           disableCodecs: true,
           query: WorkspaceRoutingQuery,
           query: WorkspaceRoutingQuery,
-          payload: Schema.UndefinedOr(Worktree.CreateInput),
+          payload: [HttpApiSchema.NoContent, Worktree.CreateInput],
           success: described(Worktree.Info, "Worktree created"),
           success: described(Worktree.Info, "Worktree created"),
           error: WorktreeApiError,
           error: WorktreeApiError,
         }).annotateMerge(
         }).annotateMerge(

+ 2 - 2
packages/opencode/src/server/routes/instance/httpapi/handlers/experimental.ts

@@ -104,9 +104,9 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper
     })
     })
 
 
     const worktreeCreate = Effect.fn("ExperimentalHttpApi.worktreeCreate")(function* (ctx: {
     const worktreeCreate = Effect.fn("ExperimentalHttpApi.worktreeCreate")(function* (ctx: {
-      payload: Worktree.CreateInput | undefined
+      payload: typeof Worktree.CreateInput.Type | void
     }) {
     }) {
-      return yield* mapWorktreeError(worktreeSvc.create(ctx.payload))
+      return yield* mapWorktreeError(worktreeSvc.create(ctx.payload ?? undefined))
     })
     })
 
 
     const worktreeRemove = Effect.fn("ExperimentalHttpApi.worktreeRemove")(function* (input: {
     const worktreeRemove = Effect.fn("ExperimentalHttpApi.worktreeRemove")(function* (input: {

+ 22 - 0
packages/opencode/test/server/worktree-endpoint-repro.test.ts

@@ -228,6 +228,28 @@ describe("worktree endpoint reproduction", () => {
     { git: true },
     { git: true },
   )
   )
 
 
+  worktreeTest(
+    "direct HttpApi worktree create rejects explicit null payload",
+    () =>
+      Effect.gen(function* () {
+        const test = yield* TestInstance
+        const server = yield* serverScoped()
+
+        const response = yield* request(
+          server,
+          `${ExperimentalPaths.worktree}?directory=${encodeURIComponent(test.directory)}`,
+          {
+            method: "POST",
+            headers: { "content-type": "application/json" },
+            body: "null",
+          },
+        )
+
+        expect(response.status).toBe(400)
+      }),
+    { git: true },
+  )
+
   worktreeTest(
   worktreeTest(
     "workspace worktree create does not hang",
     "workspace worktree create does not hang",
     () =>
     () =>