Files
Kilo-Org_kilocode/packages/opencode/test/kilocode/server/httpapi-public.test.ts
T
2026-06-02 16:13:31 +02:00

108 lines
4.5 KiB
TypeScript

import { describe, expect, test } from "bun:test"
import { OpenApi } from "effect/unstable/httpapi"
import { AgentBuilderPaths } from "../../../src/kilocode/server/httpapi/groups/agent-builder"
import { BackgroundProcessPaths } from "../../../src/kilocode/server/httpapi/groups/background-process"
import { ConfigConsolePaths } from "../../../src/kilocode/server/httpapi/groups/config-console"
import { IndexingPaths } from "../../../src/kilocode/server/httpapi/groups/indexing"
import { KiloGatewayPaths } from "../../../src/kilocode/server/httpapi/groups/kilo-gateway"
import { ExperimentalPaths } from "../../../src/server/routes/instance/httpapi/groups/experimental"
import { SessionPaths } from "../../../src/server/routes/instance/httpapi/groups/session"
import { PublicApi } from "../../../src/server/routes/instance/httpapi/public"
type Schema = {
anyOf?: Schema[]
properties?: Record<string, Schema>
type?: string
minLength?: number
maxLength?: number
pattern?: string
}
type Parameter = {
in?: string
name?: string
schema?: Schema
}
type Method = "get" | "post" | "patch"
type Body = {
content?: Record<string, { schema?: Schema }>
}
describe("Kilo PublicApi OpenAPI contract", () => {
test("uses Kilo branding", () => {
const spec = OpenApi.fromApi(PublicApi)
expect(spec.info.title).toBe("kilo")
expect(spec.info.description).toBe("kilo api")
})
test("constrains agent builder route ids", () => {
const spec = OpenApi.fromApi(PublicApi)
const save = AgentBuilderPaths.save.replace(":id", "{id}")
const params = spec.paths[save]?.put?.parameters as Parameter[] | undefined
const schema = params?.find((param) => param.name === "id")?.schema
expect(schema).toEqual({
type: "string",
minLength: 1,
maxLength: 64,
pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]*$",
})
})
test("keeps workspace routing queries on background process routes", () => {
const spec = OpenApi.fromApi(PublicApi)
const routes = [
{ method: "get", path: BackgroundProcessPaths.list },
{ method: "get", path: BackgroundProcessPaths.get },
{ method: "get", path: BackgroundProcessPaths.logs },
{ method: "post", path: BackgroundProcessPaths.stop },
{ method: "post", path: BackgroundProcessPaths.restart },
{ method: "post", path: BackgroundProcessPaths.stopSession },
] satisfies Array<{ method: Method; path: string }>
for (const route of routes) {
const path = route.path.replace(/:([A-Za-z0-9_]+)/g, "{$1}")
const params = spec.paths[path]?.[route.method]?.parameters as Parameter[] | undefined
const query = params?.filter((param) => param.in === "query").map((param) => param.name)
expect(query, `${route.method.toUpperCase()} ${route.path}`).toEqual(["directory", "workspace"])
}
})
test("keeps directory routing queries on Kilo Console routes", () => {
const spec = OpenApi.fromApi(PublicApi)
const routes = [
{ method: "get", path: ExperimentalPaths.worktreeDiff },
{ method: "get", path: ExperimentalPaths.worktreeDiffSummary },
{ method: "get", path: ExperimentalPaths.worktreeDiffFile },
{ method: "post", path: SessionPaths.viewed },
{ method: "get", path: ConfigConsolePaths.overlay },
{ method: "patch", path: ConfigConsolePaths.overlay },
{ method: "get", path: IndexingPaths.status },
] satisfies Array<{ method: Method; path: string }>
for (const route of routes) {
const params = spec.paths[route.path]?.[route.method]?.parameters as Parameter[] | undefined
const query = params?.filter((param) => param.in === "query").map((param) => param.name)
expect(query, `${route.method.toUpperCase()} ${route.path}`).toContain("directory")
expect(query, `${route.method.toUpperCase()} ${route.path}`).toContain("workspace")
}
})
test("keeps personal organization resets nullable", () => {
const spec = OpenApi.fromApi(PublicApi)
const body = spec.paths[KiloGatewayPaths.organization]?.post?.requestBody as Body | undefined
const schema = body?.content?.["application/json"]?.schema
const props = schema?.properties
expect(props?.organizationId).toEqual({ anyOf: [{ type: "string" }, { type: "null" }] })
})
test("keeps transcription prompts in the public contract", () => {
const spec = OpenApi.fromApi(PublicApi)
const body = spec.paths[KiloGatewayPaths.audioTranscriptions]?.post?.requestBody as Body | undefined
const schema = body?.content?.["application/json"]?.schema
expect(schema?.properties?.prompt).toEqual({ type: "string" })
})
})