Trim packages/kirincode/src/server/routes/instance/httpapi/public.ts until OpenAPI generation is mostly a direct projection of the HttpApi route declarations, without breaking the generated SDK surface.
The main failure mode to eliminate is spec-only behavior: anything that appears in /doc or the SDK but is not accepted by runtime HttpApi validation.
public.ts exports PublicApi with a large OpenApi.annotations({ transform }) hook. That hook rewrites the generated spec for legacy SDK compatibility.
The highest-risk rewrite is InstanceQueryParameters, which injected directory and workspace into every instance route in OpenAPI even when the runtime query schema did not accept them. This caused the SDK and /doc to advertise calls that could fail with 400 at runtime.
/doc, generated SDK types, and runtime validation must agree for every endpoint.Status legend: [x] done locally, [~] in progress locally, [ ] not started.
Current combined PR scope:
[x] PR 1 drift tests: added OpenAPI/runtime query assertions and a negative fixture in test/server/httpapi-query-schema-drift.test.ts.[x] PR 2 injection removal: removed broad directory / workspace post-generation injection from public.ts and replaced it with explicit runtime query schemas on affected routes.[ ] PR 3+ cleanup: leave query override, path pattern, error shape, auth, and component-shape rewrites for later PRs.[x] Add or extend packages/kirincode/test/server/httpapi-query-schema-drift.test.ts.[x] Import OpenApi.fromApi and PublicApi.[x] Generate the public spec in-process with OpenApi.fromApi(PublicApi).[x] Add a route inventory for the existing runtime reproducers: session, file, experimental, and instance routes.[x] For each inventory entry, assert every OpenAPI query parameter is declared by the runtime query schema.[x] Add a negative regression fixture that fails on spec-only directory / workspace params.[x] Keep this part test-only.Verification:
[x] bun test --timeout 5000 test/server/httpapi-query-schema-drift.test.ts from packages/opencode.[x] bun typecheck from packages/opencode.[x] Edit packages/kirincode/src/server/routes/instance/httpapi/public.ts.[x] Delete InstanceQueryParameters.[x] Delete the isInstanceRoute constant.[x] Delete the branch that prepends directory and workspace to every instance operation.[x] Keep normalizeParameter(param, route) for parameters that are actually produced by HttpApi.[x] Add WorkspaceRoutingQuery / WorkspaceRoutingQueryFields to runtime query schemas for affected routes.[x] Regenerate SDK and inspect diff. Result: no directory / workspace request-param removals; generated SDK diff is declaration ordering only.Notes:
WorkspaceRoutingQuery in middleware/workspace-routing.ts as the canonical runtime schema for middleware-consumed query params.OpenApi.fromApi emits their query params directly. This intentionally exposes the beta /api/session pagination/filter params in the SDK; cursor mutual-exclusion rules now live in the handlers, while directory / workspace remain allowed with cursors for routing.Expected code shape:
for (const param of operation.parameters ?? []) normalizeParameter(param, `${method.toUpperCase()} ${path}`)
Verification:
[x] bun test --timeout 5000 test/server/httpapi-query-schema-drift.test.ts from packages/opencode.[x] bun dev generate > /tmp/opencode-openapi.json from packages/opencode.[x] ./packages/sdk/js/script/build.ts from repo root.[x] Inspect SDK diff for removed directory / workspace params. Result: none after explicit runtime schemas; v2 list/message now also expose their existing beta pagination/filter query params in the SDK.[x] bun typecheck from packages/opencode.packages/kirincode/src/server/routes/instance/httpapi/public.ts.QueryNumberParameters and QueryBooleanParameters one field at a time.groups/metadata.ts or a new groups/query.ts.Schema.NumberFromString.check(...) and boolean string decoders like the existing QueryBoolean in groups/session.ts.QueryParameterSchemas entries when SDK compatibility requires a public encoded type that Effect OpenAPI cannot emit yet.Concrete first targets:
[x] Consolidate roots / archived onto an explicit shared route schema helper. Keep QueryBooleanParameters until route-level schema metadata can preserve the SDK's boolean | "true" | "false" call shape without a global transform.[x] Replace broad QueryNumberParameters reliance for start / cursor / limit with route-specific SDK compatibility schemas. Keep improving route-level constraints where behavior is intentionally stricter.GET /find/file limit, GET /session/{sessionID}/diff messageID, and GET /session/{sessionID}/message limit overrides until their route schemas generate identical SDK types directly.Verification:
bun dev generate > /tmp/opencode-openapi.json from packages/opencode../packages/sdk/js/script/build.ts from repo root.bun typecheck from packages/opencode.PathParameterSchemas and pathParameterSchema() in public.ts.packages/kirincode/src/session/schema.ts, packages/kirincode/src/permission/schema.ts, and pty schema definitions.public.ts overrides.Concrete first targets:
[x] sessionID[x] messageID[x] partID[x] permissionID[x] ptyID
[x] Remove ambiguous workspace id path overrides once the endpoint source schema emits the wrk pattern.
Verification:
bun dev generate > /tmp/opencode-openapi.json from packages/opencode../packages/sdk/js/script/build.ts from repo root.bun typecheck from packages/opencode.packages/kirincode/src/server/routes/instance/httpapi/groups/.HttpApiError.BadRequest / HttpApiError.NotFound with explicit error schemas from packages/kirincode/src/server/routes/instance/httpapi/errors.ts or add new ones there.normalizeLegacyErrorResponses() only after generated OpenAPI remains SDK-compatible.Concrete first targets:
groups/config.ts PATCH /config bad request.groups/session.ts endpoints that already translate domain not-found errors.groups/file.ts if any handler currently relies on built-in error shape.Verification:
bun dev generate > /tmp/opencode-openapi.json from packages/opencode../packages/sdk/js/script/build.ts from repo root.bun typecheck from packages/opencode.delete operation.security, delete operation.responses?.["401"], and delete spec.components?.securitySchemes in public.ts.Verification:
./packages/sdk/js/script/build.ts from repo root.public.ts: normalizeComponentNames, collapseDuplicateComponents, applyLegacySchemaOverrides, normalizeComponentDescriptions, stripOptionalNull, fixSelfReferencingComponents.effect-smol generation first.Concrete first targets:
normalizeComponentDescriptions if SDK output does not change materially.applyLegacySchemaOverrides entries that correspond to schemas already fixed at the source.stripOptionalNull until there is an explicit SDK migration plan, because it likely affects many optional fields.Verification:
bun dev generate > /tmp/opencode-openapi.json from packages/opencode../packages/sdk/js/script/build.ts from repo root.Long-term, WorkspaceRoutingMiddleware should declare the query fields it reads once, and HttpApi should use that declaration for both runtime validation and OpenAPI generation.
Target in effect-smol:
HttpApiMiddleware.Service config with optional query schema support, or add a dedicated middleware query annotation.OpenApi.fromApi emit middleware query params for endpoints using that middleware.Once available, remove WorkspaceRoutingQueryFields spreads from route groups and declare directory / workspace only on WorkspaceRoutingMiddleware.
InstanceQueryParameters spec injection; rely on WorkspaceRoutingQueryFields already present in runtime schemas.bun dev generate > /tmp/opencode-openapi.json from packages/opencode../packages/sdk/js/script/build.ts from repo root.bun typecheck from packages/opencode.