diff --git a/packages/opencode/specs/openapi-translation-cleanup.md b/packages/opencode/specs/openapi-translation-cleanup.md index 472e686ab0..255c09644f 100644 --- a/packages/opencode/specs/openapi-translation-cleanup.md +++ b/packages/opencode/specs/openapi-translation-cleanup.md @@ -111,7 +111,7 @@ Concrete first targets: - `[x]` `permissionID` - `[x]` `ptyID` -Leave ambiguous route-local `id` overrides for workspace routes until they are renamed or explicitly typed in endpoint params. +- `[x]` Remove ambiguous workspace `id` path overrides once the endpoint source schema emits the `wrk` pattern. Verification: diff --git a/packages/opencode/src/control-plane/schema.ts b/packages/opencode/src/control-plane/schema.ts index dd4c325490..a106ae8990 100644 --- a/packages/opencode/src/control-plane/schema.ts +++ b/packages/opencode/src/control-plane/schema.ts @@ -4,9 +4,9 @@ import { Identifier } from "@/id/id" import { zod, ZodOverride } from "@opencode-ai/core/effect-zod" import { withStatics } from "@opencode-ai/core/schema" -const workspaceIdSchema = Schema.String.annotate({ [ZodOverride]: Identifier.schema("workspace") }).pipe( - Schema.brand("WorkspaceID"), -) +const workspaceIdSchema = Schema.String.check(Schema.isStartsWith("wrk")) + .annotate({ [ZodOverride]: Identifier.schema("workspace") }) + .pipe(Schema.brand("WorkspaceID")) export type WorkspaceID = typeof workspaceIdSchema.Type diff --git a/packages/opencode/src/server/routes/instance/httpapi/public.ts b/packages/opencode/src/server/routes/instance/httpapi/public.ts index c67a6071e6..1a294f84e7 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/public.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/public.ts @@ -478,7 +478,7 @@ function flattenOptions(options: OpenApiSchema[] | undefined): OpenApiSchema[] | function normalizeParameter(param: OpenApiParameter, route: string) { if (!param.schema || typeof param.schema !== "object") return if (param.in === "path") { - param.schema = pathParameterSchema(route, param.name) ?? stripOptionalNull(param.schema) + param.schema = stripOptionalNull(param.schema) return } if (param.in === "query") { @@ -497,12 +497,6 @@ function normalizeParameter(param: OpenApiParameter, route: string) { param.schema = stripOptionalNull(param.schema) } -function pathParameterSchema(route: string, name: string) { - if (name === "id" && route.startsWith("DELETE /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" } - if (name === "id" && route.startsWith("POST /experimental/workspace/")) return { type: "string", pattern: "^wrk.*" } - return undefined -} - export const PublicApi = OpenCodeHttpApi.annotateMerge( OpenApi.annotations({ title: "opencode", diff --git a/packages/opencode/test/server/httpapi-query-schema-drift.test.ts b/packages/opencode/test/server/httpapi-query-schema-drift.test.ts index cd3f8a5d51..bf24f90353 100644 --- a/packages/opencode/test/server/httpapi-query-schema-drift.test.ts +++ b/packages/opencode/test/server/httpapi-query-schema-drift.test.ts @@ -17,6 +17,7 @@ import { ToolListQuery, } from "../../src/server/routes/instance/httpapi/groups/experimental" import { InstancePaths, VcsDiffQuery } from "../../src/server/routes/instance/httpapi/groups/instance" +import { WorkspacePaths } from "../../src/server/routes/instance/httpapi/groups/workspace" import { ListQuery as SessionListQuery, MessagesQuery, @@ -82,6 +83,7 @@ const pathParamPatterns = [ { method: "post", path: "/permission/:requestID/reply", name: "requestID", pattern: "^per" }, { method: "post", path: "/question/:requestID/reply", name: "requestID", pattern: "^que" }, { method: "put", path: PtyPaths.update, name: "ptyID", pattern: "^pty" }, + { method: "delete", path: WorkspacePaths.remove, name: "id", pattern: "^wrk" }, ] satisfies Array<{ method: Method; path: string; name: string; pattern: string }> function app() {