108 lines
4.5 KiB
TypeScript
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" })
|
|
})
|
|
})
|