mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
feat(kilocode): add worktree diff, FIM proxy, audio transcription, and session viewed endpoints
Introduce several new Effect HttpApi endpoints across the kilo-gateway and experimental API groups to support agent manager workflows and enhanced gateway proxying. - Add worktree diff endpoints (diff, diff/summary, diff/file) for comparing worktree changes against a base branch - Add FIM completion proxy endpoint with streaming SSE response and timeout handling - Add audio transcriptions proxy endpoint forwarding to Kilo Gateway - Add organization modes endpoint to fetch custom modes config - Add session/viewed endpoint to track which sessions the user has open - Extend session list query with projectID and worktrees parameters - Register all new routes in Hono instance router - Regenerate SDK types and OpenAPI spec
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
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 "@/server/routes/instance/httpapi/middleware/authorization"
|
||||
import { InstanceContextMiddleware } from "@/server/routes/instance/httpapi/middleware/instance-context"
|
||||
import { WorkspaceRoutingMiddleware } from "@/server/routes/instance/httpapi/middleware/workspace-routing"
|
||||
@@ -103,6 +103,61 @@ export const CloudSessionImportBody = Schema.Struct({
|
||||
sessionId: Schema.String,
|
||||
})
|
||||
|
||||
const GroupEntry = Schema.Union([
|
||||
Schema.String,
|
||||
Schema.Tuple([
|
||||
Schema.String,
|
||||
Schema.Struct({
|
||||
fileRegex: Schema.optional(Schema.String),
|
||||
description: Schema.optional(Schema.String),
|
||||
}),
|
||||
]),
|
||||
])
|
||||
|
||||
export const OrganizationMode = Schema.Struct({
|
||||
id: Schema.String,
|
||||
organization_id: Schema.String,
|
||||
name: Schema.String,
|
||||
slug: Schema.String,
|
||||
created_by: Schema.String,
|
||||
created_at: Schema.String,
|
||||
updated_at: Schema.String,
|
||||
config: Schema.Struct({
|
||||
roleDefinition: Schema.optional(Schema.String),
|
||||
whenToUse: Schema.optional(Schema.String),
|
||||
description: Schema.optional(Schema.String),
|
||||
customInstructions: Schema.optional(Schema.String),
|
||||
groups: Schema.optional(Schema.Array(GroupEntry)),
|
||||
}),
|
||||
})
|
||||
|
||||
export const OrganizationModes = Schema.Struct({
|
||||
modes: Schema.Array(OrganizationMode),
|
||||
})
|
||||
|
||||
export const FimBody = Schema.Struct({
|
||||
prefix: Schema.String,
|
||||
suffix: Schema.String,
|
||||
model: Schema.optional(Schema.String),
|
||||
maxTokens: Schema.optional(Schema.Finite),
|
||||
temperature: Schema.optional(Schema.Finite),
|
||||
})
|
||||
|
||||
export const AudioTranscriptionsBody = Schema.Struct({
|
||||
model: Schema.String,
|
||||
input_audio: Schema.Struct({
|
||||
data: Schema.String,
|
||||
format: Schema.String,
|
||||
}),
|
||||
language: Schema.optional(Schema.String),
|
||||
temperature: Schema.optional(Schema.Finite),
|
||||
})
|
||||
|
||||
export const TranscriptionResponse = Schema.Struct({
|
||||
text: Schema.String,
|
||||
usage: Schema.optional(Schema.Unknown),
|
||||
})
|
||||
|
||||
export const CloudMessage = Schema.Struct({
|
||||
info: Schema.Struct({
|
||||
id: Schema.String,
|
||||
@@ -136,7 +191,10 @@ export const CloudSessionData = Schema.Struct({
|
||||
})
|
||||
|
||||
export const KiloGatewayPaths = {
|
||||
modes: `${root}/modes`,
|
||||
profile: `${root}/profile`,
|
||||
fim: `${root}/fim`,
|
||||
audioTranscriptions: `${root}/audio/transcriptions`,
|
||||
notifications: `${root}/notifications`,
|
||||
organization: `${root}/organization`,
|
||||
clawStatus: `${root}/claw/status`,
|
||||
@@ -160,6 +218,37 @@ export const KiloGatewayApi = HttpApi.make("kilo")
|
||||
description: "Fetch user profile and organizations from Kilo Gateway",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("modes", KiloGatewayPaths.modes, {
|
||||
success: described(OrganizationModes, "Organization modes list"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "kilo.modes",
|
||||
summary: "Get organization custom modes",
|
||||
description: "Fetch custom modes defined for the current organization",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.post("fim", KiloGatewayPaths.fim, {
|
||||
payload: FimBody,
|
||||
success: Schema.String.pipe(HttpApiSchema.asText({ contentType: "text/event-stream" })),
|
||||
error: [HttpApiError.BadRequest, HttpApiError.Unauthorized],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "kilo.fim",
|
||||
summary: "FIM completion",
|
||||
description: "Proxy a Fill-in-the-Middle completion request to the Kilo Gateway",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.post("audioTranscriptions", KiloGatewayPaths.audioTranscriptions, {
|
||||
payload: AudioTranscriptionsBody,
|
||||
success: described(TranscriptionResponse, "Transcription response"),
|
||||
error: [HttpApiError.BadRequest, HttpApiError.Unauthorized],
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "kilo.audio.transcriptions",
|
||||
summary: "Speech to text transcription",
|
||||
description: "Proxy an audio transcription request to the Kilo Gateway",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("notifications", KiloGatewayPaths.notifications, {
|
||||
success: described(Schema.Array(Notification), "Notifications list"),
|
||||
error: [HttpApiError.BadRequest, HttpApiError.Unauthorized],
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
importSessionToDb,
|
||||
} from "@kilocode/kilo-gateway"
|
||||
import {
|
||||
HEADER_FEATURE,
|
||||
HEADER_ORGANIZATIONID,
|
||||
KILO_API_BASE,
|
||||
KILO_CHAT_URL,
|
||||
@@ -15,9 +16,13 @@ import {
|
||||
clearModesCache,
|
||||
fetchBalance,
|
||||
fetchKilocodeNotifications,
|
||||
fetchOrganizationModes,
|
||||
fetchProfile,
|
||||
} from "@kilocode/kilo-gateway"
|
||||
import { buildKiloHeaders } from "@kilocode/kilo-gateway"
|
||||
import { Effect } from "effect"
|
||||
import * as Stream from "effect/Stream"
|
||||
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
|
||||
import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
|
||||
import { Auth } from "@/auth"
|
||||
import { Bus } from "@/bus"
|
||||
@@ -29,6 +34,9 @@ import { InstanceHttpApi } from "@/server/routes/instance/httpapi/api"
|
||||
import { MessageTable, PartTable, SessionTable } from "@/session/session.sql"
|
||||
import { Session } from "@/session/session"
|
||||
import { Database } from "@/storage/db"
|
||||
import { AudioTranscriptionsBody, FimBody } from "../groups/kilo-gateway"
|
||||
|
||||
const FIM_TIMEOUT_MS = 30_000
|
||||
|
||||
export const kiloGatewayHandlers = HttpApiBuilder.group(InstanceHttpApi, "kilo", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
@@ -47,6 +55,117 @@ export const kiloGatewayHandlers = HttpApiBuilder.group(InstanceHttpApi, "kilo",
|
||||
return { profile, balance, currentOrgId }
|
||||
})
|
||||
|
||||
const proxy = Effect.fn("KiloGatewayHttpApi.proxyAuth")(function* () {
|
||||
const info = yield* auth.get("kilo").pipe(Effect.mapError(() => new HttpApiError.Unauthorized({})))
|
||||
return {
|
||||
auth: info,
|
||||
token: getToken(info),
|
||||
organizationId: getOrganizationId(info),
|
||||
}
|
||||
})
|
||||
|
||||
const modes = Effect.fn("KiloGatewayHttpApi.modes")(function* () {
|
||||
const info = yield* auth.get("kilo").pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
|
||||
if (!info || info.type !== "oauth" || !info.access || !info.accountId) return { modes: [] }
|
||||
|
||||
return yield* Effect.promise(() => fetchOrganizationModes(info.access, info.accountId)).pipe(
|
||||
Effect.map((modes) => ({ modes })),
|
||||
Effect.catch(() => Effect.succeed({ modes: [] })),
|
||||
)
|
||||
})
|
||||
|
||||
const fim = Effect.fn("KiloGatewayHttpApi.fim")(function* (ctx: { payload: typeof FimBody.Type }) {
|
||||
const info = yield* proxy()
|
||||
if (!info.auth) return yield* Effect.fail(new HttpApiError.Unauthorized({}))
|
||||
if (!info.token) return yield* Effect.fail(new HttpApiError.Unauthorized({}))
|
||||
|
||||
const request = yield* HttpServerRequest.HttpServerRequest
|
||||
const endpoint = new URL("fim/completions", `${KILO_API_BASE}/api/`)
|
||||
const signal = AbortSignal.any([request.source.signal, AbortSignal.timeout(FIM_TIMEOUT_MS)])
|
||||
const response = yield* Effect.promise(async () => {
|
||||
try {
|
||||
return await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${info.token}`,
|
||||
...buildKiloHeaders(undefined, { kilocodeOrganizationId: info.organizationId }),
|
||||
[HEADER_FEATURE]: "autocomplete",
|
||||
},
|
||||
signal,
|
||||
body: JSON.stringify({
|
||||
model: ctx.payload.model ?? "mistralai/codestral-2501",
|
||||
prompt: ctx.payload.prefix,
|
||||
suffix: ctx.payload.suffix,
|
||||
max_tokens: ctx.payload.maxTokens ?? 256,
|
||||
temperature: ctx.payload.temperature ?? 0.2,
|
||||
stream: true,
|
||||
}),
|
||||
})
|
||||
} catch (err) {
|
||||
if (err instanceof DOMException && err.name === "TimeoutError")
|
||||
return Response.json({ error: "FIM request timed out" }, { status: 504 })
|
||||
if (signal.aborted) return Response.json({ error: "FIM request canceled" }, { status: 499 })
|
||||
throw err
|
||||
}
|
||||
})
|
||||
if (!response.ok) {
|
||||
const text = yield* Effect.promise(() => response.text())
|
||||
return HttpServerResponse.jsonUnsafe(
|
||||
{ error: `FIM request failed: ${response.status} ${text}` },
|
||||
{ status: response.status },
|
||||
)
|
||||
}
|
||||
if (!response.body) return HttpServerResponse.raw(null, { status: response.status })
|
||||
|
||||
return HttpServerResponse.stream(
|
||||
Stream.fromReadableStream({
|
||||
evaluate: () => response.body!,
|
||||
onError: (err) => err,
|
||||
}),
|
||||
{
|
||||
contentType: "text/event-stream",
|
||||
headers: {
|
||||
"Cache-Control": "no-cache",
|
||||
Connection: "keep-alive",
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
const audioTranscriptions = Effect.fn("KiloGatewayHttpApi.audioTranscriptions")(function* (ctx: {
|
||||
payload: typeof AudioTranscriptionsBody.Type
|
||||
}) {
|
||||
const info = yield* proxy()
|
||||
if (!info.auth) return yield* Effect.fail(new HttpApiError.Unauthorized({}))
|
||||
if (!info.token) return yield* Effect.fail(new HttpApiError.Unauthorized({}))
|
||||
|
||||
const request = yield* HttpServerRequest.HttpServerRequest
|
||||
const response = yield* Effect.tryPromise({
|
||||
try: () =>
|
||||
fetch(`${KILO_API_BASE}/api/gateway/v1/audio/transcriptions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${info.token}`,
|
||||
...buildKiloHeaders(undefined, { kilocodeOrganizationId: info.organizationId }),
|
||||
[HEADER_FEATURE]: "vscode-extension",
|
||||
},
|
||||
signal: request.source.signal,
|
||||
body: JSON.stringify(ctx.payload),
|
||||
}),
|
||||
catch: () => new HttpApiError.BadRequest({}),
|
||||
})
|
||||
const text = yield* Effect.promise(() => response.text())
|
||||
return HttpServerResponse.raw(text, {
|
||||
status: response.status,
|
||||
contentType: response.headers.get("Content-Type") ?? "application/json",
|
||||
headers: {
|
||||
"Content-Type": response.headers.get("Content-Type") ?? "application/json",
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
const notifications = Effect.fn("KiloGatewayHttpApi.notifications")(function* () {
|
||||
const info = yield* auth.get("kilo").pipe(Effect.mapError(() => new HttpApiError.BadRequest({})))
|
||||
const token = getToken(info)
|
||||
@@ -178,6 +297,9 @@ export const kiloGatewayHandlers = HttpApiBuilder.group(InstanceHttpApi, "kilo",
|
||||
|
||||
return handlers
|
||||
.handle("profile", profile)
|
||||
.handle("modes", modes)
|
||||
.handle("fim", fim)
|
||||
.handle("audioTranscriptions", audioTranscriptions)
|
||||
.handle("notifications", notifications)
|
||||
.handle("organization", organization)
|
||||
.handle("clawStatus", clawStatus)
|
||||
|
||||
@@ -35,6 +35,9 @@ export function register(app: Hono, handler: Handler, context: Context.Context<u
|
||||
app.post(SessionImportPaths.part, (c) => handler(c.req.raw, context))
|
||||
app.get(IndexingPaths.status, (c) => handler(c.req.raw, context))
|
||||
app.get(KiloGatewayPaths.profile, (c) => handler(c.req.raw, context))
|
||||
app.get(KiloGatewayPaths.modes, (c) => handler(c.req.raw, context))
|
||||
app.post(KiloGatewayPaths.fim, (c) => handler(c.req.raw, context))
|
||||
app.post(KiloGatewayPaths.audioTranscriptions, (c) => handler(c.req.raw, context))
|
||||
app.get(KiloGatewayPaths.notifications, (c) => handler(c.req.raw, context))
|
||||
app.post(KiloGatewayPaths.organization, (c) => handler(c.req.raw, context))
|
||||
app.get(KiloGatewayPaths.clawStatus, (c) => handler(c.req.raw, context))
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { AccountID, OrgID } from "@/account/schema"
|
||||
import { Snapshot } from "@/snapshot" // kilocode_change
|
||||
import { MCP } from "@/mcp"
|
||||
import { ProviderID, ModelID } from "@/provider/schema"
|
||||
import { Session } from "@/session/session"
|
||||
import { WorktreeDiff } from "@/kilocode/review/worktree-diff" // kilocode_change
|
||||
import { Worktree } from "@/worktree"
|
||||
import { NonNegativeInt } from "@/util/schema"
|
||||
import { Schema, SchemaGetter } from "effect"
|
||||
@@ -55,7 +57,11 @@ const QueryBoolean = Schema.Literals(["true", "false"]).pipe(
|
||||
)
|
||||
const WorktreeList = Schema.Array(Schema.String)
|
||||
export const SessionListQuery = Schema.Struct({
|
||||
// kilocode_change start
|
||||
projectID: Schema.optional(Schema.String),
|
||||
directory: Schema.optional(Schema.String),
|
||||
worktrees: Schema.optional(QueryBoolean),
|
||||
// kilocode_change end
|
||||
roots: Schema.optional(QueryBoolean),
|
||||
start: Schema.optional(Schema.NumberFromString),
|
||||
cursor: Schema.optional(Schema.NumberFromString),
|
||||
@@ -63,6 +69,15 @@ export const SessionListQuery = Schema.Struct({
|
||||
limit: Schema.optional(Schema.NumberFromString),
|
||||
archived: Schema.optional(QueryBoolean),
|
||||
})
|
||||
// kilocode_change start
|
||||
export const WorktreeDiffQuery = Schema.Struct({
|
||||
base: Schema.optional(Schema.String),
|
||||
})
|
||||
export const WorktreeDiffFileQuery = Schema.Struct({
|
||||
base: Schema.optional(Schema.String),
|
||||
file: Schema.String,
|
||||
})
|
||||
// kilocode_change end
|
||||
|
||||
export const ExperimentalPaths = {
|
||||
console: "/experimental/console",
|
||||
@@ -71,6 +86,9 @@ export const ExperimentalPaths = {
|
||||
tool: "/experimental/tool",
|
||||
toolIDs: "/experimental/tool/ids",
|
||||
worktree: "/experimental/worktree",
|
||||
worktreeDiff: "/experimental/worktree/diff", // kilocode_change
|
||||
worktreeDiffFile: "/experimental/worktree/diff/file", // kilocode_change
|
||||
worktreeDiffSummary: "/experimental/worktree/diff/summary", // kilocode_change
|
||||
worktreeReset: "/experimental/worktree/reset",
|
||||
session: "/experimental/session",
|
||||
resource: "/experimental/resource",
|
||||
@@ -174,6 +192,41 @@ export const ExperimentalApi = HttpApi.make("experimental")
|
||||
description: "Reset a worktree branch to the primary default branch.",
|
||||
}),
|
||||
),
|
||||
// kilocode_change start - worktree diff endpoints for agent manager
|
||||
HttpApiEndpoint.get("worktreeDiff", ExperimentalPaths.worktreeDiff, {
|
||||
query: WorktreeDiffQuery,
|
||||
success: described(Schema.Array(Snapshot.FileDiff), "File diffs"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "worktree.diff",
|
||||
summary: "Get worktree diff",
|
||||
description: "Get file diffs for a worktree compared to its base branch. Includes uncommitted changes.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("worktreeDiffSummary", ExperimentalPaths.worktreeDiffSummary, {
|
||||
query: WorktreeDiffQuery,
|
||||
success: described(Schema.Array(WorktreeDiff.Item), "Diff summary items"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "worktree.diffSummary",
|
||||
summary: "Get worktree diff summary",
|
||||
description: "Get lightweight file diff metadata for a worktree compared to its base branch.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("worktreeDiffFile", ExperimentalPaths.worktreeDiffFile, {
|
||||
query: WorktreeDiffFileQuery,
|
||||
success: described(Schema.NullOr(WorktreeDiff.Item), "Diff detail item"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "worktree.diffFile",
|
||||
summary: "Get worktree diff detail",
|
||||
description: "Get full diff contents for one worktree file compared to its base branch.",
|
||||
}),
|
||||
),
|
||||
// kilocode_change end
|
||||
HttpApiEndpoint.get("session", ExperimentalPaths.session, {
|
||||
query: SessionListQuery,
|
||||
success: described(Schema.Array(Session.GlobalInfo), "List of sessions"),
|
||||
|
||||
@@ -66,6 +66,12 @@ export const RevertPayload = Schema.Struct(Struct.omit(SessionRevert.RevertInput
|
||||
export const PermissionResponsePayload = Schema.Struct({
|
||||
response: Permission.Reply,
|
||||
})
|
||||
// kilocode_change start
|
||||
export const ViewedPayload = Schema.Struct({
|
||||
focused: Schema.optional(Schema.Array(Schema.String)),
|
||||
open: Schema.optional(Schema.Array(Schema.String)),
|
||||
})
|
||||
// kilocode_change end
|
||||
|
||||
export const SessionPaths = {
|
||||
list: root,
|
||||
@@ -94,6 +100,7 @@ export const SessionPaths = {
|
||||
deleteMessage: `${root}/:sessionID/message/:messageID`,
|
||||
deletePart: `${root}/:sessionID/message/:messageID/part/:partID`,
|
||||
updatePart: `${root}/:sessionID/message/:messageID/part/:partID`,
|
||||
viewed: `${root}/viewed`, // kilocode_change
|
||||
} as const
|
||||
|
||||
export const SessionApi = HttpApi.make("session")
|
||||
@@ -409,6 +416,18 @@ export const SessionApi = HttpApi.make("session")
|
||||
description: "Update a part in a message.",
|
||||
}),
|
||||
),
|
||||
// kilocode_change start
|
||||
HttpApiEndpoint.post("viewed", SessionPaths.viewed, {
|
||||
payload: ViewedPayload,
|
||||
success: described(Schema.Boolean, "Viewed sessions updated"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "session.viewed",
|
||||
summary: "Set viewed sessions",
|
||||
description: "Notify the server which sessions the user is currently viewing, or clear all.",
|
||||
}),
|
||||
),
|
||||
// kilocode_change end
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
|
||||
@@ -7,12 +7,24 @@ import { Project } from "@/project/project"
|
||||
import { Session } from "@/session/session"
|
||||
import { ToolRegistry } from "@/tool/registry"
|
||||
import * as EffectZod from "@/util/effect-zod"
|
||||
import { Filesystem } from "@/util/filesystem" // kilocode_change
|
||||
import { Review } from "@/kilocode/review/review" // kilocode_change
|
||||
import { WorktreeDiff } from "@/kilocode/review/worktree-diff" // kilocode_change
|
||||
import { WorktreeFamily } from "@/kilocode/worktree-family" // kilocode_change
|
||||
import { Worktree } from "@/worktree"
|
||||
import { Effect, Option } from "effect"
|
||||
import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse"
|
||||
import { HttpApiBuilder, HttpApiError } from "effect/unstable/httpapi"
|
||||
import * as Log from "@opencode-ai/core/util/log" // kilocode_change
|
||||
import path from "path" // kilocode_change
|
||||
import { InstanceHttpApi } from "../api"
|
||||
import { ConsoleSwitchPayload, SessionListQuery, ToolListQuery } from "../groups/experimental"
|
||||
import {
|
||||
ConsoleSwitchPayload,
|
||||
SessionListQuery,
|
||||
ToolListQuery,
|
||||
WorktreeDiffFileQuery,
|
||||
WorktreeDiffQuery,
|
||||
} from "../groups/experimental"
|
||||
|
||||
export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "experimental", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
@@ -113,11 +125,67 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper
|
||||
return true
|
||||
})
|
||||
|
||||
// kilocode_change start - worktree diff endpoints for agent manager
|
||||
const base = Effect.fn("ExperimentalHttpApi.worktreeDiffBase")(function* (input: { base?: string }) {
|
||||
if (input.base) return input.base
|
||||
return yield* Effect.promise(() => Review.getBaseBranch())
|
||||
})
|
||||
|
||||
const worktreeDiff = Effect.fn("ExperimentalHttpApi.worktreeDiff")(function* (ctx: {
|
||||
query: typeof WorktreeDiffQuery.Type
|
||||
}) {
|
||||
const log = Log.create({ service: "worktree-diff" })
|
||||
const ref = yield* base(ctx.query)
|
||||
const dir = yield* InstanceState.directory
|
||||
log.info("computing diff", { dir, base: ref })
|
||||
const diffs = yield* Effect.promise(() => WorktreeDiff.full({ dir, base: ref, log }))
|
||||
return diffs.map((diff) => ({
|
||||
file: diff.file,
|
||||
before: diff.before,
|
||||
after: diff.after,
|
||||
patch: diff.patch,
|
||||
additions: diff.additions,
|
||||
deletions: diff.deletions,
|
||||
status: diff.status,
|
||||
}))
|
||||
})
|
||||
|
||||
const worktreeDiffSummary = Effect.fn("ExperimentalHttpApi.worktreeDiffSummary")(function* (ctx: {
|
||||
query: typeof WorktreeDiffQuery.Type
|
||||
}) {
|
||||
const log = Log.create({ service: "worktree-diff" })
|
||||
const ref = yield* base(ctx.query)
|
||||
const dir = yield* InstanceState.directory
|
||||
log.info("computing diff summary", { dir, base: ref })
|
||||
return yield* Effect.promise(() => WorktreeDiff.summary({ dir, base: ref, log }))
|
||||
})
|
||||
|
||||
const worktreeDiffFile = Effect.fn("ExperimentalHttpApi.worktreeDiffFile")(function* (ctx: {
|
||||
query: typeof WorktreeDiffFileQuery.Type
|
||||
}) {
|
||||
const log = Log.create({ service: "worktree-diff" })
|
||||
const ref = yield* base(ctx.query)
|
||||
const dir = yield* InstanceState.directory
|
||||
log.info("computing diff detail", { dir, base: ref, file: ctx.query.file })
|
||||
return yield* Effect.promise(() => WorktreeDiff.detail({ dir, base: ref, file: ctx.query.file, log })).pipe(
|
||||
Effect.map((item) => item ?? null),
|
||||
)
|
||||
})
|
||||
// kilocode_change end
|
||||
|
||||
const session = Effect.fn("ExperimentalHttpApi.session")(function* (ctx: { query: typeof SessionListQuery.Type }) {
|
||||
const limit = ctx.query.limit ?? 100
|
||||
// kilocode_change start
|
||||
const state = yield* InstanceState.context
|
||||
const projectID = ctx.query.worktrees && !ctx.query.projectID ? state.project.id : ctx.query.projectID
|
||||
const directories = ctx.query.worktrees ? yield* Effect.promise(() => WorktreeFamily.list()) : undefined
|
||||
const sorted = directories ? [...directories].sort((a, b) => b.length - a.length) : undefined
|
||||
// kilocode_change end
|
||||
const sessions = Array.from(
|
||||
Session.listGlobal({
|
||||
directory: ctx.query.directory,
|
||||
projectID, // kilocode_change
|
||||
directory: ctx.query.worktrees ? undefined : ctx.query.directory, // kilocode_change
|
||||
directories, // kilocode_change
|
||||
roots: ctx.query.roots,
|
||||
start: ctx.query.start,
|
||||
cursor: ctx.query.cursor,
|
||||
@@ -126,10 +194,18 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper
|
||||
archived: ctx.query.archived,
|
||||
}),
|
||||
)
|
||||
const list = sessions.length > limit ? sessions.slice(0, limit) : sessions
|
||||
// kilocode_change start - resolve worktree folder name for each session
|
||||
const result = sorted
|
||||
? sessions.map((session) => {
|
||||
const root = sorted.find((dir) => Filesystem.contains(dir, session.directory))
|
||||
return { ...session, worktreeName: path.basename(root ?? session.directory) }
|
||||
})
|
||||
: sessions
|
||||
const list = result.length > limit ? result.slice(0, limit) : result
|
||||
// kilocode_change end
|
||||
return HttpServerResponse.jsonUnsafe(list, {
|
||||
headers:
|
||||
sessions.length > limit && list.length > 0
|
||||
result.length > limit && list.length > 0 // kilocode_change
|
||||
? { "x-next-cursor": String(list[list.length - 1].time.updated) }
|
||||
: undefined,
|
||||
})
|
||||
@@ -139,17 +215,24 @@ export const experimentalHandlers = HttpApiBuilder.group(InstanceHttpApi, "exper
|
||||
return yield* mcp.resources()
|
||||
})
|
||||
|
||||
return handlers
|
||||
.handle("console", getConsole)
|
||||
.handle("consoleOrgs", listConsoleOrgs)
|
||||
.handle("consoleSwitch", switchConsole)
|
||||
.handle("tool", tool)
|
||||
.handle("toolIDs", toolIDs)
|
||||
.handle("worktree", worktree)
|
||||
.handle("worktreeCreate", worktreeCreate)
|
||||
.handle("worktreeRemove", worktreeRemove)
|
||||
.handle("worktreeReset", worktreeReset)
|
||||
.handle("session", session)
|
||||
.handle("resource", resource)
|
||||
return (
|
||||
handlers
|
||||
.handle("console", getConsole)
|
||||
.handle("consoleOrgs", listConsoleOrgs)
|
||||
.handle("consoleSwitch", switchConsole)
|
||||
.handle("tool", tool)
|
||||
.handle("toolIDs", toolIDs)
|
||||
.handle("worktree", worktree)
|
||||
.handle("worktreeCreate", worktreeCreate)
|
||||
.handle("worktreeRemove", worktreeRemove)
|
||||
.handle("worktreeReset", worktreeReset)
|
||||
// kilocode_change start
|
||||
.handle("worktreeDiff", worktreeDiff)
|
||||
.handle("worktreeDiffSummary", worktreeDiffSummary)
|
||||
.handle("worktreeDiffFile", worktreeDiffFile)
|
||||
// kilocode_change end
|
||||
.handle("session", session)
|
||||
.handle("resource", resource)
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
ShellPayload,
|
||||
SummarizePayload,
|
||||
UpdatePayload,
|
||||
ViewedPayload,
|
||||
} from "../groups/session"
|
||||
|
||||
const mapNotFound = <A, E, R>(self: Effect.Effect<A, E, R>) =>
|
||||
@@ -360,6 +361,14 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
|
||||
return yield* session.updatePart(payload)
|
||||
})
|
||||
|
||||
// kilocode_change start
|
||||
const viewed = Effect.fn("SessionHttpApi.viewed")(function* (ctx: { payload: typeof ViewedPayload.Type }) {
|
||||
const { KiloSessions } = yield* Effect.promise(() => import("@/kilo-sessions/kilo-sessions"))
|
||||
KiloSessions.setViewedSessions({ focused: ctx.payload.focused ?? [], open: ctx.payload.open ?? [] })
|
||||
return true
|
||||
})
|
||||
// kilocode_change end
|
||||
|
||||
return handlers
|
||||
.handle("list", list)
|
||||
.handle("status", status)
|
||||
@@ -388,5 +397,6 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
|
||||
.handle("deleteMessage", deleteMessage)
|
||||
.handle("deletePart", deletePart)
|
||||
.handle("updatePart", updatePart)
|
||||
.handle("viewed", viewed) // kilocode_change
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -69,6 +69,9 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket, opts?: CorsOptions): H
|
||||
app.get(ExperimentalPaths.worktree, (c) => handler(c.req.raw, context))
|
||||
app.post(ExperimentalPaths.worktree, (c) => handler(c.req.raw, context))
|
||||
app.delete(ExperimentalPaths.worktree, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.worktreeDiff, (c) => handler(c.req.raw, context)) // kilocode_change
|
||||
app.get(ExperimentalPaths.worktreeDiffFile, (c) => handler(c.req.raw, context)) // kilocode_change
|
||||
app.get(ExperimentalPaths.worktreeDiffSummary, (c) => handler(c.req.raw, context)) // kilocode_change
|
||||
app.post(ExperimentalPaths.worktreeReset, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.session, (c) => handler(c.req.raw, context))
|
||||
app.get(ExperimentalPaths.resource, (c) => handler(c.req.raw, context))
|
||||
@@ -140,6 +143,7 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket, opts?: CorsOptions): H
|
||||
app.delete(SessionPaths.deleteMessage, (c) => handler(c.req.raw, context))
|
||||
app.delete(SessionPaths.deletePart, (c) => handler(c.req.raw, context))
|
||||
app.patch(SessionPaths.updatePart, (c) => handler(c.req.raw, context))
|
||||
app.post(SessionPaths.viewed, (c) => handler(c.req.raw, context)) // kilocode_change
|
||||
app.post(TuiPaths.appendPrompt, (c) => handler(c.req.raw, context))
|
||||
app.post(TuiPaths.openHelp, (c) => handler(c.req.raw, context))
|
||||
app.post(TuiPaths.openSessions, (c) => handler(c.req.raw, context))
|
||||
|
||||
@@ -62,6 +62,8 @@ import type {
|
||||
GlobalUpgradeResponses,
|
||||
IndexingStatusResponses,
|
||||
InstanceDisposeResponses,
|
||||
KiloAudioTranscriptionsErrors,
|
||||
KiloAudioTranscriptionsResponses,
|
||||
KiloClawChatCredentialsResponses,
|
||||
KiloClawStatusErrors,
|
||||
KiloClawStatusResponses,
|
||||
@@ -85,6 +87,9 @@ import type {
|
||||
KilocodeSessionImportProjectResponses,
|
||||
KilocodeSessionImportSessionErrors,
|
||||
KilocodeSessionImportSessionResponses,
|
||||
KiloFimErrors,
|
||||
KiloFimResponses,
|
||||
KiloModesResponses,
|
||||
KiloNotificationsErrors,
|
||||
KiloNotificationsResponses,
|
||||
KiloOrganizationSetErrors,
|
||||
@@ -211,6 +216,7 @@ import type {
|
||||
SessionUnshareResponses,
|
||||
SessionUpdateErrors,
|
||||
SessionUpdateResponses,
|
||||
SessionViewedResponses,
|
||||
SubtaskPartInput,
|
||||
SuggestionAcceptErrors,
|
||||
SuggestionAcceptResponses,
|
||||
@@ -261,6 +267,12 @@ import type {
|
||||
WorktreeCreateErrors,
|
||||
WorktreeCreateInput,
|
||||
WorktreeCreateResponses,
|
||||
WorktreeDiffErrors,
|
||||
WorktreeDiffFileErrors,
|
||||
WorktreeDiffFileResponses,
|
||||
WorktreeDiffResponses,
|
||||
WorktreeDiffSummaryErrors,
|
||||
WorktreeDiffSummaryResponses,
|
||||
WorktreeListResponses,
|
||||
WorktreeRemoveErrors,
|
||||
WorktreeRemoveInput,
|
||||
@@ -853,6 +865,8 @@ export class Session extends HeyApiClient {
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
projectID?: string
|
||||
worktrees?: "true" | "false"
|
||||
roots?: boolean | "true" | "false"
|
||||
start?: number
|
||||
cursor?: number
|
||||
@@ -869,6 +883,8 @@ export class Session extends HeyApiClient {
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "projectID" },
|
||||
{ in: "query", key: "worktrees" },
|
||||
{ in: "query", key: "roots" },
|
||||
{ in: "query", key: "start" },
|
||||
{ in: "query", key: "cursor" },
|
||||
@@ -1373,6 +1389,104 @@ export class Worktree extends HeyApiClient {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get worktree diff
|
||||
*
|
||||
* Get file diffs for a worktree compared to its base branch. Includes uncommitted changes.
|
||||
*/
|
||||
public diff<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "base" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<WorktreeDiffResponses, WorktreeDiffErrors, ThrowOnError>({
|
||||
url: "/experimental/worktree/diff",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get worktree diff summary
|
||||
*
|
||||
* Get lightweight file diff metadata for a worktree compared to its base branch.
|
||||
*/
|
||||
public diffSummary<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "base" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<WorktreeDiffSummaryResponses, WorktreeDiffSummaryErrors, ThrowOnError>({
|
||||
url: "/experimental/worktree/diff/summary",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get worktree diff detail
|
||||
*
|
||||
* Get full diff contents for one worktree file compared to its base branch.
|
||||
*/
|
||||
public diffFile<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
file: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "base" },
|
||||
{ in: "query", key: "file" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<WorktreeDiffFileResponses, WorktreeDiffFileErrors, ThrowOnError>({
|
||||
url: "/experimental/worktree/diff/file",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Find extends HeyApiClient {
|
||||
@@ -3941,6 +4055,45 @@ export class Session2 extends HeyApiClient {
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set viewed sessions
|
||||
*
|
||||
* Notify the server which sessions the user is currently viewing, or clear all.
|
||||
*/
|
||||
public viewed<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
focused?: Array<string>
|
||||
open?: Array<string>
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "focused" },
|
||||
{ in: "body", key: "open" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<SessionViewedResponses, unknown, ThrowOnError>({
|
||||
url: "/session/viewed",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Part extends HeyApiClient {
|
||||
@@ -4930,6 +5083,58 @@ export class Indexing extends HeyApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class Audio extends HeyApiClient {
|
||||
/**
|
||||
* Speech to text transcription
|
||||
*
|
||||
* Proxy an audio transcription request to the Kilo Gateway
|
||||
*/
|
||||
public transcriptions<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
model?: string
|
||||
input_audio?: {
|
||||
data: string
|
||||
format: string
|
||||
}
|
||||
language?: string
|
||||
temperature?: number
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "model" },
|
||||
{ in: "body", key: "input_audio" },
|
||||
{ in: "body", key: "language" },
|
||||
{ in: "body", key: "temperature" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<
|
||||
KiloAudioTranscriptionsResponses,
|
||||
KiloAudioTranscriptionsErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
url: "/kilo/audio/transcriptions",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Organization extends HeyApiClient {
|
||||
/**
|
||||
* Update Kilo Gateway organization
|
||||
@@ -5146,6 +5351,81 @@ export class Kilo extends HeyApiClient {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get organization custom modes
|
||||
*
|
||||
* Fetch custom modes defined for the current organization
|
||||
*/
|
||||
public modes<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<KiloModesResponses, unknown, ThrowOnError>({
|
||||
url: "/kilo/modes",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* FIM completion
|
||||
*
|
||||
* Proxy a Fill-in-the-Middle completion request to the Kilo Gateway
|
||||
*/
|
||||
public fim<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
prefix?: string
|
||||
suffix?: string
|
||||
model?: string
|
||||
maxTokens?: number
|
||||
temperature?: number
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "prefix" },
|
||||
{ in: "body", key: "suffix" },
|
||||
{ in: "body", key: "model" },
|
||||
{ in: "body", key: "maxTokens" },
|
||||
{ in: "body", key: "temperature" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).sse.post<KiloFimResponses, KiloFimErrors, ThrowOnError>({
|
||||
url: "/kilo/fim",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Kilo notifications
|
||||
*
|
||||
@@ -5212,6 +5492,11 @@ export class Kilo extends HeyApiClient {
|
||||
})
|
||||
}
|
||||
|
||||
private _audio?: Audio
|
||||
get audio(): Audio {
|
||||
return (this._audio ??= new Audio({ client: this.client }))
|
||||
}
|
||||
|
||||
private _organization?: Organization
|
||||
get organization(): Organization {
|
||||
return (this._organization ??= new Organization({ client: this.client }))
|
||||
|
||||
@@ -1465,6 +1465,20 @@ export type WorktreeResetInput = {
|
||||
directory: string
|
||||
}
|
||||
|
||||
export type WorktreeDiffItem = {
|
||||
file: string
|
||||
patch: string
|
||||
additions: number
|
||||
deletions: number
|
||||
status?: "added" | "deleted" | "modified"
|
||||
before: string
|
||||
after: string
|
||||
tracked: boolean
|
||||
generatedLike: boolean
|
||||
summarized: boolean
|
||||
stamp: string
|
||||
}
|
||||
|
||||
export type ProjectSummary = {
|
||||
id: string
|
||||
name?: string
|
||||
@@ -4077,12 +4091,102 @@ export type WorktreeResetResponses = {
|
||||
|
||||
export type WorktreeResetResponse = WorktreeResetResponses[keyof WorktreeResetResponses]
|
||||
|
||||
export type WorktreeDiffData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
}
|
||||
url: "/experimental/worktree/diff"
|
||||
}
|
||||
|
||||
export type WorktreeDiffErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type WorktreeDiffError = WorktreeDiffErrors[keyof WorktreeDiffErrors]
|
||||
|
||||
export type WorktreeDiffResponses = {
|
||||
/**
|
||||
* File diffs
|
||||
*/
|
||||
200: Array<SnapshotFileDiff>
|
||||
}
|
||||
|
||||
export type WorktreeDiffResponse = WorktreeDiffResponses[keyof WorktreeDiffResponses]
|
||||
|
||||
export type WorktreeDiffSummaryData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
}
|
||||
url: "/experimental/worktree/diff/summary"
|
||||
}
|
||||
|
||||
export type WorktreeDiffSummaryErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type WorktreeDiffSummaryError = WorktreeDiffSummaryErrors[keyof WorktreeDiffSummaryErrors]
|
||||
|
||||
export type WorktreeDiffSummaryResponses = {
|
||||
/**
|
||||
* Diff summary items
|
||||
*/
|
||||
200: Array<WorktreeDiffItem>
|
||||
}
|
||||
|
||||
export type WorktreeDiffSummaryResponse = WorktreeDiffSummaryResponses[keyof WorktreeDiffSummaryResponses]
|
||||
|
||||
export type WorktreeDiffFileData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
base?: string
|
||||
file: string
|
||||
}
|
||||
url: "/experimental/worktree/diff/file"
|
||||
}
|
||||
|
||||
export type WorktreeDiffFileErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type WorktreeDiffFileError = WorktreeDiffFileErrors[keyof WorktreeDiffFileErrors]
|
||||
|
||||
export type WorktreeDiffFileResponses = {
|
||||
/**
|
||||
* Diff detail item
|
||||
*/
|
||||
200: WorktreeDiffItem
|
||||
}
|
||||
|
||||
export type WorktreeDiffFileResponse = WorktreeDiffFileResponses[keyof WorktreeDiffFileResponses]
|
||||
|
||||
export type ExperimentalSessionListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
projectID?: string
|
||||
worktrees?: "true" | "false"
|
||||
roots?: boolean | "true" | "false"
|
||||
start?: number
|
||||
cursor?: number
|
||||
@@ -6322,6 +6426,28 @@ export type PartUpdateResponses = {
|
||||
|
||||
export type PartUpdateResponse = PartUpdateResponses[keyof PartUpdateResponses]
|
||||
|
||||
export type SessionViewedData = {
|
||||
body?: {
|
||||
focused?: Array<string>
|
||||
open?: Array<string>
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/session/viewed"
|
||||
}
|
||||
|
||||
export type SessionViewedResponses = {
|
||||
/**
|
||||
* Viewed sessions updated
|
||||
*/
|
||||
200: boolean
|
||||
}
|
||||
|
||||
export type SessionViewedResponse = SessionViewedResponses[keyof SessionViewedResponses]
|
||||
|
||||
export type SyncStartData = {
|
||||
body?: never
|
||||
path?: never
|
||||
@@ -7172,6 +7298,124 @@ export type KiloProfileResponses = {
|
||||
|
||||
export type KiloProfileResponse = KiloProfileResponses[keyof KiloProfileResponses]
|
||||
|
||||
export type KiloModesData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/kilo/modes"
|
||||
}
|
||||
|
||||
export type KiloModesResponses = {
|
||||
/**
|
||||
* Organization modes list
|
||||
*/
|
||||
200: {
|
||||
modes: Array<{
|
||||
id: string
|
||||
organization_id: string
|
||||
name: string
|
||||
slug: string
|
||||
created_by: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
config: {
|
||||
roleDefinition?: string
|
||||
whenToUse?: string
|
||||
description?: string
|
||||
customInstructions?: string
|
||||
groups?: Array<
|
||||
| string
|
||||
| [
|
||||
string,
|
||||
{
|
||||
fileRegex?: string | null
|
||||
description?: string | null
|
||||
},
|
||||
]
|
||||
>
|
||||
}
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export type KiloModesResponse = KiloModesResponses[keyof KiloModesResponses]
|
||||
|
||||
export type KiloFimData = {
|
||||
body?: {
|
||||
prefix: string
|
||||
suffix: string
|
||||
model?: string
|
||||
maxTokens?: number
|
||||
temperature?: number
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/kilo/fim"
|
||||
}
|
||||
|
||||
export type KiloFimErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type KiloFimError = KiloFimErrors[keyof KiloFimErrors]
|
||||
|
||||
export type KiloFimResponses = {
|
||||
/**
|
||||
* Success
|
||||
*/
|
||||
200: string
|
||||
}
|
||||
|
||||
export type KiloFimResponse = KiloFimResponses[keyof KiloFimResponses]
|
||||
|
||||
export type KiloAudioTranscriptionsData = {
|
||||
body?: {
|
||||
model: string
|
||||
input_audio: {
|
||||
data: string
|
||||
format: string
|
||||
}
|
||||
language?: string
|
||||
temperature?: number
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/kilo/audio/transcriptions"
|
||||
}
|
||||
|
||||
export type KiloAudioTranscriptionsErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type KiloAudioTranscriptionsError = KiloAudioTranscriptionsErrors[keyof KiloAudioTranscriptionsErrors]
|
||||
|
||||
export type KiloAudioTranscriptionsResponses = {
|
||||
/**
|
||||
* Transcription response
|
||||
*/
|
||||
200: {
|
||||
text: string
|
||||
usage?: unknown
|
||||
}
|
||||
}
|
||||
|
||||
export type KiloAudioTranscriptionsResponse = KiloAudioTranscriptionsResponses[keyof KiloAudioTranscriptionsResponses]
|
||||
|
||||
export type KiloNotificationsData = {
|
||||
body?: never
|
||||
path?: never
|
||||
|
||||
@@ -1253,6 +1253,208 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/worktree/diff": {
|
||||
"get": {
|
||||
"tags": ["experimental"],
|
||||
"operationId": "worktree.diff",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "File diffs",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/SnapshotFileDiff"
|
||||
},
|
||||
"description": "File diffs"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Get file diffs for a worktree compared to its base branch. Includes uncommitted changes.",
|
||||
"summary": "Get worktree diff",
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.worktree.diff({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/worktree/diff/summary": {
|
||||
"get": {
|
||||
"tags": ["experimental"],
|
||||
"operationId": "worktree.diffSummary",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Diff summary items",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/WorktreeDiffItem"
|
||||
},
|
||||
"description": "Diff summary items"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Get lightweight file diff metadata for a worktree compared to its base branch.",
|
||||
"summary": "Get worktree diff summary",
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.worktree.diffSummary({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/worktree/diff/file": {
|
||||
"get": {
|
||||
"tags": ["experimental"],
|
||||
"operationId": "worktree.diffFile",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "file",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Diff detail item",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/WorktreeDiffItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Get full diff contents for one worktree file compared to its base branch.",
|
||||
"summary": "Get worktree diff detail",
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.worktree.diffFile({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/experimental/session": {
|
||||
"get": {
|
||||
"tags": ["experimental"],
|
||||
@@ -1274,6 +1476,23 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "projectID",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "worktrees",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"enum": ["true", "false"]
|
||||
},
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "roots",
|
||||
"in": "query",
|
||||
@@ -6917,6 +7136,75 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/session/viewed": {
|
||||
"post": {
|
||||
"tags": ["session"],
|
||||
"operationId": "session.viewed",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Viewed sessions updated",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"description": "Viewed sessions updated"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Notify the server which sessions the user is currently viewing, or clear all.",
|
||||
"summary": "Set viewed sessions",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"focused": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"open": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.session.viewed({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/sync/start": {
|
||||
"post": {
|
||||
"tags": ["sync"],
|
||||
@@ -8967,6 +9255,339 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/kilo/modes": {
|
||||
"get": {
|
||||
"tags": ["kilo"],
|
||||
"operationId": "kilo.modes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Organization modes list",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"modes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"slug": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_by": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"roleDefinition": {
|
||||
"type": "string"
|
||||
},
|
||||
"whenToUse": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"customInstructions": {
|
||||
"type": "string"
|
||||
},
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"fileRegex": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"maxItems": 2,
|
||||
"minItems": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"organization_id",
|
||||
"name",
|
||||
"slug",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"config"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["modes"],
|
||||
"additionalProperties": false,
|
||||
"description": "Organization modes list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Fetch custom modes defined for the current organization",
|
||||
"summary": "Get organization custom modes",
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.kilo.modes({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/kilo/fim": {
|
||||
"post": {
|
||||
"tags": ["kilo"],
|
||||
"operationId": "kilo.fim",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"text/event-stream": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Proxy a Fill-in-the-Middle completion request to the Kilo Gateway",
|
||||
"summary": "FIM completion",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"maxTokens": {
|
||||
"type": "number"
|
||||
},
|
||||
"temperature": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["prefix", "suffix"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.kilo.fim({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/kilo/audio/transcriptions": {
|
||||
"post": {
|
||||
"tags": ["kilo"],
|
||||
"operationId": "kilo.audio.transcriptions",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Transcription response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"usage": {}
|
||||
},
|
||||
"required": ["text"],
|
||||
"additionalProperties": false,
|
||||
"description": "Transcription response"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Proxy an audio transcription request to the Kilo Gateway",
|
||||
"summary": "Speech to text transcription",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"input_audio": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"format": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["data", "format"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"temperature": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": ["model", "input_audio"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\n\nconst client = createKiloClient()\nawait client.kilo.audio.transcriptions({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/kilo/notifications": {
|
||||
"get": {
|
||||
"tags": ["kilo"],
|
||||
@@ -15586,6 +16207,60 @@
|
||||
"required": ["directory"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"WorktreeDiffItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string"
|
||||
},
|
||||
"patch": {
|
||||
"type": "string"
|
||||
},
|
||||
"additions": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"deletions": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["added", "deleted", "modified"]
|
||||
},
|
||||
"before": {
|
||||
"type": "string"
|
||||
},
|
||||
"after": {
|
||||
"type": "string"
|
||||
},
|
||||
"tracked": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"generatedLike": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"summarized": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"stamp": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"file",
|
||||
"patch",
|
||||
"additions",
|
||||
"deletions",
|
||||
"before",
|
||||
"after",
|
||||
"tracked",
|
||||
"generatedLike",
|
||||
"summarized",
|
||||
"stamp"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ProjectSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
Reference in New Issue
Block a user