mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-29 03:44:06 +08:00
refactor: fix merge main
This commit is contained in:
@@ -70,12 +70,44 @@ function rect(view: View, x: number, y: number, w: number, h: number) {
|
||||
view.ctx.fillRect(left, top, right - left, bottom - top)
|
||||
}
|
||||
|
||||
function sextant(view: View, mask: number, x: number, y: number, w: number, h: number) {
|
||||
const sw = w / 2
|
||||
const sh = h / 3
|
||||
|
||||
for (const n of [1, 2, 3, 4, 5, 6]) {
|
||||
if (!(mask & (1 << (n - 1)))) continue
|
||||
const dx = n % 2 === 1 ? 0 : sw
|
||||
const dy = Math.floor((n - 1) / 2) * sh
|
||||
rect(view, x + dx, y + dy, sw, sh)
|
||||
}
|
||||
}
|
||||
|
||||
function fill(view: View, cp: number, x: number, y: number, w: number, h: number) {
|
||||
const ew = w / 8
|
||||
const eh = h / 8
|
||||
const hw = w / 2
|
||||
const hh = h / 2
|
||||
|
||||
if (cp === 0x1fb01) {
|
||||
sextant(view, 0b000010, x, y, w, h)
|
||||
return true
|
||||
}
|
||||
|
||||
if (cp === 0x1fb0f) {
|
||||
sextant(view, 0b010000, x, y, w, h)
|
||||
return true
|
||||
}
|
||||
|
||||
if (cp === 0x1fb2c) {
|
||||
sextant(view, 0b101111, x, y, w, h)
|
||||
return true
|
||||
}
|
||||
|
||||
if (cp === 0x1fb3a) {
|
||||
sextant(view, 0b111101, x, y, w, h)
|
||||
return true
|
||||
}
|
||||
|
||||
if (cp >= 0x2581 && cp <= 0x2587) {
|
||||
const n = cp - 0x2580
|
||||
rect(view, x, y + h - eh * n, w, eh * n)
|
||||
@@ -187,9 +219,11 @@ function patch(renderer: Terminal["renderer"]) {
|
||||
view.renderCellText = (cell, x, y, over) => {
|
||||
if (
|
||||
!(cell.flags & CellFlags.INVISIBLE) &&
|
||||
cell.grapheme_len === 0 &&
|
||||
cell.codepoint >= 0x2580 &&
|
||||
cell.codepoint <= 0x259f
|
||||
((cell.codepoint >= 0x2580 && cell.codepoint <= 0x259f) ||
|
||||
cell.codepoint === 0x1fb01 ||
|
||||
cell.codepoint === 0x1fb0f ||
|
||||
cell.codepoint === 0x1fb2c ||
|
||||
cell.codepoint === 0x1fb3a)
|
||||
) {
|
||||
const w = view.metrics.width * cell.width
|
||||
const h = view.metrics.height
|
||||
@@ -244,7 +278,8 @@ export function GhosttyTerminal(props: { query: Query; pty: string; active?: boo
|
||||
cols: 100,
|
||||
rows: 30,
|
||||
cursorBlink: true,
|
||||
fontFamily: "'FiraCode Nerd Font', 'FiraCode Nerd Font Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
|
||||
fontFamily:
|
||||
"'FiraCode Nerd Font', 'FiraCode Nerd Font Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
|
||||
fontSize: Math.max(14, px(host, "--font-size-base", 14)),
|
||||
scrollback: 5000,
|
||||
theme: theme(host),
|
||||
@@ -323,9 +358,7 @@ export function GhosttyTerminal(props: { query: Query; pty: string; active?: boo
|
||||
return (
|
||||
<div class="project-terminal" classList={{ shown: shown() }}>
|
||||
<div ref={host} class="project-terminal-host" />
|
||||
<Show when={failure()}>
|
||||
{(msg) => <div class="project-terminal-error">{msg()}</div>}
|
||||
</Show>
|
||||
<Show when={failure()}>{(msg) => <div class="project-terminal-error">{msg()}</div>}</Show>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ export function resolveThreadDirectory(project?: string, envPWD = process.env.PW
|
||||
const root = envPWD && Filesystem.resolve(envPWD) === real ? Filesystem.resolve(envPWD) : real
|
||||
// kilocode_change end
|
||||
if (project) return Filesystem.resolve(path.isAbsolute(project) ? project : path.join(root, project))
|
||||
return real
|
||||
return real // kilocode_change
|
||||
}
|
||||
|
||||
export const TuiThreadCommand = cmd({
|
||||
@@ -363,7 +363,7 @@ export const TuiThreadCommand = cmd({
|
||||
|
||||
try {
|
||||
await validateSession({
|
||||
url: transport.url,
|
||||
url: transport.url, // kilocode_change
|
||||
sessionID: args.session,
|
||||
directory: cwd,
|
||||
fetch: transport.fetch,
|
||||
@@ -398,9 +398,8 @@ export const TuiThreadCommand = cmd({
|
||||
}
|
||||
// kilocode_change end
|
||||
|
||||
await start({
|
||||
// kilocode_change
|
||||
url: transport.url,
|
||||
await start({ // kilocode_change
|
||||
url: transport.url, // kilocode_change
|
||||
async onSnapshot() {
|
||||
const tui = writeHeapSnapshot("tui.heapsnapshot")
|
||||
const server = await client.call("snapshot", undefined)
|
||||
|
||||
@@ -31,8 +31,14 @@ const LocalInput = Schema.Struct({
|
||||
})
|
||||
|
||||
const normalizeLocal = (input: Schema.Schema.Type<typeof LocalInput>): Schema.Schema.Type<typeof LocalCanonical> => {
|
||||
const { env, environment, ...rest } = input
|
||||
return { ...rest, environment: environment ?? env }
|
||||
const env = input.environment ?? input.env
|
||||
return {
|
||||
type: input.type,
|
||||
command: input.command,
|
||||
...(env === undefined ? {} : { environment: env }),
|
||||
...("enabled" in input ? { enabled: input.enabled } : {}),
|
||||
...("timeout" in input ? { timeout: input.timeout } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
export const Local = LocalInput.pipe(
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
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"
|
||||
import { described } from "@/server/routes/instance/httpapi/groups/metadata"
|
||||
import { Schema } from "effect"
|
||||
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
||||
|
||||
const Scope = Schema.Literals(["global", "project"])
|
||||
const Mode = Schema.Literals(["primary", "subagent", "all"])
|
||||
export const AgentBuilderID = Schema.String
|
||||
const Body = {
|
||||
scope: Schema.optional(Scope),
|
||||
description: Schema.optional(Schema.String),
|
||||
mode: Schema.optional(Mode),
|
||||
model: Schema.optional(Schema.String),
|
||||
color: Schema.optional(Schema.String),
|
||||
steps: Schema.optional(Schema.Number),
|
||||
tools: Schema.optional(Schema.Array(Schema.String)),
|
||||
permission: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
|
||||
prompt: Schema.String,
|
||||
}
|
||||
|
||||
export const AgentBuilderInput = Schema.Struct({ id: AgentBuilderID, ...Body })
|
||||
export const AgentBuilderSaveInput = Schema.Struct({ id: Schema.optional(AgentBuilderID), ...Body })
|
||||
export const AgentBuilderOutput = Schema.Struct({
|
||||
id: AgentBuilderID,
|
||||
scope: Scope,
|
||||
path: Schema.String,
|
||||
markdown: Schema.String,
|
||||
})
|
||||
|
||||
export const AgentBuilderPaths = {
|
||||
preview: "/agent-builder/preview",
|
||||
save: "/agent-builder/:id",
|
||||
} as const
|
||||
|
||||
export const AgentBuilderApi = HttpApi.make("agent-builder")
|
||||
.add(
|
||||
HttpApiGroup.make("agent-builder")
|
||||
.add(
|
||||
HttpApiEndpoint.post("preview", AgentBuilderPaths.preview, {
|
||||
payload: AgentBuilderInput,
|
||||
success: described(AgentBuilderOutput, "Agent markdown preview"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "agentBuilder.preview",
|
||||
summary: "Preview agent markdown",
|
||||
description:
|
||||
"Validate an agent builder payload and return the canonical agent markdown without writing it.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.put("save", AgentBuilderPaths.save, {
|
||||
params: { id: AgentBuilderID },
|
||||
payload: AgentBuilderSaveInput,
|
||||
success: described(AgentBuilderOutput, "Saved agent markdown"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "agentBuilder.save",
|
||||
summary: "Save agent markdown",
|
||||
description: "Save an agent builder payload as a canonical agent markdown file.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(OpenApi.annotations({ title: "agent-builder", description: "Kilo agent builder routes." }))
|
||||
.middleware(InstanceContextMiddleware)
|
||||
.middleware(WorkspaceRoutingMiddleware)
|
||||
.middleware(Authorization),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
title: "kilo HttpApi",
|
||||
version: "0.0.1",
|
||||
description: "Kilo HttpApi surface.",
|
||||
}),
|
||||
)
|
||||
@@ -0,0 +1,188 @@
|
||||
import { Config } from "@/config/config"
|
||||
import { ConfigPlugin } from "@/config/plugin"
|
||||
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"
|
||||
import { described } from "@/server/routes/instance/httpapi/groups/metadata"
|
||||
import { Schema } from "effect"
|
||||
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
||||
|
||||
const Scope = Schema.Literals(["global", "project"])
|
||||
const Origin = Schema.Literals(["project", "global", "system", "default"])
|
||||
const UnknownRecord = Schema.Record(Schema.String, Schema.Unknown)
|
||||
const ModelRef = Schema.Struct({ providerID: Schema.String, modelID: Schema.String })
|
||||
const Resolved = Schema.Struct({
|
||||
key: Schema.String,
|
||||
path: Schema.Array(Schema.String),
|
||||
value: Schema.optional(Schema.Unknown),
|
||||
global: Schema.optional(Schema.Unknown),
|
||||
local: Schema.optional(Schema.Unknown),
|
||||
source: Origin,
|
||||
inherited: Schema.Boolean,
|
||||
overridden: Schema.Boolean,
|
||||
editable: Schema.Boolean,
|
||||
reason: Schema.optional(Schema.String),
|
||||
})
|
||||
const Source = Schema.Struct({
|
||||
order: Schema.Number,
|
||||
kind: Schema.String,
|
||||
scope: Schema.String,
|
||||
label: Schema.String,
|
||||
source: Schema.String,
|
||||
path: Schema.optional(Schema.String),
|
||||
exists: Schema.Boolean,
|
||||
editable: Schema.Boolean,
|
||||
reason: Schema.optional(Schema.String),
|
||||
})
|
||||
|
||||
export const ConfigOverlayQuery = Schema.Struct({ scope: Schema.optional(Scope) })
|
||||
export const ConfigOverlayPatch = Schema.Struct({
|
||||
scope: Schema.optional(Scope),
|
||||
set: Schema.optional(UnknownRecord),
|
||||
unset: Schema.optional(Schema.Array(Schema.Array(Schema.String))),
|
||||
})
|
||||
export const ConfigOverlayResponse = Schema.Struct({
|
||||
scope: Scope,
|
||||
effective: Config.Info,
|
||||
global: Config.Info,
|
||||
project: Config.Info,
|
||||
sources: Schema.Array(Source),
|
||||
targets: Schema.Struct({
|
||||
global: Schema.optional(Schema.String),
|
||||
project: Schema.optional(Schema.String),
|
||||
active: Schema.optional(Schema.String),
|
||||
}),
|
||||
fields: Schema.Record(Schema.String, Resolved),
|
||||
collections: Schema.Record(Schema.String, Schema.Array(Resolved)),
|
||||
}).annotate({ identifier: "ConfigOverlayResponse" })
|
||||
export const ConfigSourcesResponse = Schema.Struct({ sources: Schema.Array(Source) }).annotate({
|
||||
identifier: "ConfigSourcesResponse",
|
||||
})
|
||||
export const ConfigModelStatePatch = Schema.Struct({ favorite: Schema.optional(Schema.Array(ModelRef)) })
|
||||
export const ConfigModelStateResponse = Schema.Struct({
|
||||
model: Schema.Record(Schema.String, ModelRef),
|
||||
recent: Schema.Array(ModelRef),
|
||||
favorite: Schema.Array(ModelRef),
|
||||
variant: Schema.Record(Schema.String, Schema.String),
|
||||
}).annotate({ identifier: "ConfigModelStateResponse" })
|
||||
|
||||
export const TuiConfigQuery = Schema.Struct({ scope: Schema.optional(Scope) })
|
||||
const TuiConfigShape = {
|
||||
$schema: Schema.optional(Schema.String),
|
||||
theme: Schema.optional(Schema.String),
|
||||
keybinds: Schema.optional(Schema.Record(Schema.String, Schema.UndefinedOr(Schema.String))),
|
||||
plugin: Schema.optional(Schema.Array(ConfigPlugin.Spec)),
|
||||
plugin_enabled: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)),
|
||||
scroll_speed: Schema.optional(Schema.Number),
|
||||
scroll_acceleration: Schema.optional(Schema.Struct({ enabled: Schema.Boolean })),
|
||||
diff_style: Schema.optional(Schema.Literals(["auto", "stacked"])),
|
||||
mouse: Schema.optional(Schema.Boolean),
|
||||
}
|
||||
export const TuiConfigResponse = Schema.Struct(TuiConfigShape).annotate({ identifier: "TuiConfigGetResponse" })
|
||||
export const TuiConfigPatch = Schema.Struct(TuiConfigShape)
|
||||
|
||||
export const ConfigConsolePaths = {
|
||||
sources: "/config/sources",
|
||||
effective: "/config/effective",
|
||||
overlay: "/config/overlay",
|
||||
modelState: "/config/model-state",
|
||||
tuiConfig: "/tui/config",
|
||||
} as const
|
||||
|
||||
export const ConfigConsoleApi = HttpApi.make("config-console")
|
||||
.add(
|
||||
HttpApiGroup.make("config-console")
|
||||
.add(
|
||||
HttpApiEndpoint.get("overlay", ConfigConsolePaths.overlay, {
|
||||
query: ConfigOverlayQuery,
|
||||
success: described(ConfigOverlayResponse, "Resolved config overlay"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.overlay",
|
||||
summary: "Get config overlay",
|
||||
description:
|
||||
"Resolve global, project, and effective config values with source metadata for inheritance-aware settings UI.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("sources", ConfigConsolePaths.sources, {
|
||||
success: described(ConfigSourcesResponse, "Config source inventory"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.sources",
|
||||
summary: "List config sources",
|
||||
description: "List config source metadata in load order without exposing config contents or secrets.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("effective", ConfigConsolePaths.effective, {
|
||||
success: described(Config.Info, "Effective config info"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.effective",
|
||||
summary: "Get effective configuration",
|
||||
description: "Retrieve effective config for the current instance directory.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.patch("overlayUpdate", ConfigConsolePaths.overlay, {
|
||||
payload: ConfigOverlayPatch,
|
||||
success: described(Config.Info, "Effective configuration after patch"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.overlayUpdate",
|
||||
summary: "Patch config overlay",
|
||||
description:
|
||||
"Apply a minimal global or project config patch, including unset paths for reverting local overrides.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("modelState", ConfigConsolePaths.modelState, {
|
||||
success: described(ConfigModelStateResponse, "Model state"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.modelState",
|
||||
summary: "Get model state",
|
||||
description: "Retrieve TUI-compatible recent and favorite model selections.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.patch("modelStateUpdate", ConfigConsolePaths.modelState, {
|
||||
payload: ConfigModelStatePatch,
|
||||
success: described(ConfigModelStateResponse, "Updated model state"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "config.modelStateUpdate",
|
||||
summary: "Update model state",
|
||||
description: "Patch TUI-compatible model selections shared with Kilo Console.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.get("tuiConfigGet", ConfigConsolePaths.tuiConfig, {
|
||||
success: described(TuiConfigResponse, "Effective TUI configuration"),
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "tui.config.get",
|
||||
summary: "Get TUI configuration",
|
||||
description: "Retrieve the effective TUI configuration for the current instance directory.",
|
||||
}),
|
||||
),
|
||||
HttpApiEndpoint.patch("tuiConfigUpdate", ConfigConsolePaths.tuiConfig, {
|
||||
query: TuiConfigQuery,
|
||||
payload: TuiConfigPatch,
|
||||
success: described(TuiConfigResponse, "Effective TUI configuration after the update"),
|
||||
error: HttpApiError.BadRequest,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "tui.config.update",
|
||||
summary: "Update TUI configuration",
|
||||
description: "Patch global or project TUI configuration and return the effective TUI configuration.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(OpenApi.annotations({ title: "config-console", description: "Kilo Console config routes." }))
|
||||
.middleware(InstanceContextMiddleware)
|
||||
.middleware(WorkspaceRoutingMiddleware)
|
||||
.middleware(Authorization),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
title: "kilo HttpApi",
|
||||
version: "0.0.1",
|
||||
description: "Kilo HttpApi surface.",
|
||||
}),
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
import * as InstanceState from "@/effect/instance-state"
|
||||
import { AgentBuilder } from "@/kilocode/agent/builder"
|
||||
import { InstanceStore } from "@/project/instance-store"
|
||||
import { InstanceHttpApi } from "@/server/routes/instance/httpapi/api"
|
||||
import { Effect } from "effect"
|
||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||
import { AgentBuilderID, AgentBuilderInput, AgentBuilderSaveInput } from "../groups/agent-builder"
|
||||
|
||||
export const agentBuilderHandlers = HttpApiBuilder.group(InstanceHttpApi, "agent-builder", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const store = yield* InstanceStore.Service
|
||||
|
||||
const preview = Effect.fn("AgentBuilderHttpApi.preview")(function* (ctx: {
|
||||
payload: typeof AgentBuilderInput.Type
|
||||
}) {
|
||||
const instance = yield* InstanceState.context
|
||||
return yield* Effect.promise(() => AgentBuilder.preview(instance, normalize(ctx.payload)))
|
||||
})
|
||||
|
||||
const save = Effect.fn("AgentBuilderHttpApi.save")(function* (ctx: {
|
||||
params: { id: typeof AgentBuilderID.Type }
|
||||
payload: typeof AgentBuilderSaveInput.Type
|
||||
}) {
|
||||
const instance = yield* InstanceState.context
|
||||
const input = normalize({ ...ctx.payload, id: ctx.params.id })
|
||||
const output = yield* Effect.promise(() => AgentBuilder.save(instance, input))
|
||||
yield* store.dispose(instance)
|
||||
return output
|
||||
})
|
||||
|
||||
return handlers.handle("preview", preview).handle("save", save)
|
||||
}),
|
||||
)
|
||||
|
||||
function normalize(input: typeof AgentBuilderInput.Type): AgentBuilder.Input {
|
||||
return {
|
||||
...input,
|
||||
scope: input.scope ?? "project",
|
||||
mode: input.mode ?? "primary",
|
||||
prompt: input.prompt.trim(),
|
||||
tools: input.tools ? [...input.tools] : undefined,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import { Account } from "@/account/account"
|
||||
import { Auth } from "@/auth"
|
||||
import { Config } from "@/config/config"
|
||||
import * as InstanceState from "@/effect/instance-state"
|
||||
import { KilocodeConfigOverlay } from "@/kilocode/config/overlay"
|
||||
import { KilocodeConfigSources } from "@/kilocode/config/sources"
|
||||
import { KilocodeModelState } from "@/kilocode/config/model-state"
|
||||
import { KilocodeTuiConfig } from "@/kilocode/tui/config"
|
||||
import { InstanceHttpApi } from "@/server/routes/instance/httpapi/api"
|
||||
import { Effect, Option } from "effect"
|
||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||
import {
|
||||
ConfigModelStatePatch,
|
||||
ConfigOverlayPatch,
|
||||
ConfigOverlayQuery,
|
||||
TuiConfigPatch,
|
||||
TuiConfigQuery,
|
||||
} from "../groups/config-console"
|
||||
|
||||
export const configConsoleHandlers = HttpApiBuilder.group(InstanceHttpApi, "config-console", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const config = yield* Config.Service
|
||||
const auth = yield* Auth.Service
|
||||
const account = yield* Account.Service
|
||||
|
||||
const overlay = Effect.fn("ConfigConsoleHttpApi.overlay")(function* (ctx: {
|
||||
query: typeof ConfigOverlayQuery.Type
|
||||
}) {
|
||||
const instance = yield* InstanceState.context
|
||||
const all = yield* auth.all().pipe(Effect.orElseSucceed(() => ({})))
|
||||
const active = yield* account.active().pipe(
|
||||
Effect.map(Option.getOrUndefined),
|
||||
Effect.orElseSucceed(() => undefined),
|
||||
)
|
||||
const [base, global, sources] = yield* Effect.all(
|
||||
[
|
||||
config.get(),
|
||||
config.getGlobal(),
|
||||
Effect.promise(() =>
|
||||
KilocodeConfigSources.list({
|
||||
directory: instance.directory,
|
||||
worktree: instance.worktree,
|
||||
auth: all,
|
||||
account: active,
|
||||
}),
|
||||
),
|
||||
],
|
||||
{ concurrency: 3 },
|
||||
)
|
||||
return yield* Effect.promise(() =>
|
||||
KilocodeConfigOverlay.resolve({
|
||||
directory: instance.directory,
|
||||
worktree: instance.worktree,
|
||||
scope: ctx.query.scope ?? "project",
|
||||
effective: base,
|
||||
global,
|
||||
sources: sources.sources,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
const overlayUpdate = Effect.fn("ConfigConsoleHttpApi.overlayUpdate")(function* (ctx: {
|
||||
payload: typeof ConfigOverlayPatch.Type
|
||||
}) {
|
||||
const body = {
|
||||
...ctx.payload,
|
||||
scope: ctx.payload.scope ?? "project",
|
||||
set: ctx.payload.set ? { ...ctx.payload.set } : undefined,
|
||||
unset: ctx.payload.unset?.map((item) => [...item]),
|
||||
}
|
||||
const patch = KilocodeConfigOverlay.patch(body)
|
||||
if (Object.keys(patch).length === 0) {
|
||||
if (body.scope === "global") return yield* config.getGlobal()
|
||||
return yield* config.get()
|
||||
}
|
||||
if (body.scope === "global") return (yield* config.updateGlobal(patch)).info
|
||||
yield* config.update(patch)
|
||||
return yield* config.get()
|
||||
})
|
||||
|
||||
const sources = Effect.fn("ConfigConsoleHttpApi.sources")(function* () {
|
||||
const instance = yield* InstanceState.context
|
||||
const all = yield* auth.all().pipe(Effect.orElseSucceed(() => ({})))
|
||||
const active = yield* account.active().pipe(
|
||||
Effect.map(Option.getOrUndefined),
|
||||
Effect.orElseSucceed(() => undefined),
|
||||
)
|
||||
return yield* Effect.promise(() =>
|
||||
KilocodeConfigSources.list({
|
||||
directory: instance.directory,
|
||||
worktree: instance.worktree,
|
||||
auth: all,
|
||||
account: active,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
const effective = Effect.fn("ConfigConsoleHttpApi.effective")(function* () {
|
||||
return yield* config.get()
|
||||
})
|
||||
|
||||
const modelState = Effect.fn("ConfigConsoleHttpApi.modelState")(function* () {
|
||||
return yield* Effect.promise(() => KilocodeModelState.get())
|
||||
})
|
||||
|
||||
const modelStateUpdate = Effect.fn("ConfigConsoleHttpApi.modelStateUpdate")(function* (ctx: {
|
||||
payload: typeof ConfigModelStatePatch.Type
|
||||
}) {
|
||||
return yield* Effect.promise(() =>
|
||||
KilocodeModelState.update({ favorite: ctx.payload.favorite?.map((item) => ({ ...item })) }),
|
||||
)
|
||||
})
|
||||
|
||||
const tuiConfigGet = Effect.fn("ConfigConsoleHttpApi.tuiConfigGet")(function* () {
|
||||
const instance = yield* InstanceState.context
|
||||
return yield* Effect.promise(() => KilocodeTuiConfig.get({ directory: instance.directory }))
|
||||
})
|
||||
|
||||
const tuiConfigUpdate = Effect.fn("ConfigConsoleHttpApi.tuiConfigUpdate")(function* (ctx: {
|
||||
query: typeof TuiConfigQuery.Type
|
||||
payload: typeof TuiConfigPatch.Type
|
||||
}) {
|
||||
const instance = yield* InstanceState.context
|
||||
const patch = {
|
||||
...ctx.payload,
|
||||
keybinds: ctx.payload.keybinds ? { ...ctx.payload.keybinds } : undefined,
|
||||
plugin: ctx.payload.plugin?.map((item) => {
|
||||
if (!Array.isArray(item)) return item
|
||||
return [item[0], { ...item[1] }] as [string, { readonly [x: string]: unknown }]
|
||||
}),
|
||||
plugin_enabled: ctx.payload.plugin_enabled ? { ...ctx.payload.plugin_enabled } : undefined,
|
||||
}
|
||||
return yield* Effect.promise(() =>
|
||||
KilocodeTuiConfig.update({
|
||||
directory: instance.directory,
|
||||
worktree: instance.worktree,
|
||||
scope: ctx.query.scope ?? "project",
|
||||
patch,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
return handlers
|
||||
.handle("overlay", overlay)
|
||||
.handle("overlayUpdate", overlayUpdate)
|
||||
.handle("sources", sources)
|
||||
.handle("effective", effective)
|
||||
.handle("modelState", modelState)
|
||||
.handle("modelStateUpdate", modelStateUpdate)
|
||||
.handle("tuiConfigGet", tuiConfigGet)
|
||||
.handle("tuiConfigUpdate", tuiConfigUpdate)
|
||||
}),
|
||||
)
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { Context } from "effect"
|
||||
import type { Hono } from "hono"
|
||||
import { AgentBuilderPaths } from "./groups/agent-builder"
|
||||
import { BackgroundProcessPaths } from "./groups/background-process"
|
||||
import { ConfigConsolePaths } from "./groups/config-console"
|
||||
import { IndexingPaths } from "./groups/indexing"
|
||||
import { KiloGatewayPaths } from "./groups/kilo-gateway"
|
||||
import { KilocodePaths } from "./groups/kilocode"
|
||||
@@ -13,12 +15,22 @@ import { TelemetryPaths } from "./groups/telemetry"
|
||||
type Handler = (request: Request, context: Context.Context<unknown>) => Promise<Response>
|
||||
|
||||
export function register(app: Hono, handler: Handler, context: Context.Context<unknown>) {
|
||||
app.post(AgentBuilderPaths.preview, (c) => handler(c.req.raw, context))
|
||||
app.put(AgentBuilderPaths.save, (c) => handler(c.req.raw, context))
|
||||
app.get(BackgroundProcessPaths.list, (c) => handler(c.req.raw, context))
|
||||
app.get(BackgroundProcessPaths.get, (c) => handler(c.req.raw, context))
|
||||
app.get(BackgroundProcessPaths.logs, (c) => handler(c.req.raw, context))
|
||||
app.post(BackgroundProcessPaths.stop, (c) => handler(c.req.raw, context))
|
||||
app.post(BackgroundProcessPaths.restart, (c) => handler(c.req.raw, context))
|
||||
app.post(BackgroundProcessPaths.stopSession, (c) => handler(c.req.raw, context))
|
||||
app.get(ConfigConsolePaths.sources, (c) => handler(c.req.raw, context))
|
||||
app.get(ConfigConsolePaths.effective, (c) => handler(c.req.raw, context))
|
||||
app.get(ConfigConsolePaths.overlay, (c) => handler(c.req.raw, context))
|
||||
app.patch(ConfigConsolePaths.overlay, (c) => handler(c.req.raw, context))
|
||||
app.get(ConfigConsolePaths.modelState, (c) => handler(c.req.raw, context))
|
||||
app.patch(ConfigConsolePaths.modelState, (c) => handler(c.req.raw, context))
|
||||
app.get(ConfigConsolePaths.tuiConfig, (c) => handler(c.req.raw, context))
|
||||
app.patch(ConfigConsolePaths.tuiConfig, (c) => handler(c.req.raw, context))
|
||||
app.post("/permission/allow-everything", (c) => handler(c.req.raw, context))
|
||||
app.post("/enhance-prompt", (c) => handler(c.req.raw, context))
|
||||
app.post("/commit-message", (c) => handler(c.req.raw, context))
|
||||
|
||||
@@ -12,21 +12,18 @@ type Response = {
|
||||
description?: string
|
||||
}
|
||||
|
||||
type Operation = {
|
||||
requestBody?: {
|
||||
content?: Record<string, { schema?: Schema }>
|
||||
}
|
||||
responses?: Record<string, Response>
|
||||
}
|
||||
|
||||
type Spec = {
|
||||
components?: {
|
||||
schemas?: Record<string, Schema>
|
||||
}
|
||||
paths?: Record<
|
||||
string,
|
||||
{
|
||||
post?: {
|
||||
requestBody?: {
|
||||
content?: Record<string, { schema?: Schema }>
|
||||
}
|
||||
responses?: Record<string, Response>
|
||||
}
|
||||
}
|
||||
>
|
||||
paths?: Record<string, Partial<Record<"post" | "put", Operation>>>
|
||||
}
|
||||
|
||||
export function matchLegacyKiloOpenApi(input: Record<string, unknown>) {
|
||||
@@ -40,6 +37,14 @@ export function matchLegacyKiloOpenApi(input: Record<string, unknown>) {
|
||||
if (provider?.additionalProperties && typeof provider.additionalProperties === "object")
|
||||
provider.additionalProperties = nullable(provider.additionalProperties)
|
||||
|
||||
const pty = spec.components?.schemas?.Pty?.properties
|
||||
if (pty?.sessionID) pty.sessionID = nullable(pty.sessionID)
|
||||
|
||||
const update = spec.paths?.["/pty/{ptyID}"]?.put?.requestBody?.content?.["application/json"]?.schema
|
||||
const name = update?.$ref?.replace("#/components/schemas/", "")
|
||||
const fields = name ? spec.components?.schemas?.[name]?.properties : update?.properties
|
||||
if (fields?.sessionID) fields.sessionID = nullable(fields.sessionID)
|
||||
|
||||
const fim = spec.paths?.["/kilo/fim"]?.post?.responses
|
||||
if (!fim) return
|
||||
fim["200"] = {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Layer } from "effect"
|
||||
|
||||
import { agentBuilderHandlers } from "./handlers/agent-builder"
|
||||
import { backgroundProcessHandlers } from "./handlers/background-process"
|
||||
import { commitMessageHandlers } from "./handlers/commit-message"
|
||||
import { configConsoleHandlers } from "./handlers/config-console"
|
||||
import { enhancePromptHandlers } from "./handlers/enhance-prompt"
|
||||
import { indexingHandlers } from "./handlers/indexing"
|
||||
import { kiloGatewayHandlers } from "./handlers/kilo-gateway"
|
||||
@@ -13,8 +15,10 @@ import { suggestionHandlers } from "./handlers/suggestion"
|
||||
import { telemetryHandlers } from "./handlers/telemetry"
|
||||
|
||||
export const provide = Layer.provide([
|
||||
agentBuilderHandlers,
|
||||
backgroundProcessHandlers,
|
||||
commitMessageHandlers,
|
||||
configConsoleHandlers,
|
||||
enhancePromptHandlers,
|
||||
indexingHandlers,
|
||||
kiloGatewayHandlers,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Hono } from "hono"
|
||||
import { describeRoute, resolver, validator } from "hono-openapi"
|
||||
import { AgentBuilder } from "@/kilocode/agent/builder"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Instance } from "@/project/instance"
|
||||
import { InstanceStore } from "@/project/instance-store"
|
||||
import { errors } from "@/server/error"
|
||||
@@ -53,7 +54,7 @@ export const AgentBuilderRoutes = lazy(() =>
|
||||
const body = c.req.valid("json")
|
||||
const input = AgentBuilder.Input.parse({ ...body, id: c.req.valid("param").id })
|
||||
const output = await AgentBuilder.save(context(), input)
|
||||
await InstanceStore.disposeInstance(Instance.current)
|
||||
await AppRuntime.runPromise(InstanceStore.Service.use((svc) => svc.dispose(Instance.current)))
|
||||
return c.json(output)
|
||||
},
|
||||
),
|
||||
|
||||
@@ -185,7 +185,7 @@ export const layer = Layer.effect(
|
||||
const id = PtyID.ascending()
|
||||
// kilocode_change end
|
||||
const resolved = KiloPtySelfCommand.resolve(input) // kilocode_change
|
||||
const command = resolved.command || Shell.preferred(cfg.shell)
|
||||
const command = resolved.command || Shell.preferred(cfg.shell) // kilocode_change
|
||||
const args = resolved.args || [] // kilocode_change
|
||||
if (Shell.login(command)) {
|
||||
args.push("-l") // kilocode_change
|
||||
|
||||
@@ -21,8 +21,10 @@ import { TuiApi } from "./groups/tui"
|
||||
import { WorkspaceApi } from "./groups/workspace"
|
||||
import { V2Api } from "./groups/v2"
|
||||
// kilocode_change start - Kilo HttpApi groups
|
||||
import { AgentBuilderApi } from "@/kilocode/server/httpapi/groups/agent-builder"
|
||||
import { CommitMessageApi } from "@/kilocode/server/httpapi/groups/commit-message"
|
||||
import { BackgroundProcessApi } from "@/kilocode/server/httpapi/groups/background-process"
|
||||
import { ConfigConsoleApi } from "@/kilocode/server/httpapi/groups/config-console"
|
||||
import { EnhancePromptApi } from "@/kilocode/server/httpapi/groups/enhance-prompt"
|
||||
import { IndexingApi } from "@/kilocode/server/httpapi/groups/indexing"
|
||||
import { KiloGatewayApi } from "@/kilocode/server/httpapi/groups/kilo-gateway"
|
||||
@@ -58,8 +60,10 @@ export const InstanceHttpApi = HttpApi.make("opencode-instance")
|
||||
.addHttpApi(TuiApi)
|
||||
.addHttpApi(WorkspaceApi)
|
||||
// kilocode_change start - Kilo HttpApi groups
|
||||
.addHttpApi(AgentBuilderApi)
|
||||
.addHttpApi(BackgroundProcessApi)
|
||||
.addHttpApi(CommitMessageApi)
|
||||
.addHttpApi(ConfigConsoleApi)
|
||||
.addHttpApi(EnhancePromptApi)
|
||||
.addHttpApi(IndexingApi)
|
||||
.addHttpApi(KiloGatewayApi)
|
||||
|
||||
@@ -26,6 +26,7 @@ describe("tui thread", () => {
|
||||
await check(".")
|
||||
})
|
||||
|
||||
// kilocode_change start
|
||||
test("ignores stale PWD after cwd is changed by a process wrapper", async () => {
|
||||
await using root = await tmpdir()
|
||||
const pkg = path.join(root.path, "packages", "opencode")
|
||||
@@ -33,4 +34,5 @@ describe("tui thread", () => {
|
||||
|
||||
expect(resolveThreadDirectory(".", root.path, pkg)).toBe(pkg)
|
||||
})
|
||||
// kilocode_change end
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ type Overlay = {
|
||||
|
||||
afterEach(async () => {
|
||||
;(Global.Path as { config: string }).config = original
|
||||
await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate(true)))
|
||||
await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate()))
|
||||
await disposeAllInstances()
|
||||
await resetDatabase()
|
||||
})
|
||||
@@ -45,7 +45,7 @@ async function config(dir: string, value: unknown) {
|
||||
}
|
||||
|
||||
async function invalidate() {
|
||||
await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate(true)))
|
||||
await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate()))
|
||||
}
|
||||
|
||||
describe("config overlay routes", () => {
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
import { client } from "./client.gen.js"
|
||||
import { buildClientParams, type Client, type Options as Options2, type TDataShape } from "./client/index.js"
|
||||
import type {
|
||||
AgentBuilderPreviewErrors,
|
||||
AgentBuilderPreviewResponses,
|
||||
AgentBuilderSaveErrors,
|
||||
AgentBuilderSaveResponses,
|
||||
AgentPartInput,
|
||||
AppAgentsResponses,
|
||||
AppLogErrors,
|
||||
@@ -26,9 +30,15 @@ import type {
|
||||
CommandListResponses,
|
||||
CommitMessageGenerateErrors,
|
||||
CommitMessageGenerateResponses,
|
||||
Config as Config3,
|
||||
Config as Config4,
|
||||
ConfigEffectiveResponses,
|
||||
ConfigGetResponses,
|
||||
ConfigModelStateResponses,
|
||||
ConfigModelStateUpdateResponses,
|
||||
ConfigOverlayResponses,
|
||||
ConfigOverlayUpdateResponses,
|
||||
ConfigProvidersResponses,
|
||||
ConfigSourcesResponses,
|
||||
ConfigUpdateErrors,
|
||||
ConfigUpdateResponses,
|
||||
ConfigWarningsResponses,
|
||||
@@ -254,6 +264,9 @@ import type {
|
||||
TuiAppendPromptErrors,
|
||||
TuiAppendPromptResponses,
|
||||
TuiClearPromptResponses,
|
||||
TuiConfigGetResponses,
|
||||
TuiConfigUpdateErrors,
|
||||
TuiConfigUpdateResponses,
|
||||
TuiControlNextResponses,
|
||||
TuiControlResponseResponses,
|
||||
TuiExecuteCommandErrors,
|
||||
@@ -526,7 +539,7 @@ export class Config extends HeyApiClient {
|
||||
*/
|
||||
public update<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
config?: Config3
|
||||
config?: Config4
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
@@ -683,7 +696,7 @@ export class Config2 extends HeyApiClient {
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
config?: Config3
|
||||
config?: Config4
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
@@ -770,6 +783,211 @@ export class Config2 extends HeyApiClient {
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config overlay
|
||||
*
|
||||
* Resolve global, project, and effective config values with source metadata for inheritance-aware settings UI.
|
||||
*/
|
||||
public overlay<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
scope?: "global" | "project"
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "scope" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).get<ConfigOverlayResponses, unknown, ThrowOnError>({
|
||||
url: "/config/overlay",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch config overlay
|
||||
*
|
||||
* Apply a minimal global or project config patch, including unset paths for reverting local overrides.
|
||||
*/
|
||||
public overlayUpdate<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
scope?: "global" | "project"
|
||||
set?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
unset?: Array<Array<string>>
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "scope" },
|
||||
{ in: "body", key: "set" },
|
||||
{ in: "body", key: "unset" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).patch<ConfigOverlayUpdateResponses, unknown, ThrowOnError>({
|
||||
url: "/config/overlay",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List config sources
|
||||
*
|
||||
* List config source metadata in load order without exposing config contents or secrets.
|
||||
*/
|
||||
public sources<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<ConfigSourcesResponses, unknown, ThrowOnError>({
|
||||
url: "/config/sources",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get effective configuration
|
||||
*
|
||||
* Retrieve effective config for the current instance directory.
|
||||
*/
|
||||
public effective<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<ConfigEffectiveResponses, unknown, ThrowOnError>({
|
||||
url: "/config/effective",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model state
|
||||
*
|
||||
* Retrieve TUI-compatible recent and favorite model selections.
|
||||
*/
|
||||
public modelState<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<ConfigModelStateResponses, unknown, ThrowOnError>({
|
||||
url: "/config/model-state",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update model state
|
||||
*
|
||||
* Patch TUI-compatible model selections shared with Kilo Console.
|
||||
*/
|
||||
public modelStateUpdate<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
favorite?: Array<{
|
||||
providerID: string
|
||||
modelID: string
|
||||
}>
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "favorite" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).patch<ConfigModelStateUpdateResponses, unknown, ThrowOnError>({
|
||||
url: "/config/model-state",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Console extends HeyApiClient {
|
||||
@@ -2639,7 +2857,7 @@ export class Pty extends HeyApiClient {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
title?: string
|
||||
sessionID?: string
|
||||
sessionID?: string | null
|
||||
size?: {
|
||||
rows: number
|
||||
cols: number
|
||||
@@ -4748,6 +4966,107 @@ export class Control extends HeyApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class Config3 extends HeyApiClient {
|
||||
/**
|
||||
* Get TUI configuration
|
||||
*
|
||||
* Retrieve the effective TUI configuration for the current instance directory.
|
||||
*/
|
||||
public get<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<TuiConfigGetResponses, unknown, ThrowOnError>({
|
||||
url: "/tui/config",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update TUI configuration
|
||||
*
|
||||
* Patch global or project TUI configuration and return the effective TUI configuration.
|
||||
*/
|
||||
public update<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
scope?: "global" | "project"
|
||||
$schema?: string
|
||||
theme?: string
|
||||
keybinds?: {
|
||||
[key: string]: string
|
||||
}
|
||||
plugin?: Array<
|
||||
| string
|
||||
| [
|
||||
string,
|
||||
{
|
||||
[key: string]: unknown
|
||||
},
|
||||
]
|
||||
>
|
||||
plugin_enabled?: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
scroll_acceleration?: {
|
||||
enabled: boolean
|
||||
}
|
||||
diff_style?: "auto" | "stacked"
|
||||
mouse?: boolean
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "query", key: "scope" },
|
||||
{ in: "body", key: "$schema" },
|
||||
{ in: "body", key: "theme" },
|
||||
{ in: "body", key: "keybinds" },
|
||||
{ in: "body", key: "plugin" },
|
||||
{ in: "body", key: "plugin_enabled" },
|
||||
{ in: "body", key: "scroll_speed" },
|
||||
{ in: "body", key: "scroll_acceleration" },
|
||||
{ in: "body", key: "diff_style" },
|
||||
{ in: "body", key: "mouse" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).patch<TuiConfigUpdateResponses, TuiConfigUpdateErrors, ThrowOnError>({
|
||||
url: "/tui/config",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Tui extends HeyApiClient {
|
||||
/**
|
||||
* Append TUI prompt
|
||||
@@ -5124,6 +5443,139 @@ export class Tui extends HeyApiClient {
|
||||
get control(): Control {
|
||||
return (this._control ??= new Control({ client: this.client }))
|
||||
}
|
||||
|
||||
private _config?: Config3
|
||||
get config(): Config3 {
|
||||
return (this._config ??= new Config3({ client: this.client }))
|
||||
}
|
||||
}
|
||||
|
||||
export class AgentBuilder extends HeyApiClient {
|
||||
/**
|
||||
* Preview agent markdown
|
||||
*
|
||||
* Validate an agent builder payload and return the canonical agent markdown without writing it.
|
||||
*/
|
||||
public preview<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
id?: string
|
||||
scope?: "global" | "project"
|
||||
description?: string
|
||||
mode?: "primary" | "subagent" | "all"
|
||||
model?: string
|
||||
color?: string
|
||||
steps?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
tools?: Array<string>
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
prompt?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{ in: "body", key: "id" },
|
||||
{ in: "body", key: "scope" },
|
||||
{ in: "body", key: "description" },
|
||||
{ in: "body", key: "mode" },
|
||||
{ in: "body", key: "model" },
|
||||
{ in: "body", key: "color" },
|
||||
{ in: "body", key: "steps" },
|
||||
{ in: "body", key: "tools" },
|
||||
{ in: "body", key: "permission" },
|
||||
{ in: "body", key: "prompt" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<AgentBuilderPreviewResponses, AgentBuilderPreviewErrors, ThrowOnError>(
|
||||
{
|
||||
url: "/agent-builder/preview",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Save agent markdown
|
||||
*
|
||||
* Save an agent builder payload as a canonical agent markdown file.
|
||||
*/
|
||||
public save<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
path_id: string
|
||||
directory?: string
|
||||
workspace?: string
|
||||
body_id?: string
|
||||
scope?: "global" | "project"
|
||||
description?: string
|
||||
mode?: "primary" | "subagent" | "all"
|
||||
model?: string
|
||||
color?: string
|
||||
steps?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
tools?: Array<string>
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
prompt?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{
|
||||
in: "path",
|
||||
key: "path_id",
|
||||
map: "id",
|
||||
},
|
||||
{ in: "query", key: "directory" },
|
||||
{ in: "query", key: "workspace" },
|
||||
{
|
||||
in: "body",
|
||||
key: "body_id",
|
||||
map: "id",
|
||||
},
|
||||
{ in: "body", key: "scope" },
|
||||
{ in: "body", key: "description" },
|
||||
{ in: "body", key: "mode" },
|
||||
{ in: "body", key: "model" },
|
||||
{ in: "body", key: "color" },
|
||||
{ in: "body", key: "steps" },
|
||||
{ in: "body", key: "tools" },
|
||||
{ in: "body", key: "permission" },
|
||||
{ in: "body", key: "prompt" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).put<AgentBuilderSaveResponses, AgentBuilderSaveErrors, ThrowOnError>({
|
||||
url: "/agent-builder/{id}",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class BackgroundProcess extends HeyApiClient {
|
||||
@@ -6974,6 +7426,11 @@ export class KiloClient extends HeyApiClient {
|
||||
return (this._tui ??= new Tui({ client: this.client }))
|
||||
}
|
||||
|
||||
private _agentBuilder?: AgentBuilder
|
||||
get agentBuilder(): AgentBuilder {
|
||||
return (this._agentBuilder ??= new AgentBuilder({ client: this.client }))
|
||||
}
|
||||
|
||||
private _backgroundProcess?: BackgroundProcess
|
||||
get backgroundProcess(): BackgroundProcess {
|
||||
return (this._backgroundProcess ??= new BackgroundProcess({ client: this.client }))
|
||||
|
||||
@@ -438,7 +438,7 @@ export type Pty = {
|
||||
cwd: string
|
||||
status: "running" | "exited"
|
||||
pid: number
|
||||
sessionID?: string
|
||||
sessionID?: string | null
|
||||
}
|
||||
|
||||
export type OutputFormatText = {
|
||||
@@ -1985,6 +1985,117 @@ export type BackgroundProcessLogs = {
|
||||
output: string
|
||||
}
|
||||
|
||||
export type ConfigOverlayResponse = {
|
||||
scope: "global" | "project"
|
||||
effective: Config
|
||||
global: Config
|
||||
project: Config
|
||||
sources: Array<{
|
||||
order: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
kind: string
|
||||
scope: string
|
||||
label: string
|
||||
source: string
|
||||
path?: string
|
||||
exists: boolean
|
||||
editable: boolean
|
||||
reason?: string
|
||||
}>
|
||||
targets: {
|
||||
global?: string
|
||||
project?: string
|
||||
active?: string
|
||||
}
|
||||
fields: {
|
||||
[key: string]: {
|
||||
key: string
|
||||
path: Array<string>
|
||||
value?: unknown
|
||||
global?: unknown
|
||||
local?: unknown
|
||||
source: "project" | "global" | "system" | "default"
|
||||
inherited: boolean
|
||||
overridden: boolean
|
||||
editable: boolean
|
||||
reason?: string
|
||||
}
|
||||
}
|
||||
collections: {
|
||||
[key: string]: Array<{
|
||||
key: string
|
||||
path: Array<string>
|
||||
value?: unknown
|
||||
global?: unknown
|
||||
local?: unknown
|
||||
source: "project" | "global" | "system" | "default"
|
||||
inherited: boolean
|
||||
overridden: boolean
|
||||
editable: boolean
|
||||
reason?: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export type ConfigSourcesResponse = {
|
||||
sources: Array<{
|
||||
order: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
kind: string
|
||||
scope: string
|
||||
label: string
|
||||
source: string
|
||||
path?: string
|
||||
exists: boolean
|
||||
editable: boolean
|
||||
reason?: string
|
||||
}>
|
||||
}
|
||||
|
||||
export type ConfigModelStateResponse = {
|
||||
model: {
|
||||
[key: string]: {
|
||||
providerID: string
|
||||
modelID: string
|
||||
}
|
||||
}
|
||||
recent: Array<{
|
||||
providerID: string
|
||||
modelID: string
|
||||
}>
|
||||
favorite: Array<{
|
||||
providerID: string
|
||||
modelID: string
|
||||
}>
|
||||
variant: {
|
||||
[key: string]: string
|
||||
}
|
||||
}
|
||||
|
||||
export type TuiConfigGetResponse = {
|
||||
$schema?: string
|
||||
theme?: string
|
||||
keybinds?: {
|
||||
[key: string]: string
|
||||
}
|
||||
plugin?: Array<
|
||||
| string
|
||||
| [
|
||||
string,
|
||||
{
|
||||
[key: string]: unknown
|
||||
},
|
||||
]
|
||||
>
|
||||
plugin_enabled?: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
scroll_acceleration?: {
|
||||
enabled: boolean
|
||||
}
|
||||
diff_style?: "auto" | "stacked"
|
||||
mouse?: boolean
|
||||
}
|
||||
|
||||
export type EffectHttpApiErrorUnauthorized = {
|
||||
_tag: "Unauthorized"
|
||||
}
|
||||
@@ -5211,7 +5322,7 @@ export type PtyGetResponse = PtyGetResponses[keyof PtyGetResponses]
|
||||
export type PtyUpdateData = {
|
||||
body?: {
|
||||
title?: string
|
||||
sessionID?: string
|
||||
sessionID?: string | null
|
||||
size?: {
|
||||
rows: number
|
||||
cols: number
|
||||
@@ -7395,6 +7506,100 @@ export type ExperimentalWorkspaceWarpResponses = {
|
||||
export type ExperimentalWorkspaceWarpResponse =
|
||||
ExperimentalWorkspaceWarpResponses[keyof ExperimentalWorkspaceWarpResponses]
|
||||
|
||||
export type AgentBuilderPreviewData = {
|
||||
body?: {
|
||||
id: string
|
||||
scope?: "global" | "project"
|
||||
description?: string
|
||||
mode?: "primary" | "subagent" | "all"
|
||||
model?: string
|
||||
color?: string
|
||||
steps?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
tools?: Array<string>
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
prompt: string
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/agent-builder/preview"
|
||||
}
|
||||
|
||||
export type AgentBuilderPreviewErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type AgentBuilderPreviewError = AgentBuilderPreviewErrors[keyof AgentBuilderPreviewErrors]
|
||||
|
||||
export type AgentBuilderPreviewResponses = {
|
||||
/**
|
||||
* Agent markdown preview
|
||||
*/
|
||||
200: {
|
||||
id: string
|
||||
scope: "global" | "project"
|
||||
path: string
|
||||
markdown: string
|
||||
}
|
||||
}
|
||||
|
||||
export type AgentBuilderPreviewResponse = AgentBuilderPreviewResponses[keyof AgentBuilderPreviewResponses]
|
||||
|
||||
export type AgentBuilderSaveData = {
|
||||
body?: {
|
||||
id?: string
|
||||
scope?: "global" | "project"
|
||||
description?: string
|
||||
mode?: "primary" | "subagent" | "all"
|
||||
model?: string
|
||||
color?: string
|
||||
steps?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
tools?: Array<string>
|
||||
permission?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
prompt: string
|
||||
}
|
||||
path: {
|
||||
id: string
|
||||
}
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/agent-builder/{id}"
|
||||
}
|
||||
|
||||
export type AgentBuilderSaveErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type AgentBuilderSaveError = AgentBuilderSaveErrors[keyof AgentBuilderSaveErrors]
|
||||
|
||||
export type AgentBuilderSaveResponses = {
|
||||
/**
|
||||
* Saved agent markdown
|
||||
*/
|
||||
200: {
|
||||
id: string
|
||||
scope: "global" | "project"
|
||||
path: string
|
||||
markdown: string
|
||||
}
|
||||
}
|
||||
|
||||
export type AgentBuilderSaveResponse = AgentBuilderSaveResponses[keyof AgentBuilderSaveResponses]
|
||||
|
||||
export type BackgroundProcessListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
@@ -7594,6 +7799,204 @@ export type CommitMessageGenerateResponses = {
|
||||
|
||||
export type CommitMessageGenerateResponse = CommitMessageGenerateResponses[keyof CommitMessageGenerateResponses]
|
||||
|
||||
export type ConfigOverlayData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
scope?: "global" | "project"
|
||||
}
|
||||
url: "/config/overlay"
|
||||
}
|
||||
|
||||
export type ConfigOverlayResponses = {
|
||||
/**
|
||||
* Resolved config overlay
|
||||
*/
|
||||
200: ConfigOverlayResponse
|
||||
}
|
||||
|
||||
export type ConfigOverlayResponse2 = ConfigOverlayResponses[keyof ConfigOverlayResponses]
|
||||
|
||||
export type ConfigOverlayUpdateData = {
|
||||
body?: {
|
||||
scope?: "global" | "project"
|
||||
set?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
unset?: Array<Array<string>>
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/config/overlay"
|
||||
}
|
||||
|
||||
export type ConfigOverlayUpdateResponses = {
|
||||
/**
|
||||
* Effective configuration after patch
|
||||
*/
|
||||
200: Config
|
||||
}
|
||||
|
||||
export type ConfigOverlayUpdateResponse = ConfigOverlayUpdateResponses[keyof ConfigOverlayUpdateResponses]
|
||||
|
||||
export type ConfigSourcesData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/config/sources"
|
||||
}
|
||||
|
||||
export type ConfigSourcesResponses = {
|
||||
/**
|
||||
* Config source inventory
|
||||
*/
|
||||
200: ConfigSourcesResponse
|
||||
}
|
||||
|
||||
export type ConfigSourcesResponse2 = ConfigSourcesResponses[keyof ConfigSourcesResponses]
|
||||
|
||||
export type ConfigEffectiveData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/config/effective"
|
||||
}
|
||||
|
||||
export type ConfigEffectiveResponses = {
|
||||
/**
|
||||
* Effective config info
|
||||
*/
|
||||
200: Config
|
||||
}
|
||||
|
||||
export type ConfigEffectiveResponse = ConfigEffectiveResponses[keyof ConfigEffectiveResponses]
|
||||
|
||||
export type ConfigModelStateData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/config/model-state"
|
||||
}
|
||||
|
||||
export type ConfigModelStateResponses = {
|
||||
/**
|
||||
* Model state
|
||||
*/
|
||||
200: ConfigModelStateResponse
|
||||
}
|
||||
|
||||
export type ConfigModelStateResponse2 = ConfigModelStateResponses[keyof ConfigModelStateResponses]
|
||||
|
||||
export type ConfigModelStateUpdateData = {
|
||||
body?: {
|
||||
favorite?: Array<{
|
||||
providerID: string
|
||||
modelID: string
|
||||
}>
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/config/model-state"
|
||||
}
|
||||
|
||||
export type ConfigModelStateUpdateResponses = {
|
||||
/**
|
||||
* Updated model state
|
||||
*/
|
||||
200: ConfigModelStateResponse
|
||||
}
|
||||
|
||||
export type ConfigModelStateUpdateResponse = ConfigModelStateUpdateResponses[keyof ConfigModelStateUpdateResponses]
|
||||
|
||||
export type TuiConfigGetData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/tui/config"
|
||||
}
|
||||
|
||||
export type TuiConfigGetResponses = {
|
||||
/**
|
||||
* Effective TUI configuration
|
||||
*/
|
||||
200: TuiConfigGetResponse
|
||||
}
|
||||
|
||||
export type TuiConfigGetResponse2 = TuiConfigGetResponses[keyof TuiConfigGetResponses]
|
||||
|
||||
export type TuiConfigUpdateData = {
|
||||
body?: {
|
||||
$schema?: string
|
||||
theme?: string
|
||||
keybinds?: {
|
||||
[key: string]: string
|
||||
}
|
||||
plugin?: Array<
|
||||
| string
|
||||
| [
|
||||
string,
|
||||
{
|
||||
[key: string]: unknown
|
||||
},
|
||||
]
|
||||
>
|
||||
plugin_enabled?: {
|
||||
[key: string]: boolean
|
||||
}
|
||||
scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN"
|
||||
scroll_acceleration?: {
|
||||
enabled: boolean
|
||||
}
|
||||
diff_style?: "auto" | "stacked"
|
||||
mouse?: boolean
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
scope?: "global" | "project"
|
||||
}
|
||||
url: "/tui/config"
|
||||
}
|
||||
|
||||
export type TuiConfigUpdateErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
}
|
||||
|
||||
export type TuiConfigUpdateError = TuiConfigUpdateErrors[keyof TuiConfigUpdateErrors]
|
||||
|
||||
export type TuiConfigUpdateResponses = {
|
||||
/**
|
||||
* Effective TUI configuration after the update
|
||||
*/
|
||||
200: TuiConfigGetResponse
|
||||
}
|
||||
|
||||
export type TuiConfigUpdateResponse = TuiConfigUpdateResponses[keyof TuiConfigUpdateResponses]
|
||||
|
||||
export type EnhancePromptEnhanceData = {
|
||||
body?: {
|
||||
/**
|
||||
|
||||
+1218
-2
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user