mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-29 03:44:06 +08:00
feat: add /reload action to reboot the instance from disk
Reboots the per-directory instance, reloading config, skills, agents, commands, and MCP prompts changed on disk without restarting the server. Sessions and history are preserved; only the per-directory instance caches are torn down and rebuilt. Server: POST /instance/reload wraps the existing atomic InstanceStore.reload path (the same one project.git.init uses). The rebuild completes before the 200 response, so clients can refetch with no race. Returns 409 ConflictError while a session is actively running. Emits the existing server.instance.disposed SSE event, which the TUI and extension already use to auto-refetch. CLI: /reload palette command calls the endpoint; the TUI already bootstraps on server.instance.disposed. Extension: /reload slash command, a reload button in the task header and settings panel, and a Kilo Code: Reload Config and Skills command palette entry. The handler clears the command cache and reuses reloadAfterAuthChange to re-fetch config, providers, agents, skills, and commands. Reload targets the current session's directory so Agent Manager worktree sessions reload their own worktree instance rather than the workspace root. SDK: regenerate so client.instance.reload is available to external integrations.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@kilocode/cli": minor
|
||||
"kilo-code": minor
|
||||
---
|
||||
|
||||
Add a reload action that reboots the per-directory instance, picking up config, skills, agents, commands, and MCP prompts changed on disk. Sessions and history are preserved. Surfaces: `/reload` in the CLI palette and editor chat, a reload button in the task header and settings panel, the `Kilo Code: Reload Config and Skills` command, and a `POST /instance/reload` HTTP endpoint. The endpoint returns 409 while a session is actively running.
|
||||
@@ -422,6 +422,11 @@
|
||||
"command": "kilo-code.new.takeHeapSnapshot",
|
||||
"title": "Take Heap Snapshot",
|
||||
"category": "Kilo Code"
|
||||
},
|
||||
{
|
||||
"command": "kilo-code.new.reload",
|
||||
"title": "Reload Config and Skills",
|
||||
"category": "Kilo Code"
|
||||
}
|
||||
],
|
||||
"submenus": [
|
||||
|
||||
@@ -1075,6 +1075,9 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
console.error("[Kilo New] KiloProvider: ❌ Retry connection failed:", e),
|
||||
)
|
||||
break
|
||||
case "reload":
|
||||
this.handleReload().catch((e) => console.error("[Kilo New] KiloProvider: Reload failed:", e))
|
||||
break
|
||||
case "openSubAgentViewer":
|
||||
vscode.commands.executeCommand("kilo-code.new.openSubAgentViewer", message.sessionID, message.title)
|
||||
break
|
||||
@@ -3608,6 +3611,36 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
])
|
||||
}
|
||||
|
||||
/** Reload config, skills, agents, and commands from disk by rebooting the instance. */
|
||||
private async handleReload(): Promise<void> {
|
||||
if (!this.client) {
|
||||
console.warn("[Kilo New] handleReload: no client connection")
|
||||
return
|
||||
}
|
||||
const dir = this.getWorkspaceDirectory(this.currentSession?.id)
|
||||
try {
|
||||
await this.client.instance.reload({ directory: dir }, { throwOnError: true })
|
||||
} catch (err: any) {
|
||||
const status = err?.response?.status
|
||||
if (status === 409) {
|
||||
vscode.window.showWarningMessage(
|
||||
"Cannot reload while a session is running. Wait for it to finish or abort it first.",
|
||||
)
|
||||
} else {
|
||||
console.error("[Kilo New] handleReload: reload endpoint failed:", err)
|
||||
vscode.window.showErrorMessage("Reload failed. See extension logs for details.")
|
||||
}
|
||||
return
|
||||
}
|
||||
this.clearCommandsCache()
|
||||
await this.reloadAfterAuthChange()
|
||||
}
|
||||
|
||||
/** Public reload entry point for VS Code commands. */
|
||||
async reload(): Promise<void> {
|
||||
return this.handleReload()
|
||||
}
|
||||
|
||||
private mapSyncEventToWebviewMessage(event: LegacySyncEvent) {
|
||||
switch (event.type) {
|
||||
case "message.updated": {
|
||||
|
||||
@@ -530,6 +530,12 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
registerHeapSnapshot(context, connectionService)
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("kilo-code.new.reload", () => {
|
||||
provider.reload().catch((e) => console.error("[Kilo New] reload command failed:", e))
|
||||
}),
|
||||
)
|
||||
|
||||
// Register code actions (editor context menus, terminal context menus, keyboard shortcuts)
|
||||
registerCodeActions(context, provider, agentManagerProvider)
|
||||
registerTerminalActions(context, provider, agentManagerProvider)
|
||||
|
||||
@@ -212,6 +212,15 @@ export const TaskHeader: Component<TaskHeaderProps> = (props) => {
|
||||
aria-label={language.t("command.session.compact")}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip value={language.t("common.reload")} placement="bottom">
|
||||
<IconButton
|
||||
icon="reset"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
onClick={() => vscode.postMessage({ type: "reload" })}
|
||||
aria-label={language.t("common.reload")}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<Show when={hasMessages()}>
|
||||
<button
|
||||
|
||||
@@ -143,6 +143,14 @@ const Settings: Component<SettingsProps> = (props) => {
|
||||
<Button variant="secondary" size="small" icon="edit" onClick={() => open("global")}>
|
||||
{language.t("settings.openGlobalConfig")}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="small"
|
||||
icon="reset"
|
||||
onClick={() => vscode.postMessage({ type: "reload" })}
|
||||
>
|
||||
{language.t("common.reload")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Settings tabs */}
|
||||
|
||||
@@ -158,6 +158,14 @@ export function useSlashCommand(
|
||||
action: sandbox.action,
|
||||
enabled: sandbox.enabled,
|
||||
},
|
||||
{
|
||||
name: "reload",
|
||||
description: "Reload config, skills, agents, and commands from disk",
|
||||
hints: ["refresh"],
|
||||
action: () => {
|
||||
vscode.postMessage({ type: "reload" })
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
const excluded = () => {
|
||||
|
||||
@@ -1156,6 +1156,7 @@ export const dict = {
|
||||
|
||||
"common.retry": "Retry",
|
||||
"common.refresh": "Refresh",
|
||||
"common.reload": "Reload",
|
||||
|
||||
"profile.title": "Profile",
|
||||
"profile.notLoggedIn": "Not logged in",
|
||||
|
||||
@@ -924,6 +924,10 @@ export interface RetryConnectionRequest {
|
||||
type: "retryConnection"
|
||||
}
|
||||
|
||||
export interface ReloadRequest {
|
||||
type: "reload"
|
||||
}
|
||||
|
||||
// Open a sub-agent session in a read-only editor panel
|
||||
export interface OpenSubAgentViewerRequest {
|
||||
type: "openSubAgentViewer"
|
||||
@@ -1333,6 +1337,7 @@ export type WebviewMessage =
|
||||
| DiffViewerSetBaseBranchRequest
|
||||
| DiffVirtualSetMarkdownRenderRequest
|
||||
| RetryConnectionRequest
|
||||
| ReloadRequest
|
||||
| OpenSubAgentViewerRequest
|
||||
| PreviewImageRequest
|
||||
| SaveImageRequest
|
||||
|
||||
@@ -15,6 +15,7 @@ import KiloSidebarPr from "@/kilocode/plugins/sidebar-pr"
|
||||
import KiloSidebarUsage from "@/kilocode/plugins/sidebar-usage"
|
||||
import KiloSandbox from "@/kilocode/plugins/sandbox"
|
||||
import KiloRemote from "@/kilocode/plugins/remote"
|
||||
import KiloReload from "@/kilocode/plugins/reload"
|
||||
// kilocode_change end
|
||||
import SidebarContext from "../feature-plugins/sidebar/context"
|
||||
import SidebarMcp from "../feature-plugins/sidebar/mcp"
|
||||
@@ -54,6 +55,7 @@ export function internalTuiPlugins(flags: Pick<RuntimeFlags.Info, "experimentalE
|
||||
KiloSidebarUsage, // kilocode_change
|
||||
KiloSandbox, // kilocode_change
|
||||
KiloRemote, // kilocode_change
|
||||
KiloReload, // kilocode_change
|
||||
HomeFooter,
|
||||
HomeTips,
|
||||
SidebarContext,
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { TuiPlugin, TuiPluginModule } from "@kilocode/plugin/tui"
|
||||
|
||||
const id = "internal:reload"
|
||||
|
||||
const tui: TuiPlugin = async (api) => {
|
||||
api.keymap.registerLayer({
|
||||
commands: [
|
||||
{
|
||||
namespace: "palette",
|
||||
name: "app.reload",
|
||||
title: "Reload",
|
||||
desc: "Reload config, skills, agents, and commands from disk",
|
||||
category: "System",
|
||||
slashName: "reload",
|
||||
async run() {
|
||||
try {
|
||||
await api.client.instance.reload({}, { throwOnError: true })
|
||||
api.ui.toast({ message: "Reloaded", variant: "success" })
|
||||
} catch (err) {
|
||||
api.ui.toast({ message: String(err), variant: "error", duration: 5000 })
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const plugin: TuiPluginModule & { id: string } = { id, tui }
|
||||
|
||||
export default plugin
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Authorization } from "@/server/routes/instance/httpapi/middleware/authorization"
|
||||
import { InstanceContextMiddleware } from "@/server/routes/instance/httpapi/middleware/instance-context"
|
||||
import {
|
||||
WorkspaceRoutingMiddleware,
|
||||
WorkspaceRoutingQuery,
|
||||
} from "@/server/routes/instance/httpapi/middleware/workspace-routing"
|
||||
import { described } from "@/server/routes/instance/httpapi/groups/metadata"
|
||||
import { ConflictError } from "@/server/routes/instance/httpapi/errors"
|
||||
import { Schema } from "effect"
|
||||
import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
||||
|
||||
export const ReloadPaths = {
|
||||
reload: "/instance/reload",
|
||||
} as const
|
||||
|
||||
export const InstanceReloadApi = HttpApi.make("instance-reload")
|
||||
.add(
|
||||
HttpApiGroup.make("instance-reload")
|
||||
.add(
|
||||
HttpApiEndpoint.post("reload", ReloadPaths.reload, {
|
||||
query: WorkspaceRoutingQuery,
|
||||
success: described(Schema.Boolean, "Instance reloaded"),
|
||||
error: ConflictError,
|
||||
}).annotateMerge(
|
||||
OpenApi.annotations({
|
||||
identifier: "instance.reload",
|
||||
summary: "Reload instance",
|
||||
description:
|
||||
"Atomically dispose and reboot the current Kilo instance, reloading config, skills, agents, commands, and MCP prompts from disk. Returns 409 if a session is actively running.",
|
||||
}),
|
||||
),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
title: "instance-reload",
|
||||
description: "Kilo instance reload route.",
|
||||
}),
|
||||
)
|
||||
.middleware(InstanceContextMiddleware)
|
||||
.middleware(WorkspaceRoutingMiddleware)
|
||||
.middleware(Authorization),
|
||||
)
|
||||
.annotateMerge(
|
||||
OpenApi.annotations({
|
||||
title: "kilo HttpApi",
|
||||
version: "0.0.1",
|
||||
description: "Kilo HttpApi surface.",
|
||||
}),
|
||||
)
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as InstanceState from "@/effect/instance-state"
|
||||
import { SessionStatus } from "@/session/status"
|
||||
import { ConflictError } from "@/server/routes/instance/httpapi/errors"
|
||||
import { markInstanceForReload } from "@/server/routes/instance/httpapi/lifecycle"
|
||||
import { InstanceHttpApi } from "@/server/routes/instance/httpapi/api"
|
||||
import { Effect } from "effect"
|
||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||
import type { SessionID } from "@/session/schema"
|
||||
|
||||
export function hasBusySession(statuses: Map<SessionID, SessionStatus.Info>): boolean {
|
||||
for (const info of statuses.values()) {
|
||||
if (info.type === "busy") return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const instanceReloadHandlers = HttpApiBuilder.group(InstanceHttpApi, "instance-reload", (handlers) =>
|
||||
Effect.gen(function* () {
|
||||
const status = yield* SessionStatus.Service
|
||||
|
||||
const reload = Effect.fn("InstanceReloadHttpApi.reload")(function* () {
|
||||
const ctx = yield* InstanceState.context
|
||||
if (hasBusySession(yield* status.list())) {
|
||||
return yield* Effect.fail(
|
||||
new ConflictError({
|
||||
message: "Cannot reload while a session is running. Wait for it to finish or abort it first.",
|
||||
}),
|
||||
)
|
||||
}
|
||||
yield* markInstanceForReload(ctx, {
|
||||
directory: ctx.directory,
|
||||
worktree: ctx.worktree,
|
||||
project: ctx.project,
|
||||
})
|
||||
return true
|
||||
})
|
||||
|
||||
return handlers.handle("reload", reload)
|
||||
}),
|
||||
)
|
||||
@@ -15,6 +15,7 @@ import { commitMessageHandlers } from "./handlers/commit-message"
|
||||
import { configConsoleHandlers } from "./handlers/config-console"
|
||||
import { enhancePromptHandlers } from "./handlers/enhance-prompt"
|
||||
import { indexingHandlers } from "./handlers/indexing"
|
||||
import { instanceReloadHandlers } from "./handlers/instance-reload"
|
||||
import { interactiveTerminalHandlers } from "./handlers/interactive-terminal"
|
||||
import { kiloGatewayHandlers } from "./handlers/kilo-gateway"
|
||||
import { kilocodeHandlers } from "./handlers/kilocode"
|
||||
@@ -35,6 +36,7 @@ export const provide = Layer.provide([
|
||||
configConsoleHandlers,
|
||||
enhancePromptHandlers,
|
||||
indexingHandlers,
|
||||
instanceReloadHandlers,
|
||||
interactiveTerminalHandlers,
|
||||
kiloGatewayHandlers,
|
||||
kilocodeHandlers,
|
||||
|
||||
@@ -28,6 +28,7 @@ import { BackgroundProcessApi } from "@/kilocode/server/httpapi/groups/backgroun
|
||||
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 { InstanceReloadApi } from "@/kilocode/server/httpapi/groups/instance-reload"
|
||||
import { InteractiveTerminalApi } from "@/kilocode/server/httpapi/groups/interactive-terminal"
|
||||
import { KiloGatewayApi } from "@/kilocode/server/httpapi/groups/kilo-gateway"
|
||||
import { KilocodeApi } from "@/kilocode/server/httpapi/groups/kilocode"
|
||||
@@ -76,6 +77,7 @@ export const InstanceHttpApi = HttpApi.make("opencode-instance")
|
||||
.addHttpApi(ConfigConsoleApi)
|
||||
.addHttpApi(EnhancePromptApi)
|
||||
.addHttpApi(IndexingApi)
|
||||
.addHttpApi(InstanceReloadApi)
|
||||
.addHttpApi(InteractiveTerminalApi)
|
||||
.addHttpApi(KiloGatewayApi)
|
||||
.addHttpApi(KilocodeApi)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { hasBusySession } from "@/kilocode/server/httpapi/handlers/instance-reload"
|
||||
import type { SessionStatus } from "@/session/status"
|
||||
import { SessionID } from "@/session/schema"
|
||||
|
||||
const entries = (items: [string, SessionStatus.Info][]) =>
|
||||
items.map(([k, v]) => [k as SessionID, v] as [SessionID, SessionStatus.Info])
|
||||
|
||||
describe("instance-reload hasBusySession", () => {
|
||||
it("returns false for an empty map", () => {
|
||||
expect(hasBusySession(new Map(entries([])))).toBe(false)
|
||||
})
|
||||
|
||||
it("returns false when all sessions are idle", () => {
|
||||
expect(
|
||||
hasBusySession(
|
||||
new Map(
|
||||
entries([
|
||||
["s1", { type: "idle" }],
|
||||
["s2", { type: "idle" }],
|
||||
]),
|
||||
),
|
||||
),
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it("returns true when any session is busy", () => {
|
||||
expect(
|
||||
hasBusySession(
|
||||
new Map(
|
||||
entries([
|
||||
["s1", { type: "idle" }],
|
||||
["s2", { type: "busy" }],
|
||||
]),
|
||||
),
|
||||
),
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it("returns true when the only session is busy", () => {
|
||||
expect(hasBusySession(new Map(entries([["s1", { type: "busy" }]])))).toBe(true)
|
||||
})
|
||||
})
|
||||
@@ -134,6 +134,8 @@ import type {
|
||||
IndexingWarningsResponses,
|
||||
InstanceDisposeErrors,
|
||||
InstanceDisposeResponses,
|
||||
InstanceReloadErrors,
|
||||
InstanceReloadResponses,
|
||||
InteractiveTerminalCloseErrors,
|
||||
InteractiveTerminalCloseResponses,
|
||||
InteractiveTerminalGetErrors,
|
||||
@@ -2257,6 +2259,36 @@ export class Instance extends HeyApiClient {
|
||||
...params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload instance
|
||||
*
|
||||
* Atomically dispose and reboot the current Kilo instance, reloading config, skills, agents, commands, and MCP prompts from disk. Returns 409 if a session is actively running.
|
||||
*/
|
||||
public reload<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).post<InstanceReloadResponses, InstanceReloadErrors, ThrowOnError>({
|
||||
url: "/instance/reload",
|
||||
...options,
|
||||
...params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Path extends HeyApiClient {
|
||||
|
||||
@@ -2571,6 +2571,12 @@ export type KiloEmbeddingModelCatalog = {
|
||||
}
|
||||
}
|
||||
|
||||
export type ConflictError = {
|
||||
_tag: "ConflictError"
|
||||
message: string
|
||||
resource?: string
|
||||
}
|
||||
|
||||
export type InteractiveTerminalSnapshot = {
|
||||
info: InteractiveTerminalInfo
|
||||
output: string
|
||||
@@ -10588,6 +10594,38 @@ export type IndexingModelsResponses = {
|
||||
|
||||
export type IndexingModelsResponse = IndexingModelsResponses[keyof IndexingModelsResponses]
|
||||
|
||||
export type InstanceReloadData = {
|
||||
body?: never
|
||||
path?: never
|
||||
query?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
url: "/instance/reload"
|
||||
}
|
||||
|
||||
export type InstanceReloadErrors = {
|
||||
/**
|
||||
* Bad request
|
||||
*/
|
||||
400: BadRequestError
|
||||
/**
|
||||
* ConflictError
|
||||
*/
|
||||
409: ConflictError
|
||||
}
|
||||
|
||||
export type InstanceReloadError = InstanceReloadErrors[keyof InstanceReloadErrors]
|
||||
|
||||
export type InstanceReloadResponses = {
|
||||
/**
|
||||
* Instance reloaded
|
||||
*/
|
||||
200: boolean
|
||||
}
|
||||
|
||||
export type InstanceReloadResponse = InstanceReloadResponses[keyof InstanceReloadResponses]
|
||||
|
||||
export type InteractiveTerminalListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
|
||||
@@ -13085,6 +13085,71 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/instance/reload": {
|
||||
"post": {
|
||||
"tags": ["instance-reload"],
|
||||
"operationId": "instance.reload",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "directory",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "workspace",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Instance reloaded",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"description": "Instance reloaded"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/BadRequestError"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "ConflictError",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ConflictError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Atomically dispose and reboot the current Kilo instance, reloading config, skills, agents, commands, and MCP prompts from disk. Returns 409 if a session is actively running.",
|
||||
"summary": "Reload instance",
|
||||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "js",
|
||||
"source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.instance.reload({\n ...\n})"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/interactive-terminal": {
|
||||
"get": {
|
||||
"tags": ["interactive-terminal"],
|
||||
@@ -27801,6 +27866,23 @@
|
||||
"required": ["defaultModel", "models", "aliases"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ConflictError": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_tag": {
|
||||
"type": "string",
|
||||
"enum": ["ConflictError"]
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["_tag", "message"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"InteractiveTerminalSnapshot": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -36967,6 +37049,10 @@
|
||||
"name": "indexing",
|
||||
"description": "Kilo indexing routes."
|
||||
},
|
||||
{
|
||||
"name": "instance-reload",
|
||||
"description": "Kilo instance reload route."
|
||||
},
|
||||
{
|
||||
"name": "interactive-terminal",
|
||||
"description": "Kilo human-driven interactive terminal routes."
|
||||
|
||||
Reference in New Issue
Block a user