diff --git a/packages/core/src/credential.ts b/packages/core/src/credential.ts index 1a64284202..276223d216 100644 --- a/packages/core/src/credential.ts +++ b/packages/core/src/credential.ts @@ -12,6 +12,7 @@ import { FSUtil } from "./fs-util" import { Global } from "./global" import { DataMigrationTable } from "./data-migration.sql" import path from "path" +import { parse as parseKiloAccounts } from "./kilocode/credential-migration" // kilocode_change export const ID = Schema.String.pipe( Schema.brand("Credential.ID"), @@ -106,6 +107,62 @@ export const legacyImportLayer = Layer.effectDiscard( const { db } = yield* Database.Service const fs = yield* FSUtil.Service const global = yield* Global.Service + // kilocode_change start - preserve Kilo's multi-account JSON stores before the upstream auth.json fallback + const kiloName = "credential.kilo-account-json" + if (!(yield* db.select().from(DataMigrationTable).where(eq(DataMigrationTable.name, kiloName)).get())) { + const current = yield* fs.readJson(path.join(global.data, "account.json")).pipe(Effect.option) + const prior = yield* fs.readJson(path.join(global.data, "auth-v2.json")).pipe(Effect.option) + const raw = Option.isSome(current) ? current.value : Option.getOrUndefined(prior) + const values = parseKiloAccounts(raw) + if (values.length > 0) { + yield* db.transaction((tx) => + Effect.gen(function* () { + const existing = new Set( + (yield* tx.select({ connectorID: CredentialTable.connector_id }).from(CredentialTable).all()).map( + (item) => item.connectorID, + ), + ) + for (const item of values) { + const connector = ConnectorSchema.ID.make(item.connectorID.replace(/\/+$/, "")) + if (existing.has(connector)) continue + const value: Value = + item.credential.type === "api" + ? new Key({ + type: "key", + key: item.credential.key, + metadata: item.credential.metadata, + }) + : new OAuth({ + type: "oauth", + refresh: item.credential.refresh, + access: item.credential.access, + expires: item.credential.expires, + metadata: { + ...(item.credential.accountId ? { accountID: item.credential.accountId } : {}), + ...(item.credential.enterpriseUrl ? { enterpriseURL: item.credential.enterpriseUrl } : {}), + }, + }) + yield* tx.insert(CredentialTable).values({ + id: ID.create(), + connector_id: connector, + method_id: ConnectorSchema.MethodID.make( + item.credential.type === "api" + ? "api-key" + : connector === ConnectorSchema.ID.make("openai") + ? "chatgpt-browser" + : "oauth", + ), + label: item.label, + value, + active: item.active, + }) + } + yield* tx.insert(DataMigrationTable).values({ name: kiloName, time_completed: Date.now() }).run() + }), + ) + } + } + // kilocode_change end const name = "credential.auth-json" if (yield* db.select().from(DataMigrationTable).where(eq(DataMigrationTable.name, name)).get()) return const raw = yield* fs.readJson(path.join(global.data, "auth.json")).pipe(Effect.option) diff --git a/packages/core/src/kilocode/credential-migration.ts b/packages/core/src/kilocode/credential-migration.ts new file mode 100644 index 0000000000..387c9dce0f --- /dev/null +++ b/packages/core/src/kilocode/credential-migration.ts @@ -0,0 +1,48 @@ +import { Option, Schema } from "effect" +import { NonNegativeInt } from "../schema" + +const OAuth = Schema.Struct({ + type: Schema.Literal("oauth"), + refresh: Schema.String, + access: Schema.String, + expires: NonNegativeInt, + accountId: Schema.optional(Schema.String), + enterpriseUrl: Schema.optional(Schema.String), +}) + +const Key = Schema.Struct({ + type: Schema.Literal("api"), + key: Schema.String, + metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)), +}) + +const Account = Schema.Struct({ + id: Schema.String, + serviceID: Schema.String, + description: Schema.String, + credential: Schema.Union([OAuth, Key]), +}) + +const Store = Schema.Struct({ + version: Schema.Literal(2), + accounts: Schema.Record(Schema.String, Account), + active: Schema.Record(Schema.String, Schema.String), +}) + +export function parse(input: unknown) { + const decoded = Schema.decodeUnknownOption(Store)(input) + if (Option.isNone(decoded)) return [] + const first = new Set() + return Object.values(decoded.value.accounts).map((account) => { + const fallback = !first.has(account.serviceID) + first.add(account.serviceID) + return { + connectorID: account.serviceID, + label: account.description, + credential: account.credential, + active: decoded.value.active[account.serviceID] + ? decoded.value.active[account.serviceID] === account.id + : fallback, + } + }) +} diff --git a/packages/core/src/util/log.ts b/packages/core/src/util/log.ts new file mode 100644 index 0000000000..fc341f09c0 --- /dev/null +++ b/packages/core/src/util/log.ts @@ -0,0 +1,232 @@ +export * as Log from "./log" + +import path from "path" +import { existsSync, writeFileSync } from "fs" // kilocode_change +import fs from "fs/promises" +import * as Global from "../global" +import { Schema } from "effect" +import { Glob } from "./glob" +import { createStream } from "rotating-file-stream" // kilocode_change +import { KILO_RUN_ID } from "./opencode-process" // kilocode_change + +export const Level = Schema.Literals(["DEBUG", "INFO", "WARN", "ERROR"]).annotate({ + identifier: "LogLevel", + description: "Log level", +}) +export type Level = Schema.Schema.Type + +const levelPriority: Record = { + DEBUG: 0, + INFO: 1, + WARN: 2, + ERROR: 3, +} +const keep = 10 +const initializedRunID = "KILO_LOG_INITIALIZED_RUN_ID" + +let level: Level = "INFO" + +function shouldLog(input: Level): boolean { + return levelPriority[input] >= levelPriority[level] +} + +export type Logger = { + debug(message?: any, extra?: Record): void + info(message?: any, extra?: Record): void + error(message?: any, extra?: Record): void + warn(message?: any, extra?: Record): void + tag(key: string, value: string): Logger + clone(): Logger + time( + message: string, + extra?: Record, + ): { + stop(): void + [Symbol.dispose](): void + } +} + +const loggers = new Map() + +export const Default = create({ service: "default" }) + +export interface Options { + print: boolean + dev?: boolean + level?: Level +} + +let logpath = "" +export function file() { + return logpath +} +const stderr = (msg: any) => { + process.stderr.write(msg) + return msg.length +} +let write = stderr +let stream: ReturnType | undefined // kilocode_change + +export async function init(options: Options) { + if (options.level) level = options.level + void cleanup(Global.Path.log) + // kilocode_change start - initialize one rotating stream and truncate dev.log once per Kilo run + if (stream) { + const active = stream + stream = undefined + await new Promise((resolve) => active.end(resolve)) + } + if (options.print) { + write = stderr + return + } + logpath = path.join( + Global.Path.log, + options.dev ? "dev.log" : new Date().toISOString().split(".")[0].replace(/:/g, "") + ".log", + ) + const run = process.env[KILO_RUN_ID] + if (!options.dev || !run || process.env[initializedRunID] !== run) { + await fs.truncate(logpath).catch(() => {}) + if (options.dev && run) process.env[initializedRunID] = run + } + const dir = path.dirname(logpath) + const active = createStream(path.basename(logpath), { + size: "50M", + maxFiles: 10, + history: ".log-history", + path: dir, + }) + stream = active + active.on("rotation", () => { + if (!existsSync(dir)) return + + try { + // RATIONALE: If current log path was deleted while stream still holds the fd, + // rotating-file-stream will try to rename a missing path and emit ENOENT. + writeFileSync(logpath, "", { flag: "wx" }) + } catch (err) { + if (typeof err === "object" && err && "code" in err && err.code === "EEXIST") return + + const msg = err instanceof Error ? err.message : String(err) + process.stderr.write("log stream warning: " + msg + "\n") + } + }) + active.on("error", (err: Error) => { + process.stderr.write("log stream error: " + err.message + "\n") + }) + active.on("warning", (err: Error) => { + process.stderr.write("log stream warning: " + err.message + "\n") + }) + write = (msg: any) => { + active.write(msg) + return msg.length + } + // kilocode_change end +} + +async function cleanup(dir: string) { + const files = ( + await Glob.scan("????-??-??T??????.log", { + cwd: dir, + absolute: false, + include: "file", + }).catch(() => []) + ) + .filter((file) => path.basename(file) === file) + .sort() + if (files.length <= keep) return + + const doomed = files.slice(0, -keep) + await Promise.all(doomed.map((file) => fs.unlink(path.join(dir, file)).catch(() => {}))) +} + +function formatError(error: Error, depth = 0): string { + const result = error.message + return error.cause instanceof Error && depth < 10 + ? result + " Caused by: " + formatError(error.cause, depth + 1) + : result +} + +let last = Date.now() +export function create(tags?: Record) { + tags = tags || {} + + const service = tags["service"] + if (service && typeof service === "string") { + const cached = loggers.get(service) + if (cached) { + return cached + } + } + + function build(message: any, extra?: Record) { + const prefix = Object.entries({ + ...tags, + ...extra, + }) + .filter(([_, value]) => value !== undefined && value !== null) + .map(([key, value]) => { + const prefix = `${key}=` + if (value instanceof Error) return prefix + formatError(value) + if (typeof value === "object") return prefix + JSON.stringify(value) + return prefix + value + }) + .join(" ") + const next = new Date() + const diff = next.getTime() - last + last = next.getTime() + return [next.toISOString().split(".")[0], "+" + diff + "ms", prefix, message].filter(Boolean).join(" ") + "\n" + } + const result: Logger = { + debug(message?: any, extra?: Record) { + if (shouldLog("DEBUG")) { + write("DEBUG " + build(message, extra)) + } + }, + info(message?: any, extra?: Record) { + if (shouldLog("INFO")) { + write("INFO " + build(message, extra)) + } + }, + error(message?: any, extra?: Record) { + if (shouldLog("ERROR")) { + write("ERROR " + build(message, extra)) + } + }, + warn(message?: any, extra?: Record) { + if (shouldLog("WARN")) { + write("WARN " + build(message, extra)) + } + }, + tag(key: string, value: string) { + if (tags) tags[key] = value + return result + }, + clone() { + return create({ ...tags }) + }, + time(message: string, extra?: Record) { + const now = Date.now() + result.info(message, { status: "started", ...extra }) + function stop() { + result.info(message, { + status: "completed", + duration: Date.now() - now, + ...extra, + }) + } + return { + stop, + [Symbol.dispose]() { + stop() + }, + } + }, + } + + if (service && typeof service === "string") { + loggers.set(service, result) + } + + return result +} diff --git a/packages/core/src/util/opencode-process.ts b/packages/core/src/util/opencode-process.ts new file mode 100644 index 0000000000..a7ac0a89ef --- /dev/null +++ b/packages/core/src/util/opencode-process.ts @@ -0,0 +1,24 @@ +export const KILO_RUN_ID = "KILO_RUN_ID" +export const KILO_PROCESS_ROLE = "KILO_PROCESS_ROLE" + +export function ensureRunID() { + return (process.env[KILO_RUN_ID] ??= crypto.randomUUID()) +} + +export function ensureProcessRole(fallback: "main" | "worker") { + return (process.env[KILO_PROCESS_ROLE] ??= fallback) +} + +export function ensureProcessMetadata(fallback: "main" | "worker") { + return { + runID: ensureRunID(), + processRole: ensureProcessRole(fallback), + } +} + +export function sanitizedProcessEnv(overrides?: Record) { + const env = Object.fromEntries( + Object.entries(process.env).filter((entry): entry is [string, string] => entry[1] !== undefined), + ) + return overrides ? Object.assign(env, overrides) : env +} diff --git a/packages/core/test/kilocode/account-auth-v2-migration.test.ts b/packages/core/test/kilocode/account-auth-v2-migration.test.ts index 8b7206b032..9620d612a3 100644 --- a/packages/core/test/kilocode/account-auth-v2-migration.test.ts +++ b/packages/core/test/kilocode/account-auth-v2-migration.test.ts @@ -1,7 +1,9 @@ import path from "path" import { describe, expect } from "bun:test" import { Effect, Layer } from "effect" -import { Auth } from "@opencode-ai/core/auth" +import { Connector } from "@opencode-ai/core/connector" +import { Credential } from "@opencode-ai/core/credential" +import { Database } from "@opencode-ai/core/database/database" import { EventV2 } from "@opencode-ai/core/event" import { FSUtil } from "@opencode-ai/core/fs-util" import { Global } from "@opencode-ai/core/global" @@ -9,11 +11,17 @@ import { tmpdir } from "../fixture/tmpdir" import { it } from "../lib/effect" function layer(dir: string) { - return Auth.layer.pipe( + const database = Database.layerFromPath(path.join(dir, "credential.db")).pipe(Layer.fresh) + const importer = Credential.legacyImportLayer.pipe( + Layer.provide(database), Layer.provide(FSUtil.defaultLayer), - Layer.provideMerge(EventV2.defaultLayer), Layer.provide(Global.layerWith({ data: dir })), ) + return Credential.layer.pipe( + Layer.provide(database), + Layer.provide(EventV2.defaultLayer), + Layer.provideMerge(importer), + ) } const auth = Effect.acquireRelease( @@ -29,7 +37,7 @@ const auth = Effect.acquireRelease( }), ) -describe("Auth auth-v2 migration", () => { +describe("Credential auth-v2 migration", () => { it.live("preserves multiple accounts, active selection, and Kilo organization", () => Effect.acquireRelease( Effect.promise(() => tmpdir()), @@ -72,22 +80,20 @@ describe("Auth auth-v2 migration", () => { yield* Effect.promise(() => Bun.write(path.join(tmp.path, "auth-v2.json"), JSON.stringify(store))) const result = yield* Effect.gen(function* () { - const accounts = yield* Auth.Service + const credentials = yield* Credential.Service return { - all: yield* accounts.all(), - active: yield* accounts.active(Auth.ServiceID.make("kilo")), + all: yield* credentials.all(), + active: yield* credentials.active(Connector.ID.make("kilo")), } }).pipe(Effect.provide(layer(tmp.path))) - expect(result.all.map((item) => String(item.id))).toEqual(["acc_first", "acc_second"]) - expect(String(result.active?.id)).toBe("acc_second") - expect(result.active?.credential.type).toBe("oauth") - if (result.active?.credential.type === "oauth") { - expect(result.active.credential.access).toBe("access-second") - expect(result.active.credential.accountId).toBe("org-second") + expect(result.all.map((item) => item.label)).toEqual(["first", "second"]) + expect(result.active?.label).toBe("second") + expect(result.active?.value.type).toBe("oauth") + if (result.active?.value.type === "oauth") { + expect(result.active.value.access).toBe("access-second") + expect(result.active.value.metadata?.accountID).toBe("org-second") } - const saved = yield* Effect.promise(() => Bun.file(path.join(tmp.path, "account.json")).json()) - expect(saved).toEqual(store) }), ), ), diff --git a/packages/core/test/plugin/provider-kilo.test.ts b/packages/core/test/plugin/provider-kilo.test.ts index 253a1e6eb4..a14c78821a 100644 --- a/packages/core/test/plugin/provider-kilo.test.ts +++ b/packages/core/test/plugin/provider-kilo.test.ts @@ -1,6 +1,7 @@ import { describe, expect } from "bun:test" import { Effect } from "effect" import { Catalog } from "@opencode-ai/core/catalog" +import { Credential } from "@opencode-ai/core/credential" import { PluginV2 } from "@opencode-ai/core/plugin" import { ProviderPlugins } from "@opencode-ai/core/plugin/provider" import { KiloPlugin } from "@opencode-ai/core/plugin/provider/kilo" @@ -150,7 +151,7 @@ describe("KiloPlugin", () => { const transform = yield* catalog.transform() yield* transform((catalog) => { const item = provider("kilo", { - enabled: { via: "account", service: "kilo" }, + enabled: { via: "credential", credentialID: Credential.ID.make("cred_kilo") }, request: { headers: {}, body: { apiKey: "authenticated-token", kilocodeOrganizationId: "authenticated-org" }, @@ -163,7 +164,7 @@ describe("KiloPlugin", () => { }) const result = yield* catalog.provider.get(ProviderV2.ID.make("kilo")) - expect(result.enabled).toEqual({ via: "account", service: "kilo" }) + expect(result.enabled).toEqual({ via: "credential", credentialID: Credential.ID.make("cred_kilo") }) expect(result.request.body.kilocodeToken).toBe("authenticated-token") expect(result.request.body.kilocodeOrganizationId).toBe("environment-org") }), diff --git a/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md b/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md index f8729d480f..8a2d4178c2 100644 --- a/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md +++ b/packages/kilo-docs/pages/code-with-ai/platforms/cli-reference.md @@ -29,7 +29,7 @@ Options: manage MCP (Model Context Protocol) servers Commands: - kilo mcp add add an MCP server + kilo mcp add [name] add an MCP server kilo mcp list list MCP servers and their status [aliases: ls] kilo mcp auth [name] authenticate with an OAuth-enabled MCP server kilo mcp logout [name] remove OAuth credentials for an MCP server @@ -45,9 +45,15 @@ Options: ``` add an MCP server +Positionals: + name name of the MCP server [string] + Options: --help Show help [boolean] --version Show version number [boolean] + --url URL for a remote MCP server [string] + --env environment variable for a local MCP server (KEY=VALUE) [array] + --header HTTP header for a remote MCP server (KEY=VALUE) [array] ``` ### kilo mcp list @@ -289,7 +295,6 @@ Options: ripgrep debugging utilities Commands: - kilo debug rg tree show file tree using ripgrep kilo debug rg files list files using ripgrep kilo debug rg search search file contents using ripgrep @@ -298,17 +303,6 @@ Options: --version Show version number [boolean] ``` -### kilo debug rg tree - -``` -show file tree using ripgrep - -Options: - --help Show help [boolean] - --version Show version number [boolean] - --limit [number] -``` - ### kilo debug rg files ``` @@ -346,7 +340,6 @@ Commands: kilo debug file read read file contents as JSON kilo debug file list list files in a directory kilo debug file search search files by query - kilo debug file tree [dir] show directory tree Options: --help Show help [boolean] @@ -392,19 +385,6 @@ Options: --version Show version number [boolean] ``` -### kilo debug file tree - -``` -show directory tree - -Positionals: - dir Directory to tree [string] [default: "."] - -Options: - --help Show help [boolean] - --version Show version number [boolean] -``` - ### kilo debug scrap ``` @@ -547,9 +527,9 @@ Options: manage AI providers and credentials Commands: - kilo auth list list providers and credentials [aliases: ls] - kilo auth login [url] log in to a provider - kilo auth logout log out from a configured provider + kilo auth list list providers and credentials [aliases: ls] + kilo auth login [url] log in to a provider + kilo auth logout [provider] log out from a configured provider Options: --help Show help [boolean] @@ -586,6 +566,9 @@ Options: ``` log out from a configured provider +Positionals: + provider provider id or name to log out from [string] + Options: --help Show help [boolean] --version Show version number [boolean] diff --git a/packages/opencode/src/agent/agent.ts b/packages/opencode/src/agent/agent.ts index f2db608c74..3df8e1e6f6 100644 --- a/packages/opencode/src/agent/agent.ts +++ b/packages/opencode/src/agent/agent.ts @@ -29,9 +29,8 @@ import * as OtelTracer from "@effect/opentelemetry/Tracer" import { AbsolutePath, type DeepMutable } from "@opencode-ai/core/schema" import * as KiloAgent from "@/kilocode/agent" // kilocode_change import { RuntimeFlags } from "@/effect/runtime-flags" -import { Reference as ReferenceV1 } from "@/reference/reference" // kilocode_change -import { ConfigReference } from "@/config/reference" // kilocode_change import * as AgentRequirements from "@/kilocode/agent-requirements" // kilocode_change +import * as KiloReference from "@/kilocode/reference" // kilocode_change import { MCP } from "@/mcp" // kilocode_change import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" @@ -114,398 +113,398 @@ export const layer = Layer.effect( const locations = yield* LocationServiceMap const state = yield* InstanceState.make( - Effect.fn("Agent.state")(function* (ctx) { - const cfg = yield* config.get() - const skillDirs = yield* skill.dirs() - // kilocode_change start - include global config dirs so agents can read them without prompting - const referenceDirs = yield* Effect.gen(function* () { + Effect.fn("Agent.state")(function* (ctx) { + const cfg = yield* config.get() + const skillDirs = yield* skill.dirs() + // kilocode_change start - include global config dirs so agents can read them without prompting + const referenceDirs = yield* Effect.gen(function* () { yield* (yield* PluginBoot.Service).wait() return (yield* (yield* Reference.Service).list()).map((reference) => reference.path) }).pipe(Effect.provide(locations.get(Location.Ref.make({ directory: AbsolutePath.make(ctx.directory) })))) const whitelistedDirs = [ - Truncate.GLOB, - path.join(Global.Path.tmp, "*"), - ...skillDirs.map((dir) => path.join(dir, "*")), - path.join(Global.Path.config, "*"), + Truncate.GLOB, + path.join(Global.Path.tmp, "*"), + ...skillDirs.map((dir) => path.join(dir, "*")), + path.join(Global.Path.config, "*"), ...KilocodePaths.globalDirs().map((dir) => path.join(dir, "*")), - ...referenceDirs.map((dir) => path.join(dir, "*")), + ...referenceDirs.map((dir) => path.join(dir, "*")), ] - // kilocode_change end - const readonlyExternalDirectory = { - "*": "ask", - ...Object.fromEntries(whitelistedDirs.map((dir) => [dir, "allow"])), - } satisfies Record - - const baseDefaults = Permission.fromConfig({ - // kilocode_change - "*": "allow", - doom_loop: "ask", - external_directory: { + // kilocode_change end + const readonlyExternalDirectory = { "*": "ask", ...Object.fromEntries(whitelistedDirs.map((dir) => [dir, "allow"])), - }, - suggest: "deny", // kilocode_change - question: "deny", - interactive_terminal: "deny", // kilocode_change - human-driven tools are primary-agent only - plan_enter: "deny", - plan_exit: "deny", - repo_clone: "deny", // kilocode_change - repo_overview: "deny", // kilocode_change - // mirrors github.com/github/gitignore Node.gitignore pattern for .env files - read: { + } satisfies Record + + const baseDefaults = Permission.fromConfig({ + // kilocode_change "*": "allow", - "*.env": "ask", - "*.env.*": "ask", - "*.env.example": "allow", - }, - }) + doom_loop: "ask", + external_directory: { + "*": "ask", + ...Object.fromEntries(whitelistedDirs.map((dir) => [dir, "allow"])), + }, + suggest: "deny", // kilocode_change + question: "deny", + interactive_terminal: "deny", // kilocode_change - human-driven tools are primary-agent only + plan_enter: "deny", + plan_exit: "deny", + repo_clone: "deny", // kilocode_change + repo_overview: "deny", // kilocode_change + // mirrors github.com/github/gitignore Node.gitignore pattern for .env files + read: { + "*": "allow", + "*.env": "ask", + "*.env.*": "ask", + "*.env.example": "allow", + }, + }) - // kilocode_change start - patch defaults with bash allowlist and recall permission - const kilo = KiloAgent.prepare(cfg) - const defaults = Permission.merge(baseDefaults, kilo.defaultsPatch) - // kilocode_change end - - const user = Permission.fromConfig(cfg.permission ?? {}) - - const agents: Record = { - build: { - name: "build", - description: "The default agent. Executes tools based on configured permissions.", - options: {}, - permission: Permission.merge( - defaults, - Permission.fromConfig({ - question: "allow", - interactive_terminal: "allow", // kilocode_change - suggest: "allow", // kilocode_change - plan_enter: "allow", - }), - user, - ), - mode: "primary", - native: true, - }, - plan: { - name: "plan", - description: "Plan mode. Disallows all edit tools.", - options: {}, - permission: Permission.merge( - defaults, - Permission.fromConfig({ - question: "allow", - plan_exit: "allow", - task: { - general: "deny", - }, - external_directory: { - [path.join(Global.Path.data, "plans", "*")]: "allow", - }, - edit: { - "*": "deny", - [path.join(".opencode", "plans", "*.md")]: "allow", - [path.relative(ctx.worktree, path.join(Global.Path.data, path.join("plans", "*.md")))]: "allow", - }, - }), - user, - ), - mode: "primary", - native: true, - }, - general: { - name: "general", - description: `General-purpose agent for researching complex questions and executing multi-step tasks. Use this agent to execute multiple units of work in parallel.`, - permission: Permission.merge( - defaults, - Permission.fromConfig({ - todowrite: "deny", - }), - user, - ), - options: {}, - mode: "subagent", - native: true, - }, - explore: { - name: "explore", - permission: Permission.merge( - defaults, - Permission.fromConfig({ - "*": "deny", - grep: "allow", - glob: "allow", - list: "allow", - bash: "allow", - webfetch: "allow", - websearch: "allow", - read: "allow", - external_directory: readonlyExternalDirectory, - }), - user, - ), - description: `Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.`, - prompt: PROMPT_EXPLORE, - options: {}, - mode: "subagent", - native: true, - }, - // kilocode_change start - retain Kilo's opt-in repository research agent - ...(flags.experimentalScout - ? { - scout: { - name: "scout", - permission: Permission.merge( - defaults, - Permission.fromConfig({ - "*": "deny", - grep: "allow", - glob: "allow", - webfetch: "allow", - websearch: "allow", - read: "allow", - repo_clone: "allow", - repo_overview: "allow", - external_directory: { - ...readonlyExternalDirectory, - [path.join(Global.Path.repos, "*")]: "allow", - }, - }), - user, - ), - description: `Docs and dependency-source specialist. Use this when you need to inspect external documentation, clone dependency repositories into the managed cache, and research library implementation details without modifying the user's workspace.`, - prompt: PROMPT_SCOUT, - options: {}, - mode: "subagent" as const, - native: true, - }, - } - : {}), + // kilocode_change start - patch defaults with bash allowlist and recall permission + const kilo = KiloAgent.prepare(cfg) + const defaults = Permission.merge(baseDefaults, kilo.defaultsPatch) // kilocode_change end - compaction: { - name: "compaction", - mode: "primary", - native: true, - hidden: true, - prompt: PROMPT_COMPACTION, - permission: Permission.merge( - defaults, - user, - Permission.fromConfig({ - "*": "deny", - }), - ), - options: {}, - }, - title: { - name: "title", - mode: "primary", - options: {}, - native: true, - hidden: true, - temperature: 0.5, - permission: Permission.merge( - defaults, - user, - Permission.fromConfig({ - "*": "deny", - }), - ), - prompt: PROMPT_TITLE, - }, - summary: { - name: "summary", - mode: "primary", - options: {}, - native: true, - hidden: true, - permission: Permission.merge( - defaults, - user, - Permission.fromConfig({ - "*": "deny", - }), - ), - prompt: PROMPT_SUMMARY, - }, - } - // kilocode_change start - rename build→code, add debug/orchestrator/ask, patch plan/explore - KiloAgent.patchAgents(agents, defaults, user, cfg, kilo, ctx.worktree, whitelistedDirs) + const user = Permission.fromConfig(cfg.permission ?? {}) - const agentConfigs = KiloAgent.preprocessConfig(cfg.agent ?? {}) - for (const [key, value] of Object.entries(agentConfigs)) { - // kilocode_change end - if (value.disable) { - delete agents[key] - continue - } - let item = agents[key] - if (!item) - item = agents[key] = { - name: key, - mode: "all", - permission: Permission.merge(defaults, user), + const agents: Record = { + build: { + name: "build", + description: "The default agent. Executes tools based on configured permissions.", options: {}, - native: false, - } - if (value.model) item.model = Provider.parseModel(value.model) - item.variant = value.variant ?? item.variant - item.prompt = value.prompt ?? item.prompt - item.description = value.description ?? item.description - item.temperature = value.temperature ?? item.temperature - item.topP = value.top_p ?? item.topP - item.mode = value.mode ?? item.mode - item.color = value.color ?? item.color - item.hidden = value.hidden ?? item.hidden - item.name = value.name ?? item.name - item.steps = value.steps ?? item.steps - // kilocode_change start - carry metadata as typed fields, never as provider options - item.displayName = value.displayName ?? item.displayName - item.source = value.source ?? item.source - item.requirements = value.requirements ?? item.requirements - // kilocode_change end - item.options = mergeDeep(item.options, value.options ?? {}) - item.permission = Permission.merge(item.permission, Permission.fromConfig(value.permission ?? {})) - KiloAgent.processConfigItem(item) // kilocode_change - populate displayName from options - } + permission: Permission.merge( + defaults, + Permission.fromConfig({ + question: "allow", + interactive_terminal: "allow", // kilocode_change + suggest: "allow", // kilocode_change + plan_enter: "allow", + }), + user, + ), + mode: "primary", + native: true, + }, + plan: { + name: "plan", + description: "Plan mode. Disallows all edit tools.", + options: {}, + permission: Permission.merge( + defaults, + Permission.fromConfig({ + question: "allow", + plan_exit: "allow", + task: { + general: "deny", + }, + external_directory: { + [path.join(Global.Path.data, "plans", "*")]: "allow", + }, + edit: { + "*": "deny", + [path.join(".opencode", "plans", "*.md")]: "allow", + [path.relative(ctx.worktree, path.join(Global.Path.data, path.join("plans", "*.md")))]: "allow", + }, + }), + user, + ), + mode: "primary", + native: true, + }, + general: { + name: "general", + description: `General-purpose agent for researching complex questions and executing multi-step tasks. Use this agent to execute multiple units of work in parallel.`, + permission: Permission.merge( + defaults, + Permission.fromConfig({ + todowrite: "deny", + }), + user, + ), + options: {}, + mode: "subagent", + native: true, + }, + explore: { + name: "explore", + permission: Permission.merge( + defaults, + Permission.fromConfig({ + "*": "deny", + grep: "allow", + glob: "allow", + list: "allow", + bash: "allow", + webfetch: "allow", + websearch: "allow", + read: "allow", + external_directory: readonlyExternalDirectory, + }), + user, + ), + description: `Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.`, + prompt: PROMPT_EXPLORE, + options: {}, + mode: "subagent", + native: true, + }, + // kilocode_change start - retain Kilo's opt-in repository research agent + ...(flags.experimentalScout + ? { + scout: { + name: "scout", + permission: Permission.merge( + defaults, + Permission.fromConfig({ + "*": "deny", + grep: "allow", + glob: "allow", + webfetch: "allow", + websearch: "allow", + read: "allow", + repo_clone: "allow", + repo_overview: "allow", + external_directory: { + ...readonlyExternalDirectory, + [path.join(Global.Path.repos, "*")]: "allow", + }, + }), + user, + ), + description: `Docs and dependency-source specialist. Use this when you need to inspect external documentation, clone dependency repositories into the managed cache, and research library implementation details without modifying the user's workspace.`, + prompt: PROMPT_SCOUT, + options: {}, + mode: "subagent" as const, + native: true, + }, + } + : {}), + // kilocode_change end + compaction: { + name: "compaction", + mode: "primary", + native: true, + hidden: true, + prompt: PROMPT_COMPACTION, + permission: Permission.merge( + defaults, + user, + Permission.fromConfig({ + "*": "deny", + }), + ), + options: {}, + }, + title: { + name: "title", + mode: "primary", + options: {}, + native: true, + hidden: true, + temperature: 0.5, + permission: Permission.merge( + defaults, + user, + Permission.fromConfig({ + "*": "deny", + }), + ), + prompt: PROMPT_TITLE, + }, + summary: { + name: "summary", + mode: "primary", + options: {}, + native: true, + hidden: true, + permission: Permission.merge( + defaults, + user, + Permission.fromConfig({ + "*": "deny", + }), + ), + prompt: PROMPT_SUMMARY, + }, + } + + // kilocode_change start - rename build→code, add debug/orchestrator/ask, patch plan/explore + KiloAgent.patchAgents(agents, defaults, user, cfg, kilo, ctx.worktree, whitelistedDirs) + + const agentConfigs = KiloAgent.preprocessConfig(cfg.agent ?? {}) + for (const [key, value] of Object.entries(agentConfigs)) { + // kilocode_change end + if (value.disable) { + delete agents[key] + continue + } + let item = agents[key] + if (!item) + item = agents[key] = { + name: key, + mode: "all", + permission: Permission.merge(defaults, user), + options: {}, + native: false, + } + if (value.model) item.model = Provider.parseModel(value.model) + item.variant = value.variant ?? item.variant + item.prompt = value.prompt ?? item.prompt + item.description = value.description ?? item.description + item.temperature = value.temperature ?? item.temperature + item.topP = value.top_p ?? item.topP + item.mode = value.mode ?? item.mode + item.color = value.color ?? item.color + item.hidden = value.hidden ?? item.hidden + item.name = value.name ?? item.name + item.steps = value.steps ?? item.steps + // kilocode_change start - carry metadata as typed fields, never as provider options + item.displayName = value.displayName ?? item.displayName + item.source = value.source ?? item.source + item.requirements = value.requirements ?? item.requirements + // kilocode_change end + item.options = mergeDeep(item.options, value.options ?? {}) + item.permission = Permission.merge(item.permission, Permission.fromConfig(value.permission ?? {})) + KiloAgent.processConfigItem(item) // kilocode_change - populate displayName from options + } + + function referencePrompt(reference: KiloReference.Resolved) { + if (reference.kind === "local") { + return [ + `You are configured reference @${reference.name}, a read-only research agent for external reference material.`, + `Local directory: ${reference.path}`, + `Inspect this directory as the primary reference source. Prefer repo_overview with path ${JSON.stringify(reference.path)} before broader searches. Do not edit files.`, + `Return exact absolute file paths for findings whenever possible.`, + ].join("\n\n") + } + + if (reference.kind === "invalid") { + return [ + `You are configured reference @${reference.name}, but this reference is not usable yet.`, + `Configured repository: ${reference.repository}`, + `Problem: ${reference.message}`, + `Explain this configuration problem if invoked. Do not edit files or attempt fallback clones.`, + ].join("\n\n") + } - function referencePrompt(reference: ReferenceV1.Resolved) { - if (reference.kind === "local") { return [ `You are configured reference @${reference.name}, a read-only research agent for external reference material.`, - `Local directory: ${reference.path}`, - `Inspect this directory as the primary reference source. Prefer repo_overview with path ${JSON.stringify(reference.path)} before broader searches. Do not edit files.`, + `Repository: ${reference.repository}`, + ...(reference.branch ? [`Branch/ref: ${reference.branch}`] : []), + `Cached directory: ${reference.path}`, + `Kilo materializes this configured repository before use. Do not call repo_clone for this reference.`, // kilocode_change + `Inspect the cached directory as the primary reference source. Prefer repo_overview with path ${JSON.stringify(reference.path)} before broader searches, then use Glob, Grep, and Read inside that directory. Do not edit files.`, `Return exact absolute file paths for findings whenever possible.`, ].join("\n\n") } - if (reference.kind === "invalid") { - return [ - `You are configured reference @${reference.name}, but this reference is not usable yet.`, - `Configured repository: ${reference.repository}`, - `Problem: ${reference.message}`, - `Explain this configuration problem if invoked. Do not edit files or attempt fallback clones.`, - ].join("\n\n") + function referenceDescription(reference: KiloReference.Resolved) { + if (reference.kind === "local") return `Scout reference for local directory ${reference.path}` + if (reference.kind === "git") return `Scout reference for repository ${reference.repository}` + return `Invalid Scout reference for repository ${reference.repository}` } - return [ - `You are configured reference @${reference.name}, a read-only research agent for external reference material.`, - `Repository: ${reference.repository}`, - ...(reference.branch ? [`Branch/ref: ${reference.branch}`] : []), - `Cached directory: ${reference.path}`, - `Kilo materializes this configured repository before use. Do not call repo_clone for this reference.`, // kilocode_change - `Inspect the cached directory as the primary reference source. Prefer repo_overview with path ${JSON.stringify(reference.path)} before broader searches, then use Glob, Grep, and Read inside that directory. Do not edit files.`, - `Return exact absolute file paths for findings whenever possible.`, - ].join("\n\n") - } - - function referenceDescription(reference: ReferenceV1.Resolved) { - if (reference.kind === "local") return `Scout reference for local directory ${reference.path}` - if (reference.kind === "git") return `Scout reference for repository ${reference.repository}` - return `Invalid Scout reference for repository ${reference.repository}` - } - - if (flags.experimentalScout) { - const resolvedReferences = ReferenceV1.resolveAll({ - references: ConfigReference.normalize(cfg.reference ?? {}), // kilocode_change - directory: ctx.directory, - worktree: ctx.worktree, - }) - for (const resolved of resolvedReferences) { - if (agents[resolved.name]) continue - const localPath = resolved.kind === "invalid" ? undefined : resolved.path - agents[resolved.name] = { - name: resolved.name, - description: referenceDescription(resolved), - permission: Permission.merge( - agents.scout.permission, - Permission.fromConfig({ - repo_clone: "deny", - ...(localPath - ? { - external_directory: { - [localPath]: "allow", - [path.join(localPath, "*")]: "allow", - }, - } - : {}), - }), - ), - prompt: referencePrompt(resolved), - options: { reference: cfg.reference?.[resolved.name], resolved }, - mode: "subagent", - native: false, + if (flags.experimentalScout) { + const resolvedReferences = KiloReference.resolveAll({ + references: cfg.reference ?? {}, // kilocode_change + directory: ctx.directory, + worktree: ctx.worktree, + }) + for (const resolved of resolvedReferences) { + if (agents[resolved.name]) continue + const localPath = resolved.kind === "invalid" ? undefined : resolved.path + agents[resolved.name] = { + name: resolved.name, + description: referenceDescription(resolved), + permission: Permission.merge( + agents.scout.permission, + Permission.fromConfig({ + repo_clone: "deny", + ...(localPath + ? { + external_directory: { + [localPath]: "allow", + [path.join(localPath, "*")]: "allow", + }, + } + : {}), + }), + ), + prompt: referencePrompt(resolved), + options: { reference: cfg.reference?.[resolved.name], resolved }, + mode: "subagent", + native: false, + } } } - } - // Ensure Truncate.GLOB is allowed unless explicitly configured - for (const name in agents) { - const agent = agents[name] - const explicit = agent.permission.some((r) => { - if (r.permission !== "external_directory") return false - if (r.action !== "deny") return false - return r.pattern === Truncate.GLOB - }) - if (explicit) continue + // Ensure Truncate.GLOB is allowed unless explicitly configured + for (const name in agents) { + const agent = agents[name] + const explicit = agent.permission.some((r) => { + if (r.permission !== "external_directory") return false + if (r.action !== "deny") return false + return r.pattern === Truncate.GLOB + }) + if (explicit) continue - agents[name].permission = Permission.merge( - agents[name].permission, - Permission.fromConfig({ external_directory: { [Truncate.GLOB]: "allow" } }), - ) - } - - KiloAgent.hardenSystemAgents(agents) // kilocode_change - keep system utility agents deny-only after config merges - - const get = Effect.fnUntraced(function* (agent: string) { - return agents[KiloAgent.resolveKey(agent)] // kilocode_change - treat "build" as "code" - }) - - const list = Effect.fnUntraced(function* () { - const cfg = yield* config.get() - return pipe( - agents, - values(), - sortBy( - [(x) => (cfg.default_agent ? x.name === cfg.default_agent : x.name === "code"), "desc"], // kilocode_change - renamed from "build" to "code" - [(x) => x.name, "asc"], - ), - ) - }) - - const defaultInfo = Effect.fnUntraced(function* () { - const c = yield* config.get() - if (c.default_agent) { - // kilocode_change start - const effective = KiloAgent.resolveKey(c.default_agent) - const agent = agents[effective] - // kilocode_change end - if (!agent) throw new Error(`default agent "${c.default_agent}" not found`) - if (agent.mode === "subagent") throw new Error(`default agent "${c.default_agent}" is a subagent`) - if (agent.hidden === true) throw new Error(`default agent "${c.default_agent}" is hidden`) - return agent + agents[name].permission = Permission.merge( + agents[name].permission, + Permission.fromConfig({ external_directory: { [Truncate.GLOB]: "allow" } }), + ) } - // kilocode_change start - prefer "code" as default agent (key order changes after rename from "build") - const code = agents.code - if (code && code.mode !== "subagent" && code.hidden !== true) return code - // kilocode_change end - const visible = Object.values(agents).find((a) => a.mode !== "subagent" && a.hidden !== true) - if (!visible) throw new Error("no primary visible agent found") - return visible - }) - const defaultAgent = Effect.fnUntraced(function* () { - return (yield* defaultInfo()).name - }) + KiloAgent.hardenSystemAgents(agents) // kilocode_change - keep system utility agents deny-only after config merges - return { - version: KiloAgent.cacheKey(cfg), // kilocode_change - get, - list, - defaultInfo, - defaultAgent, - } satisfies State - }), - ) + const get = Effect.fnUntraced(function* (agent: string) { + return agents[KiloAgent.resolveKey(agent)] // kilocode_change - treat "build" as "code" + }) + + const list = Effect.fnUntraced(function* () { + const cfg = yield* config.get() + return pipe( + agents, + values(), + sortBy( + [(x) => (cfg.default_agent ? x.name === cfg.default_agent : x.name === "code"), "desc"], // kilocode_change - renamed from "build" to "code" + [(x) => x.name, "asc"], + ), + ) + }) + + const defaultInfo = Effect.fnUntraced(function* () { + const c = yield* config.get() + if (c.default_agent) { + // kilocode_change start + const effective = KiloAgent.resolveKey(c.default_agent) + const agent = agents[effective] + // kilocode_change end + if (!agent) throw new Error(`default agent "${c.default_agent}" not found`) + if (agent.mode === "subagent") throw new Error(`default agent "${c.default_agent}" is a subagent`) + if (agent.hidden === true) throw new Error(`default agent "${c.default_agent}" is hidden`) + return agent + } + // kilocode_change start - prefer "code" as default agent (key order changes after rename from "build") + const code = agents.code + if (code && code.mode !== "subagent" && code.hidden !== true) return code + // kilocode_change end + const visible = Object.values(agents).find((a) => a.mode !== "subagent" && a.hidden !== true) + if (!visible) throw new Error("no primary visible agent found") + return visible + }) + + const defaultAgent = Effect.fnUntraced(function* () { + return (yield* defaultInfo()).name + }) + + return { + version: KiloAgent.cacheKey(cfg), // kilocode_change + get, + list, + defaultInfo, + defaultAgent, + } satisfies State + }), + ) // kilocode_change start - rebuild cached agents when permission-relevant config changes const current = Effect.fnUntraced(function* (select: (s: State) => Effect.Effect) { diff --git a/packages/opencode/src/bus/index.ts b/packages/opencode/src/bus/index.ts index db663b1235..9422619e10 100644 --- a/packages/opencode/src/bus/index.ts +++ b/packages/opencode/src/bus/index.ts @@ -14,6 +14,7 @@ import { Identifier } from "@/id/id" import { context as instanceContext, type InstanceContext } from "@/project/instance-context" // kilocode_change import { InstanceRef } from "@/effect/instance-ref" import { LocalContext } from "@/util/local-context" // kilocode_change +import { LayerNode } from "@opencode-ai/core/effect/layer-node" // kilocode_change const log = Log.create({ service: "bus" }) @@ -193,6 +194,7 @@ export const layer = Layer.effect( ) export const defaultLayer = layer +export const node = LayerNode.make(layer, []) // kilocode_change const { runPromise, runSync } = makeRuntime(Service, layer) diff --git a/packages/opencode/src/cli/cmd/tui.ts b/packages/opencode/src/cli/cmd/tui.ts index 036290eff2..daff31af51 100644 --- a/packages/opencode/src/cli/cmd/tui.ts +++ b/packages/opencode/src/cli/cmd/tui.ts @@ -167,6 +167,7 @@ export const TuiThreadCommand = cmd({ // kilocode_change end const auth = KiloTuiThreadDaemon.workerAuth() // kilocode_change - protect TUI-owned HTTP routes from unauthenticated local callers const worker = new Worker(file, { + preload: ["@opentui/solid/preload"], // kilocode_change - Bun workers do not inherit the parent preload env: { ...process.env, ...auth.env, // kilocode_change diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 2f6af7718f..9ca2c88a36 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -55,6 +55,9 @@ import { import { unique } from "remeda" // kilocode_change end import { withTransientReadRetry } from "@/util/effect-http-client" +import * as Log from "@opencode-ai/core/util/log" // kilocode_change + +const log = Log.create({ service: "config" }) // kilocode_change // Custom merge function that concatenates array fields instead of replacing them // Keep remeda's deep conditional merge type out of hot config-loading paths; TS profiling showed it dominates here. @@ -70,7 +73,7 @@ function mergeConfigConcatArrays(target: Info, source: Info): Info { return merged } -function normalizeLoadedConfig(data: unknown) { +function normalizeLoadedConfig(data: unknown, source: string) { if (!isRecord(data)) return data const copy = KilocodeConfig.retireIndexingFlag({ ...data }, source) // kilocode_change const hadLegacy = "theme" in copy || "keybinds" in copy || "tui" in copy @@ -78,6 +81,7 @@ function normalizeLoadedConfig(data: unknown) { delete copy.theme delete copy.keybinds delete copy.tui + log.warn("tui keys in the main config are deprecated; move them to tui.json", { path: source }) // kilocode_change return copy } @@ -307,7 +311,7 @@ export const layer = Layer.effect( ), ) const parsed = ConfigParse.jsonc(expanded, source) - const data = ConfigParse.schema(ConfigV1.Info, normalizeLoadedConfig(parsed), source) + const data = ConfigParse.schema(ConfigV1.Info, normalizeLoadedConfig(parsed, source), source) if (!("path" in options)) return data yield* Effect.promise(() => resolveLoadedPlugins(data, options.path)) @@ -1053,6 +1057,14 @@ export const defaultLayer = layer.pipe( Layer.provide(FetchHttpClient.layer), ) -export const node = LayerNode.make(layer, [FSUtil.node, Auth.node, Account.node, Env.node, Npm.node, httpClient]) +export const node = LayerNode.make(layer, [ + FSUtil.node, + Auth.node, + Account.node, + Env.node, + Npm.node, + httpClient, + Git.node, +]) // kilocode_change export * as Config from "./config" diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts index dd3863625c..60593f951f 100644 --- a/packages/opencode/src/config/tui.ts +++ b/packages/opencode/src/config/tui.ts @@ -39,6 +39,7 @@ export type HostMetadata = { export interface Interface { readonly get: () => Effect.Effect + readonly info: () => Effect.Effect // kilocode_change - editable config for Kilo console readonly pluginOrigins: () => Effect.Effect readonly waitForDependencies: () => Effect.Effect } @@ -242,14 +243,15 @@ const loadState = Effect.fn("TuiConfig.loadState")(function* (ctx: { directory: // kilocode_change start - inject Kilo default plugins to keep TUI aligned with server config const defaults = KilocodeDefaultPlugins.apply( - { plugin: result.plugin, plugin_origins: acc.plugin_origins }, + { plugin: result.plugin ? [...result.plugin] : undefined, plugin_origins: acc.plugin_origins }, { disabled: Flag.KILO_DISABLE_DEFAULT_PLUGINS }, ) - result.plugin = defaults.plugin + const config = { ...result, plugin: defaults.plugin } // kilocode_change end return { - config: result, + config, + info: { ...acc.result, plugin: defaults.plugin }, // kilocode_change - include applied Kilo defaults pluginOrigins: defaults.plugin_origins ?? [], // kilocode_change - exclude builtins from dependency installation dirs: result.plugin?.length ? dirs : [], } @@ -280,12 +282,13 @@ export const layer = Layer.effect( ) const get = Effect.fn("TuiConfig.get")(() => Effect.succeed(data.config)) + const info = Effect.fn("TuiConfig.info")(() => Effect.succeed(data.info)) // kilocode_change const pluginOrigins = Effect.fn("TuiConfig.pluginOrigins")(() => Effect.succeed(data.pluginOrigins)) const waitForDependencies = Effect.fn("TuiConfig.waitForDependencies")(() => Effect.forEach(deps, Fiber.join, { concurrency: "unbounded" }).pipe(Effect.ignore(), Effect.asVoid), ) - return Service.of({ get, pluginOrigins, waitForDependencies }) + return Service.of({ get, info, pluginOrigins, waitForDependencies }) // kilocode_change }).pipe(Effect.withSpan("TuiConfig.layer")), ) @@ -301,6 +304,10 @@ export async function get() { return runPromise((svc) => svc.get()) } +export async function info() { + return runPromise((svc) => svc.info()) +} + export async function pluginOrigins() { return runPromise((svc) => svc.pluginOrigins()) } diff --git a/packages/opencode/src/kilo-sessions/kilo-sessions.ts b/packages/opencode/src/kilo-sessions/kilo-sessions.ts index 277b1eaaec..7a08d4821c 100644 --- a/packages/opencode/src/kilo-sessions/kilo-sessions.ts +++ b/packages/opencode/src/kilo-sessions/kilo-sessions.ts @@ -32,6 +32,7 @@ import { Permission } from "@/permission" import { withTimeout } from "@/util/timeout" import { Snapshot } from "@/snapshot" import { cumulativeSessionDiff } from "@/kilocode/session-portability/cumulative-diff" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" async function provide(input: { directory: string; fn: () => R }): Promise { const { provide } = await import("@/kilocode/instance") @@ -382,6 +383,8 @@ export namespace KiloSessions { Layer.provide(Session.defaultLayer), ) + export const node = LayerNode.make(layer, [Bus.node, Config.node, Session.node]) + export async function enableRemote() { if (remote) return if (ingestDisabled) return diff --git a/packages/opencode/src/kilocode/bootstrap.ts b/packages/opencode/src/kilocode/bootstrap.ts index 05915762b2..a5a6c0a558 100644 --- a/packages/opencode/src/kilocode/bootstrap.ts +++ b/packages/opencode/src/kilocode/bootstrap.ts @@ -18,6 +18,7 @@ import { MemoryService } from "@kilocode/kilo-memory/effect/service" import { MemoryEvents } from "@/kilocode/memory/events" import { installMemoryRuntime } from "@/kilocode/memory/runtime" import { KiloToolRegistry } from "@/kilocode/tool/registry" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" const log = Log.create({ service: "kilocode-bootstrap" }) @@ -99,4 +100,14 @@ export namespace KilocodeBootstrap { Bus.defaultLayer, ]), ) + + const memory = LayerNode.make(MemoryService.layer, []) + export const node = LayerNode.make(layer, [ + KiloSessions.node, + Session.node, + SessionSummary.node, + Provider.node, + memory, + Bus.node, + ]) } diff --git a/packages/opencode/src/kilocode/claw/autocomplete.tsx b/packages/opencode/src/kilocode/claw/autocomplete.tsx index 895e2aaadb..dbab7a2851 100644 --- a/packages/opencode/src/kilocode/claw/autocomplete.tsx +++ b/packages/opencode/src/kilocode/claw/autocomplete.tsx @@ -21,7 +21,7 @@ import fuzzysort from "fuzzysort" import { Index, Show, createEffect, createMemo, createSignal, onCleanup, onMount } from "solid-js" import { createStore } from "solid-js/store" import { useTerminalDimensions } from "@opentui/solid" -import { SplitBorder } from "@tui/component/border" +import { SplitBorder } from "@tui/ui/border" import { useBindings, useOpencodeModeStack } from "@tui/keymap" import { selectedForeground, useTheme } from "@tui/context/theme" diff --git a/packages/opencode/src/kilocode/claw/chat.tsx b/packages/opencode/src/kilocode/claw/chat.tsx index 686b1c479c..4b98d0d155 100644 --- a/packages/opencode/src/kilocode/claw/chat.tsx +++ b/packages/opencode/src/kilocode/claw/chat.tsx @@ -13,7 +13,7 @@ import { createEffect, createMemo, createSignal, For, Show } from "solid-js" import { type BoxRenderable, type MouseEvent, type TextareaRenderable } from "@opentui/core" import { useRenderer } from "@opentui/solid" import { useTheme } from "@tui/context/theme" -import { SplitBorder, EmptyBorder } from "@tui/component/border" +import { SplitBorder, EmptyBorder } from "@tui/ui/border" import { useKV } from "@tui/context/kv" import { Spinner } from "@tui/component/spinner" import type { ChatMessage, TypingMember } from "./types" diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx index 46b45902e2..34e74fcaa6 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx @@ -8,7 +8,7 @@ import { createEffect, on } from "solid-js" import { useKeyboard } from "@opentui/solid" import { TextAttributes } from "@opentui/core" -import * as Clipboard from "@tui/util/clipboard" +import * as Clipboard from "@tui/clipboard" import { useBindings } from "@tui/keymap" import { useSDK } from "@tui/context/sdk" import { useSync } from "@tui/context/sync" @@ -34,6 +34,7 @@ export { KiloTerminalTitle } from "./terminal-title" // Hot reload TUI-local settings (keybinds/theme/ui) when changed from the Kilo Console. // Called from the App body (below SDKProvider and the TuiConfig provider). export { useTuiConfigHotReload } from "@/kilocode/cli/cmd/tui/context/tui-config-hot-reload" +export { KiloTuiConfig } from "@/kilocode/cli/cmd/tui/context/tui-config" // --------------------------------------------------------------------------- // Constants diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-memory.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-memory.tsx index 73f1111e66..6ece330fdf 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-memory.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-memory.tsx @@ -6,14 +6,14 @@ import { MemoryDecisions } from "@kilocode/kilo-memory/decisions" import { MemoryToken } from "@kilocode/kilo-memory/token" import { Global } from "@opencode-ai/core/global" import { createMemo, createResource, For, Match, Show, Switch } from "solid-js" -import { relativeTime } from "@/cli/cmd/tui/feature-plugins/session/util" -import { useProject } from "@/cli/cmd/tui/context/project" -import { useSDK } from "@/cli/cmd/tui/context/sdk" -import { useTheme } from "@/cli/cmd/tui/context/theme" -import { useTuiConfig } from "@/cli/cmd/tui/context/tui-config" -import { useBindings } from "@/cli/cmd/tui/keymap" -import { useDialog, type DialogContext } from "@/cli/cmd/tui/ui/dialog" -import { getScrollAcceleration } from "@/cli/cmd/tui/util/scroll" +import { relativeTime } from "@/kilocode/cli/cmd/tui/relative-time" +import { useProject } from "@tui/context/project" +import { useSDK } from "@tui/context/sdk" +import { useTheme } from "@tui/context/theme" +import { useTuiConfig } from "@tui/config" +import { useBindings } from "@tui/keymap" +import { useDialog, type DialogContext } from "@tui/ui/dialog" +import { getScrollAcceleration } from "@tui/util/scroll" import { route } from "@/kilocode/cli/cmd/tui/memory-command" import { errorMessage } from "@/util/error" @@ -163,9 +163,7 @@ export function DialogMemoryHelp(props: { reason?: string }) { esc - - {(reason) => {reason()}} - + {(reason) => {reason()}} {(item) => ( @@ -232,8 +230,8 @@ function DialogMemoryStatus(props: { workspace?: string; directory?: string }) { Startup context - {item().state.autoInject ? "on" : "off"} · last injected{" "} - {fmt(item().state.stats.lastInjectedTokens)} tokens + {item().state.autoInject ? "on" : "off"} · last injected {fmt(item().state.stats.lastInjectedTokens)}{" "} + tokens diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-process-list.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-process-list.tsx index 83baa0b652..6b3a94b97f 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-process-list.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/component/dialog-process-list.tsx @@ -9,7 +9,7 @@ import { useRoute } from "@tui/context/route" import { useSDK } from "@tui/context/sdk" import { useSync } from "@tui/context/sync" import { useTheme } from "@tui/context/theme" -import { useTuiConfig } from "@tui/context/tui-config" +import { useTuiConfig } from "@tui/config" import { useToast } from "@tui/ui/toast" import { getScrollAcceleration } from "@tui/util/scroll" import { errorMessage } from "@/util/error" diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-prompt.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-prompt.tsx index 86914a1780..d26c0816f5 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-prompt.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-prompt.tsx @@ -1,7 +1,7 @@ import type { KiloClient } from "@kilocode/sdk/v2" import type { CliRenderer } from "@opentui/core" -import type { DialogContext } from "@/cli/cmd/tui/ui/dialog" -import type { ToastContext } from "@/cli/cmd/tui/ui/toast" +import type { DialogContext } from "@tui/ui/dialog" +import type { ToastContext } from "@tui/ui/toast" import { showMemoryDialog, showMemoryHelpDialog, diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-sidebar.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-sidebar.tsx index 8a30a0f4ec..2f35c74c6f 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-sidebar.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/component/memory-sidebar.tsx @@ -2,7 +2,7 @@ import type { TuiPluginApi } from "@kilocode/plugin/tui" import { MemoryAutosaveStatus } from "@kilocode/kilo-memory/autosave-status" import { createMemo, createResource, createSignal, onCleanup, onMount, Show } from "solid-js" import * as Log from "@opencode-ai/core/util/log" -import { relativeTime } from "@/cli/cmd/tui/feature-plugins/session/util" +import { relativeTime } from "@/kilocode/cli/cmd/tui/relative-time" import { route } from "@/kilocode/cli/cmd/tui/memory-command" import { errorMessage } from "@/util/error" import { Locale } from "@/util/locale" @@ -39,12 +39,12 @@ export function MemorySidebar(props: { api: TuiPluginApi; sessionID: string }) { const [data] = createResource( () => `${workspace() ?? "__default__"}:${dir()}:${tick()}`, async () => { - const status = await props.api.client.memory.status(route({ workspace: workspace(), directory: dir() })).catch( - (error: unknown) => { + const status = await props.api.client.memory + .status(route({ workspace: workspace(), directory: dir() })) + .catch((error: unknown) => { log.warn("memory status unavailable", { error: errorMessage(error) }) return undefined - }, - ) + }) if (!status) return if (status.error || !status.data) return return status.data diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config-hot-reload.ts b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config-hot-reload.ts index b04ff83af2..e28b072f1e 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config-hot-reload.ts +++ b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config-hot-reload.ts @@ -9,9 +9,9 @@ * Kept separate from `tui-config.tsx` so the store factory has no SDK/event imports. */ import { onCleanup, onMount } from "solid-js" -import type { TuiConfig } from "@/cli/cmd/tui/config/tui" -import { useSDK } from "@/cli/cmd/tui/context/sdk" -import { useEvent } from "@/cli/cmd/tui/context/event" +import type { TuiConfig } from "@tui/config" +import { useSDK } from "@tui/context/sdk" +import { useEvent } from "@tui/context/event" import { KiloTuiConfig } from "./tui-config" /** diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx index 654efa6d99..5b30b23229 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx @@ -7,15 +7,13 @@ */ import { createContext, useContext, type ParentProps } from "solid-js" import { createStore, reconcile } from "solid-js/store" -import { TuiConfig } from "@/cli/cmd/tui/config/tui" -import { TuiKeybind } from "@/cli/cmd/tui/config/keybind" -import { KeymapLeaderTimeoutDefault } from "@/cli/cmd/tui/config/tui-schema" +import { LeaderTimeoutDefault, TuiConfig, TuiConfigProvider, useTuiConfig } from "@tui/config" +import { TuiKeybind } from "@tui/config/keybind" import { createBindingLookup } from "@opentui/keymap/extras" import { KiloTitleIcon } from "@/kilocode/cli/cmd/tui/title-icon" export type SetTuiConfig = (next: TuiConfig.Info) => void -const ConfigContext = createContext() const SetContext = createContext() export namespace KiloTuiConfig { @@ -39,7 +37,8 @@ export namespace KiloTuiConfig { commandMap: TuiKeybind.CommandMap, bindingDefaults: TuiKeybind.bindingDefaults(), }), - leader_timeout: next.leader_timeout ?? KeymapLeaderTimeoutDefault, + leader_timeout: next.leader_timeout ?? LeaderTimeoutDefault, + mouse: next.mouse ?? true, } if (JSON.stringify(config.keybinds.bindings) === JSON.stringify(store.keybinds.bindings)) { config.keybinds = store.keybinds @@ -52,16 +51,14 @@ export namespace KiloTuiConfig { export function Provider(props: ParentProps<{ config: TuiConfig.Resolved }>) { const store = makeStore(props.config) return ( - + {props.children} - + ) } export function use() { - const value = useContext(ConfigContext) - if (!value) throw new Error("TuiConfig context must be used within a context provider") - return value + return useTuiConfig() } export function useSet() { diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/permissions.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/permissions.tsx index 1a46f8e59d..88ab1f7a06 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/permissions.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/permissions.tsx @@ -1,5 +1,5 @@ import type { PermissionRequest } from "@kilocode/sdk/v2" -import { useTheme } from "@/cli/cmd/tui/context/theme" +import { useTheme } from "@tui/context/theme" import { MemoryPermissionRegistry } from "@/kilocode/cli/cmd/tui/routes/session/memory-permission" function MemoryBody(props: { request: PermissionRequest }) { diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/relative-time.ts b/packages/opencode/src/kilocode/cli/cmd/tui/relative-time.ts new file mode 100644 index 0000000000..f922c17df2 --- /dev/null +++ b/packages/opencode/src/kilocode/cli/cmd/tui/relative-time.ts @@ -0,0 +1,11 @@ +export function relativeTime(timestamp: number) { + const seconds = Math.floor((Date.now() - timestamp) / 1000) + if (seconds < 60) return "just now" + const minutes = Math.floor(seconds / 60) + if (minutes < 60) return `${minutes}m ago` + const hours = Math.floor(minutes / 60) + if (hours < 24) return `${hours}h ago` + const days = Math.floor(hours / 24) + if (days < 7) return `${days}d ago` + return new Date(timestamp).toLocaleDateString(undefined, { month: "short", day: "numeric" }) +} diff --git a/packages/opencode/src/kilocode/commands.ts b/packages/opencode/src/kilocode/commands.ts index fce47c346a..e462359eab 100644 --- a/packages/opencode/src/kilocode/commands.ts +++ b/packages/opencode/src/kilocode/commands.ts @@ -3,8 +3,8 @@ // When upstream adds a new command to index.ts, add it here too. import { AcpCommand } from "../cli/cmd/acp" import { McpCommand } from "../cli/cmd/mcp" -import { TuiThreadCommand } from "../cli/cmd/tui/thread" -import { AttachCommand } from "../cli/cmd/tui/attach" +import { TuiThreadCommand } from "../cli/cmd/tui" +import { AttachCommand } from "../cli/cmd/attach" import { RunCommand } from "../cli/cmd/run" import { GenerateCommand } from "../cli/cmd/generate" import { DebugCommand } from "../cli/cmd/debug" diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx index 239ea52eec..797723d1b6 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx @@ -12,7 +12,7 @@ import { useDialog } from "@tui/ui/dialog" import { useSync } from "@tui/context/sync" import { useToast } from "@tui/ui/toast" import { Link } from "@tui/ui/link" -import * as Clipboard from "@tui/util/clipboard" +import * as Clipboard from "@tui/clipboard" import { DialogKiloOrganization } from "./dialog-kilo-organization.js" // These types are OpenCode-internal and imported at runtime @@ -43,7 +43,7 @@ export function KiloAutoMethod(props: KiloAutoMethodProps) { useKeyboard((evt: any) => { if (evt.name === "c" && !evt.ctrl && !evt.meta) { const code = props.authorization.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4}/)?.[0] ?? props.authorization.url - Clipboard.copy(code) + Clipboard.write(code) .then(() => toast.show({ message: "Copied to clipboard", variant: "info" })) .catch(toast.error) } diff --git a/packages/opencode/src/kilocode/components/kilo-error-display.tsx b/packages/opencode/src/kilocode/components/kilo-error-display.tsx index 0e44293f46..d0e4dd9297 100644 --- a/packages/opencode/src/kilocode/components/kilo-error-display.tsx +++ b/packages/opencode/src/kilocode/components/kilo-error-display.tsx @@ -1,5 +1,5 @@ import { createMemo, Match, Switch, type JSX } from "solid-js" -import { SplitBorder } from "@tui/component/border" +import { SplitBorder } from "@tui/ui/border" import { useTheme } from "@tui/context/theme" import { parseKiloErrorCode, kiloErrorTitle, kiloErrorDescription } from "@/kilocode/kilo-errors" import type { AssistantMessage } from "@kilocode/sdk/v2" diff --git a/packages/opencode/src/kilocode/plan-followup.ts b/packages/opencode/src/kilocode/plan-followup.ts index 7299675c48..01de704a54 100644 --- a/packages/opencode/src/kilocode/plan-followup.ts +++ b/packages/opencode/src/kilocode/plan-followup.ts @@ -1,6 +1,6 @@ import { Telemetry } from "@kilocode/kilo-telemetry" import { Agent } from "@/agent/agent" -import { TuiEvent } from "@/cli/cmd/tui/event" +import { TuiEvent } from "@/server/tui-event" import { Flag } from "@opencode-ai/core/flag/flag" import { Global } from "@opencode-ai/core/global" import { Identifier } from "@/id/id" diff --git a/packages/opencode/src/kilocode/plugins/memory-palette.tsx b/packages/opencode/src/kilocode/plugins/memory-palette.tsx index a5c7ce1963..3ad9ec5742 100644 --- a/packages/opencode/src/kilocode/plugins/memory-palette.tsx +++ b/packages/opencode/src/kilocode/plugins/memory-palette.tsx @@ -1,5 +1,5 @@ import type { TuiPlugin } from "@kilocode/plugin/tui" -import type { InternalTuiPlugin } from "@/cli/cmd/tui/plugin/internal" +import type { InternalTuiPlugin } from "@/plugin/tui/internal" import { DialogMemoryHelp } from "@/kilocode/cli/cmd/tui/component/dialog-memory" const id = "internal:kilo-memory-palette" diff --git a/packages/opencode/src/kilocode/plugins/permissions.ts b/packages/opencode/src/kilocode/plugins/permissions.ts index 8d29c3406a..a9b5caffb6 100644 --- a/packages/opencode/src/kilocode/plugins/permissions.ts +++ b/packages/opencode/src/kilocode/plugins/permissions.ts @@ -1,5 +1,5 @@ import type { TuiPlugin } from "@kilocode/plugin/tui" -import type { InternalTuiPlugin } from "@/cli/cmd/tui/plugin/internal" +import type { InternalTuiPlugin } from "@/plugin/tui/internal" import { MemoryPermission } from "@/kilocode/cli/cmd/tui/permissions" const id = "internal:kilo-permissions" diff --git a/packages/opencode/src/kilocode/plugins/sidebar-indexing.tsx b/packages/opencode/src/kilocode/plugins/sidebar-indexing.tsx index 4c9113ad21..8406fde006 100644 --- a/packages/opencode/src/kilocode/plugins/sidebar-indexing.tsx +++ b/packages/opencode/src/kilocode/plugins/sidebar-indexing.tsx @@ -2,7 +2,7 @@ import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@kilocode/plugin/ import { createEffect, createMemo, createSignal, onCleanup, onMount, Show } from "solid-js" import type { IndexingStatus, IndexingStatusState } from "@kilocode/kilo-indexing/status" import * as Log from "@opencode-ai/core/util/log" -import { useSync } from "@/cli/cmd/tui/context/sync" +import { useSync } from "@tui/context/sync" import { formatIndexingLabel } from "../indexing-label" import { indexingEnabled } from "../indexing-feature" diff --git a/packages/opencode/src/kilocode/plugins/sidebar-memory.tsx b/packages/opencode/src/kilocode/plugins/sidebar-memory.tsx index 1cf80612f0..01ed60e08e 100644 --- a/packages/opencode/src/kilocode/plugins/sidebar-memory.tsx +++ b/packages/opencode/src/kilocode/plugins/sidebar-memory.tsx @@ -1,5 +1,5 @@ import type { TuiPlugin } from "@kilocode/plugin/tui" -import type { InternalTuiPlugin } from "@/cli/cmd/tui/plugin/internal" +import type { InternalTuiPlugin } from "@/plugin/tui/internal" import { MemorySidebar } from "@/kilocode/cli/cmd/tui/component/memory-sidebar" const id = "internal:kilo-sidebar-memory" diff --git a/packages/opencode/src/kilocode/reference.ts b/packages/opencode/src/kilocode/reference.ts new file mode 100644 index 0000000000..978f0e6cef --- /dev/null +++ b/packages/opencode/src/kilocode/reference.ts @@ -0,0 +1,97 @@ +import path from "path" +import { ConfigReference } from "@opencode-ai/core/config/reference" +import { Global } from "@opencode-ai/core/global" +import { parseRepositoryReference, repositoryCachePath, type RemoteReference } from "@/util/repository" + +export type Resolved = + | { + name: string + kind: "local" + path: string + } + | { + name: string + kind: "git" + repository: string + reference: RemoteReference + path: string + branch?: string + } + | { + name: string + kind: "invalid" + repository?: string + message: string + } + +type Normalized = + | { kind: "local"; path: string } + | { kind: "git"; repository: string; branch?: string } + | { kind: "invalid"; message: string } + +function normalize(name: string, entry: ConfigReference.Entry): Normalized { + if (name.length === 0) return { kind: "invalid", message: "Reference alias must not be empty" } + if (/[\/\s`,]/.test(name)) { + return { kind: "invalid", message: "Reference alias must not contain /, whitespace, comma, or backtick" } + } + if (typeof entry === "string") { + if (entry.startsWith(".") || entry.startsWith("/") || entry.startsWith("~")) { + return { kind: "local", path: entry } + } + return { kind: "git", repository: entry } + } + if ("path" in entry) return { kind: "local", path: entry.path } + return { kind: "git", repository: entry.repository, branch: entry.branch } +} + +function local(input: { directory: string; worktree: string; value: string }) { + if (input.value.startsWith("~/")) return path.join(Global.Path.home, input.value.slice(2)) + if (path.isAbsolute(input.value)) return input.value + return path.resolve(input.worktree === "/" ? input.directory : input.worktree, input.value) +} + +function resolve(name: string, entry: Normalized, directory: string, worktree: string): Resolved { + if (entry.kind === "invalid") return { name, kind: "invalid", message: entry.message } + if (entry.kind === "local") { + return { name, kind: "local", path: local({ directory, worktree, value: entry.path }) } + } + const reference = parseRepositoryReference(entry.repository) + if (!reference || reference.protocol === "file:") { + return { + name, + kind: "invalid", + repository: entry.repository, + message: "Repository must be a git URL, host/path reference, or GitHub owner/repo shorthand", + } + } + return { + name, + kind: "git", + repository: entry.repository, + reference, + path: repositoryCachePath(reference), + branch: entry.branch, + } +} + +export function resolveAll(input: { references: ConfigReference.Info; directory: string; worktree: string }) { + const seen = new Map() + return Object.entries(input.references).map(([name, entry]) => { + const item = resolve(name, normalize(name, entry), input.directory, input.worktree) + if (item.kind !== "git") return item + + const existing = seen.get(item.path) + if (!existing) { + seen.set(item.path, { name, branch: item.branch }) + return item + } + if (existing.branch === item.branch) return item + + return { + name, + kind: "invalid" as const, + repository: item.repository, + message: `Reference conflicts with @${existing.name}: both use ${item.path}, but @${existing.name} requests ${existing.branch ?? "default branch"} and @${name} requests ${item.branch ?? "default branch"}`, + } + }) +} diff --git a/packages/opencode/src/kilocode/suggestion/tui/bar.tsx b/packages/opencode/src/kilocode/suggestion/tui/bar.tsx index 65f5ecbea4..f76e4fb2c0 100644 --- a/packages/opencode/src/kilocode/suggestion/tui/bar.tsx +++ b/packages/opencode/src/kilocode/suggestion/tui/bar.tsx @@ -3,8 +3,8 @@ import type { SuggestionRequest } from "@kilocode/sdk/v2" import { createMemo, createSignal, For } from "solid-js" -import { useSDK } from "../../../cli/cmd/tui/context/sdk" -import { selectedForeground, useTheme } from "../../../cli/cmd/tui/context/theme" +import { useSDK } from "@tui/context/sdk" +import { selectedForeground, useTheme } from "@tui/context/theme" export function SuggestBar(props: { request: SuggestionRequest }) { const sdk = useSDK() diff --git a/packages/opencode/src/kilocode/suggestion/tui/prompt.tsx b/packages/opencode/src/kilocode/suggestion/tui/prompt.tsx index 4c0061ce76..959ed8a0e5 100644 --- a/packages/opencode/src/kilocode/suggestion/tui/prompt.tsx +++ b/packages/opencode/src/kilocode/suggestion/tui/prompt.tsx @@ -2,12 +2,12 @@ import type { SuggestionRequest } from "@kilocode/sdk/v2" import { createMemo, createSignal, For } from "solid-js" -import { SplitBorder } from "../../../cli/cmd/tui/component/border" -import { useSDK } from "../../../cli/cmd/tui/context/sdk" -import { useTuiConfig } from "../../../cli/cmd/tui/context/tui-config" -import { useBindings } from "../../../cli/cmd/tui/keymap" -import { tint, useTheme } from "../../../cli/cmd/tui/context/theme" -import { useDialog } from "../../../cli/cmd/tui/ui/dialog" +import { SplitBorder } from "@tui/ui/border" +import { useSDK } from "@tui/context/sdk" +import { useTuiConfig } from "@tui/config" +import { useBindings } from "@tui/keymap" +import { tint, useTheme } from "@tui/context/theme" +import { useDialog } from "@tui/ui/dialog" // The footer-mounted overlay only ever hosts blocking suggestions now; the // built-in suggest tool emits non-blocking requests that render inline at diff --git a/packages/opencode/src/kilocode/suggestion/tui/render.tsx b/packages/opencode/src/kilocode/suggestion/tui/render.tsx index b73dd6adc4..ba1d78779d 100644 --- a/packages/opencode/src/kilocode/suggestion/tui/render.tsx +++ b/packages/opencode/src/kilocode/suggestion/tui/render.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource @opentui/solid */ import { createMemo, Match, Show, Switch, type JSX } from "solid-js" -import { useTheme } from "../../../cli/cmd/tui/context/theme" +import { useTheme } from "@tui/context/theme" import type { SuggestionRequest, ToolPart as MessageToolPart } from "@kilocode/sdk/v2" import { SuggestBar } from "./bar" diff --git a/packages/opencode/src/kilocode/tui/config.ts b/packages/opencode/src/kilocode/tui/config.ts index ddb8f354db..6c6d7a61c0 100644 --- a/packages/opencode/src/kilocode/tui/config.ts +++ b/packages/opencode/src/kilocode/tui/config.ts @@ -5,9 +5,8 @@ import { applyEdits, modify } from "jsonc-parser" import { mergeDeep } from "remeda" import { Global } from "@opencode-ai/core/global" import { ConfigParse } from "@/config/parse" -import { CurrentWorkingDirectory } from "@/cli/cmd/tui/config/cwd" -import { TuiConfig } from "@/cli/cmd/tui/config/tui" -import { TuiInfo } from "@/cli/cmd/tui/config/tui-schema" +import { CurrentWorkingDirectory } from "@/config/tui-cwd" +import { TuiConfig } from "@/config/tui" import { KilocodeKeybinds } from "./keybinds" import { Filesystem } from "@/util/filesystem" import { isRecord } from "@/util/record" @@ -18,7 +17,7 @@ export namespace KilocodeTuiConfig { export const Scope = z.enum(["project", "global"]) export type Scope = z.infer - export const Patch = TuiInfo + export const Patch = TuiConfig.Info export type Patch = Schema.Schema.Type export type Editable = Omit & { keybinds?: Record } @@ -90,7 +89,7 @@ export namespace KilocodeTuiConfig { function parse(input: string, file: string): Patch { const data = ConfigParse.jsonc(input, file) if (!isRecord(data)) return {} - return writable(ConfigParse.schema(TuiInfo, normalize(data), file)) + return writable(ConfigParse.schema(TuiConfig.Info, normalize(data), file)) } function normalize(raw: Record) { diff --git a/packages/opencode/src/kilocode/tui/keybinds.ts b/packages/opencode/src/kilocode/tui/keybinds.ts index ec1f335ae8..570a39cd6e 100644 --- a/packages/opencode/src/kilocode/tui/keybinds.ts +++ b/packages/opencode/src/kilocode/tui/keybinds.ts @@ -1,4 +1,4 @@ -import { TuiKeybind } from "@/cli/cmd/tui/config/keybind" +import { TuiKeybind } from "@opencode-ai/tui/config/keybind" import { Schema } from "effect" export namespace KilocodeKeybinds { diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts index 2b7db1c32b..7390fc05d3 100644 --- a/packages/opencode/src/lsp/server.ts +++ b/packages/opencode/src/lsp/server.ts @@ -2,6 +2,7 @@ import type { ChildProcessWithoutNullStreams } from "child_process" import path from "path" import os from "os" import { Global } from "@opencode-ai/core/global" +import * as Log from "@opencode-ai/core/util/log" // kilocode_change import { text } from "node:stream/consumers" import fs from "fs/promises" import { Filesystem } from "@/util/filesystem" @@ -16,6 +17,7 @@ import { Npm } from "@opencode-ai/core/npm" import { TsCheck } from "../kilocode/ts-check" // kilocode_change import type { RuntimeFlags } from "@/effect/runtime-flags" +const log = Log.create({ service: "lsp.server" }) // kilocode_change const pathExists = async (p: string) => fs .stat(p) diff --git a/packages/opencode/src/mcp/oauth-callback.ts b/packages/opencode/src/mcp/oauth-callback.ts index 0656ad92a3..ef0450f66a 100644 --- a/packages/opencode/src/mcp/oauth-callback.ts +++ b/packages/opencode/src/mcp/oauth-callback.ts @@ -1,8 +1,11 @@ import { createConnection } from "net" import { createServer } from "http" +import * as Log from "@opencode-ai/core/util/log" // kilocode_change import { OAUTH_CALLBACK_PORT, OAUTH_CALLBACK_PATH, parseRedirectUri } from "./oauth-provider" import * as KiloOAuthCallback from "../kilocode/mcp-oauth-callback" // kilocode_change +const log = Log.create({ service: "mcp.oauth-callback" }) // kilocode_change + // Current callback server configuration (may differ from defaults if custom redirectUri is used) let currentPort = OAUTH_CALLBACK_PORT let currentPath = OAUTH_CALLBACK_PATH diff --git a/packages/opencode/src/permission/index.ts b/packages/opencode/src/permission/index.ts index fd3d95b3b9..9276aaef65 100644 --- a/packages/opencode/src/permission/index.ts +++ b/packages/opencode/src/permission/index.ts @@ -497,6 +497,6 @@ export function toConfig(rules: Ruleset): ConfigPermissionV1.Info { } // kilocode_change end -export const node = LayerNode.make(layer, [EventV2Bridge.node]) +export const node = LayerNode.make(layer, [EventV2Bridge.node, Config.node, Database.node]) // kilocode_change export * as Permission from "." diff --git a/packages/opencode/src/plugin/openai/codex.ts b/packages/opencode/src/plugin/openai/codex.ts index 85d40e7a35..c8245caf63 100644 --- a/packages/opencode/src/plugin/openai/codex.ts +++ b/packages/opencode/src/plugin/openai/codex.ts @@ -1,4 +1,5 @@ import type { Hooks, PluginInput } from "@kilocode/plugin" +import * as Log from "@opencode-ai/core/util/log" // kilocode_change import { InstallationVersion } from "@opencode-ai/core/installation/version" import { OAUTH_DUMMY_KEY } from "../../auth" import os from "os" @@ -7,6 +8,8 @@ import { createServer } from "http" import { refreshCodexAuth } from "@/kilocode/provider/codex-refresh" // kilocode_change import { OpenAIWebSocketPool } from "./ws-pool" +const log = Log.create({ service: "plugin.codex" }) // kilocode_change + const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann" const ISSUER = "https://auth.openai.com" const CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses" @@ -25,9 +28,7 @@ const ALLOWED_MODELS = new Set([ // kilocode_change end ]) // kilocode_change start -const DISALLOWED_MODELS = new Set([ - "gpt-5.5-pro", -]) +const DISALLOWED_MODELS = new Set(["gpt-5.5-pro"]) // kilocode_change end interface PkceCodes { diff --git a/packages/opencode/src/plugin/openai/ws-pool.ts b/packages/opencode/src/plugin/openai/ws-pool.ts index 01d899bdd1..71a5e947e7 100644 --- a/packages/opencode/src/plugin/openai/ws-pool.ts +++ b/packages/opencode/src/plugin/openai/ws-pool.ts @@ -1,10 +1,13 @@ import WebSocket from "ws" +import * as Log from "@opencode-ai/core/util/log" // kilocode_change import { ProviderError } from "@/provider/error" import { isRecord } from "@/util/record" import { OpenAIWebSocket } from "./ws" export const TITLE_HEADER = "x-kilo-title" +const log = Log.create({ service: "plugin.openai.ws" }) // kilocode_change + export interface CreateWebSocketFetchOptions { httpFetch?: typeof globalThis.fetch url?: string diff --git a/packages/opencode/src/project/bootstrap.ts b/packages/opencode/src/project/bootstrap.ts index 6e4c08c1be..9655f367c4 100644 --- a/packages/opencode/src/project/bootstrap.ts +++ b/packages/opencode/src/project/bootstrap.ts @@ -78,6 +78,7 @@ export const node = LayerNode.make(layer, [ LSP.node, Plugin.node, Project.node, + KilocodeBootstrap.node, // kilocode_change Snapshot.node, Vcs.node, ]) diff --git a/packages/opencode/src/provider/auth.ts b/packages/opencode/src/provider/auth.ts index b04c02a1ab..3234df3b88 100644 --- a/packages/opencode/src/provider/auth.ts +++ b/packages/opencode/src/provider/auth.ts @@ -261,6 +261,6 @@ export const defaultLayer = Layer.suspend(() => ) // kilocode_change end -export const node = LayerNode.make(layer, [Auth.node, Plugin.node]) +export const node = LayerNode.make(layer, [Auth.node, Plugin.node, ModelCache.node]) // kilocode_change export * as ProviderAuth from "./auth" diff --git a/packages/opencode/src/provider/model-cache.ts b/packages/opencode/src/provider/model-cache.ts index 7e41c2515e..4cfca273f5 100644 --- a/packages/opencode/src/provider/model-cache.ts +++ b/packages/opencode/src/provider/model-cache.ts @@ -6,6 +6,8 @@ import { Config } from "../config/config" import { Auth } from "../auth" import type { Provider } from "@opencode-ai/core/models-dev" import * as Log from "@opencode-ai/core/util/log" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" +import { httpClient } from "@opencode-ai/core/effect/layer-node-platform" type Models = Provider["models"] type KiloOptions = NonNullable[0]> @@ -282,4 +284,7 @@ export const defaultLayer = layer.pipe( Layer.provide(kiloModelsLayer), ) +const kiloModels = LayerNode.make(kiloModelsLayer, []) +export const node = LayerNode.make(layer, [Auth.node, Config.node, kiloModels, httpClient]) + export * as ModelCache from "./model-cache" diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index 6a693cde48..61bd0d1a24 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -6,6 +6,7 @@ import * as Core from "@opencode-ai/core/models-dev" import { Context, Effect, Layer } from "effect" import { AI_SDK_PROVIDERS, KILO_OPENROUTER_BASE, PROMPTS } from "@kilocode/kilo-gateway" import { overlay } from "@/kilocode/anaconda-desktop/provider" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" export const Model = Core.Model export type Model = Core.Model @@ -105,5 +106,7 @@ export const defaultLayer = layer.pipe( Layer.provide(ModelCache.defaultLayer), ) +export const node = LayerNode.make(layer, [Core.node, Config.node, Auth.node, ModelCache.node]) + export { AI_SDK_PROVIDERS, PROMPTS } export * as ModelsDev from "./models" diff --git a/packages/opencode/src/session/compaction.ts b/packages/opencode/src/session/compaction.ts index a54a1bd6fe..824b01097a 100644 --- a/packages/opencode/src/session/compaction.ts +++ b/packages/opencode/src/session/compaction.ts @@ -728,6 +728,7 @@ export const node = LayerNode.make(layer, [ Provider.node, EventV2Bridge.node, RuntimeFlags.node, + Database.node, // kilocode_change ]) export * as SessionCompaction from "./compaction" diff --git a/packages/opencode/src/session/llm.ts b/packages/opencode/src/session/llm.ts index c81d05e120..a47681b7ad 100644 --- a/packages/opencode/src/session/llm.ts +++ b/packages/opencode/src/session/llm.ts @@ -4,6 +4,7 @@ import { PermissionV1 } from "@opencode-ai/core/v1/permission" import { Provider } from "@/provider/provider" import { SessionV1 } from "@opencode-ai/core/v1/session" import { serviceUse } from "@opencode-ai/core/effect/service-use" +import { Log } from "@opencode-ai/core/util/log" // kilocode_change import { Context, Effect, Layer } from "effect" import * as Stream from "effect/Stream" import { streamText, wrapLanguageModel, type ModelMessage, type Tool } from "ai" @@ -39,6 +40,8 @@ import { LLMAISDK } from "./llm/ai-sdk" import { LLMNativeRuntime } from "./llm/native-runtime" import { LLMRequestPrep } from "./llm/request" +const log = Log.create({ service: "llm" }) // kilocode_change + export const OUTPUT_TOKEN_MAX = ProviderTransform.OUTPUT_TOKEN_MAX export type StreamInput = { @@ -94,6 +97,7 @@ const live: Layer.Layer< const flags = yield* RuntimeFlags.Service const run = Effect.fn("LLM.run")(function* (input: StreamRequest) { + const l = log.clone().tag("providerID", input.model.providerID).tag("modelID", input.model.id) // kilocode_change yield* Effect.logInfo("stream", { providerID: input.model.providerID, modelID: input.model.id, diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 8cdde3d2f5..774d4b0172 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -2052,7 +2052,10 @@ export const PromptInput = Schema.Struct({ // `parts` type from the exported Schema input types so callers see a proper // tagged union. type PartInputUnion = - MessageV2.TextPartInput | MessageV2.FilePartInput | MessageV2.AgentPartInput | MessageV2.SubtaskPartInput + | MessageV2.TextPartInput + | MessageV2.FilePartInput + | MessageV2.AgentPartInput + | MessageV2.SubtaskPartInput export type PromptInput = Omit, "parts" | "editorContext"> & { parts: PartInputUnion[] editorContext?: MessageV2.EditorContext @@ -2169,6 +2172,7 @@ export const node = LayerNode.make(layer, [ EventV2Bridge.node, RuntimeFlags.node, Database.node, + Question.node, // kilocode_change ]) export * as SessionPrompt from "./prompt" diff --git a/packages/opencode/src/session/summary.ts b/packages/opencode/src/session/summary.ts index 7c6b3effa9..d540de8617 100644 --- a/packages/opencode/src/session/summary.ts +++ b/packages/opencode/src/session/summary.ts @@ -195,6 +195,12 @@ export const DiffInput = Schema.Struct({ }) export type DiffInput = Schema.Schema.Type -export const node = LayerNode.make(layer, [Session.node, Snapshot.node, EventV2Bridge.node, Config.node]) +export const node = LayerNode.make(layer, [ + Session.node, + Snapshot.node, + EventV2Bridge.node, + Config.node, + Storage.node, // kilocode_change +]) export * as SessionSummary from "./summary" diff --git a/packages/opencode/src/share/session.ts b/packages/opencode/src/share/session.ts index fc93de0ba8..322e2b528d 100644 --- a/packages/opencode/src/share/session.ts +++ b/packages/opencode/src/share/session.ts @@ -54,6 +54,6 @@ export const defaultLayer = layer.pipe( Layer.provide(RuntimeFlags.defaultLayer), ) -export const node = LayerNode.make(layer, [Config.node, Session.node, ShareNext.node, RuntimeFlags.node]) +export const node = LayerNode.make(layer, [Config.node, Session.node, RuntimeFlags.node]) // kilocode_change export * as SessionShare from "./session" diff --git a/packages/opencode/src/skill/index.ts b/packages/opencode/src/skill/index.ts index e89c4e7dc5..3f90f6be87 100644 --- a/packages/opencode/src/skill/index.ts +++ b/packages/opencode/src/skill/index.ts @@ -124,9 +124,7 @@ const add = Effect.fnUntraced(function* (state: State, match: Match, events: Eve }).pipe( Effect.catch( Effect.fnUntraced(function* (err) { - const message = FrontmatterError.isInstance(err) - ? err.data.message - : `Failed to parse skill ${match.path}` // kilocode_change + const message = FrontmatterError.isInstance(err) ? err.data.message : `Failed to parse skill ${match.path}` // kilocode_change const { Session } = yield* Effect.promise(() => import("@/session/session")) yield* events.publish(Session.Event.Error, { error: new NamedError.Unknown({ message }).toObject() }) yield* Effect.logError("failed to load skill", { skill: match.path, error: err }) // kilocode_change @@ -418,6 +416,7 @@ export const node = LayerNode.make(layer, [ FSUtil.node, Global.node, RuntimeFlags.node, + Git.node, // kilocode_change ]) export * as Skill from "." diff --git a/packages/opencode/src/snapshot/index.ts b/packages/opencode/src/snapshot/index.ts index 652dd99f11..5b974dfd60 100644 --- a/packages/opencode/src/snapshot/index.ts +++ b/packages/opencode/src/snapshot/index.ts @@ -524,7 +524,7 @@ export const layer: Layer.Layer = const clash = (a: string, b: string) => a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`) - for (let i = 0; i < ops.length;) { + for (let i = 0; i < ops.length; ) { const first = ops[i]! const run = [first] let j = i + 1 @@ -960,6 +960,6 @@ export const defaultLayer = layer.pipe( Layer.provide(EffectFlock.defaultLayer), // kilocode_change ) -export const node = LayerNode.make(layer, [FSUtil.node, AppProcess.node, Config.node]) +export const node = LayerNode.make(layer, [FSUtil.node, AppProcess.node, Config.node, EffectFlock.node]) // kilocode_change export * as Snapshot from "." diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index f21c9a5c4f..fe892d3f4b 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -64,6 +64,9 @@ import * as ToolNetwork from "@/kilocode/sandbox/network" // kilocode_change import { MemoryService } from "@kilocode/kilo-memory/effect/service" // kilocode_change import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" +import { RepositoryCache } from "@opencode-ai/core/repository-cache" // kilocode_change +import { RipgrepBinary } from "@opencode-ai/core/ripgrep/binary" // kilocode_change +import { AppProcess } from "@opencode-ai/core/process" // kilocode_change export function webSearchEnabled( providerID: ProviderV2.ID, @@ -394,6 +397,8 @@ export const defaultLayer: Layer.Layer = Layer.suspend( // kilocode_change start Layer.provide( Ripgrep.layer.pipe( + Layer.provide(RipgrepBinary.layer), + Layer.provide(AppProcess.defaultLayer), Layer.provide(ToolNetwork.httpLayer), Layer.provide(FSUtil.defaultLayer), Layer.provide(CrossSpawnSpawner.defaultLayer), @@ -408,6 +413,7 @@ export const defaultLayer: Layer.Layer = Layer.suspend( Layer.provide(Database.defaultLayer), Layer.provide(RuntimeFlags.defaultLayer), Layer.provide(SessionStatus.defaultLayer), + Layer.provide(RepositoryCache.defaultLayer), Layer.provide(Truncate.defaultLayer), // kilocode_change - split the pipe to stay within Effect's overload limit ) .pipe(Layer.provide(Auth.defaultLayer)), @@ -494,6 +500,7 @@ function isJsonSchemaObject(value: unknown): value is Record { const networkNode = LayerNode.make(ToolNetwork.httpLayer, []) const busNode = LayerNode.make(Bus.layer, []) const notebookNode = LayerNode.make(Notebook.defaultLayer, []) +const repositoryCacheNode = LayerNode.make(RepositoryCache.defaultLayer, []) export const node = LayerNode.make(layer.pipe(Layer.provide(Ripgrep.defaultLayer)), [ Config.node, @@ -521,6 +528,7 @@ export const node = LayerNode.make(layer.pipe(Layer.provide(Ripgrep.defaultLayer Auth.node, SessionStatus.node, notebookNode, + repositoryCacheNode, ]) // kilocode_change end diff --git a/packages/opencode/src/tool/repo_clone.ts b/packages/opencode/src/tool/repo_clone.ts index 3c5a6e8933..990ed45229 100644 --- a/packages/opencode/src/tool/repo_clone.ts +++ b/packages/opencode/src/tool/repo_clone.ts @@ -1,8 +1,9 @@ import { Effect, Schema } from "effect" import DESCRIPTION from "./repo_clone.txt" import * as Tool from "./tool" -import { repositoryCachePath } from "@/util/repository" -import { RepositoryCache } from "@/reference/repository-cache" +import { Global } from "@opencode-ai/core/global" // kilocode_change +import { Repository } from "@opencode-ai/core/repository" // kilocode_change +import { RepositoryCache } from "@opencode-ai/core/repository-cache" // kilocode_change export const Parameters = Schema.Struct({ repository: Schema.String.annotate({ @@ -36,12 +37,12 @@ export const RepoCloneTool = Tool.define, ctx: Tool.Context) => Effect.gen(function* () { - const reference = yield* RepositoryCache.parseRemoteReference(params.repository) + const reference = yield* RepositoryCache.parseRemote(params.repository) if (params.branch) yield* RepositoryCache.validateBranch(params.branch) const repository = reference.label const remote = reference.remote - const localPath = repositoryCachePath(reference) + const localPath = Repository.cachePath(Global.Path.repos, reference) yield* ctx.ask({ permission: "repo_clone", diff --git a/packages/opencode/src/tool/warpgrep.ts b/packages/opencode/src/tool/warpgrep.ts index 52b82f6e8d..891eb0e3f4 100644 --- a/packages/opencode/src/tool/warpgrep.ts +++ b/packages/opencode/src/tool/warpgrep.ts @@ -4,7 +4,7 @@ import { WarpGrepClient } from "@morphllm/morphsdk/tools/warp-grep/client" // ki import { Telemetry } from "@kilocode/kilo-telemetry" // kilocode_change import { Instance } from "../kilocode/instance" // kilocode_change import { EventV2Bridge } from "@/event-v2-bridge" // kilocode_change -import { TuiEvent } from "../cli/cmd/tui/event" // kilocode_change +import { TuiEvent } from "@/server/tui-event" // kilocode_change import DESCRIPTION from "./warpgrep.txt" // FREE_PERIOD_TODO: Remove KILO_WARPGREP_PROXY_URL constant and the proxy diff --git a/packages/opencode/test/cli/tui/markdown.test.ts b/packages/opencode/test/cli/tui/markdown.test.ts index c93470e5fe..c0da26fa41 100644 --- a/packages/opencode/test/cli/tui/markdown.test.ts +++ b/packages/opencode/test/cli/tui/markdown.test.ts @@ -1,6 +1,6 @@ // kilocode_change - new file import { describe, expect, it } from "bun:test" -import { formatMarkdownTables } from "../../../src/cli/cmd/tui/util/markdown" +import { formatMarkdownTables } from "@tui/util/markdown" describe("formatMarkdownTables", () => { it("formats a simple table with fixed-width columns", () => { diff --git a/packages/opencode/test/fixture/fixture.ts b/packages/opencode/test/fixture/fixture.ts index 5817b708e0..6e008eaeee 100644 --- a/packages/opencode/test/fixture/fixture.ts +++ b/packages/opencode/test/fixture/fixture.ts @@ -1,5 +1,5 @@ import { $ } from "bun" -import * as Observability from "@opencode-ai/core/effect/observability" +import * as Observability from "@opencode-ai/core/observability" import { ConfigV1 } from "@opencode-ai/core/v1/config/config" import * as fs from "fs/promises" import os from "os" @@ -24,8 +24,7 @@ import { remove as cleanup } from "../kilocode/cleanup" // kilocode_change const noopBootstrap = Layer.succeed(InstanceBootstrap.Service, InstanceBootstrap.Service.of({ run: Effect.void })) export const testInstanceStoreLayer = InstanceStore.defaultLayer.pipe(Layer.provide(noopBootstrap)) -const makeTestRuntime = () => - ManagedRuntime.make(testInstanceStoreLayer.pipe(Layer.provideMerge(Observability.layer))) +const makeTestRuntime = () => ManagedRuntime.make(testInstanceStoreLayer.pipe(Layer.provideMerge(Observability.layer))) let testRuntime: ReturnType | undefined const runtime = () => (testRuntime ??= makeTestRuntime()) diff --git a/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts b/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts index a17222163a..10065c2028 100644 --- a/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts +++ b/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts @@ -6,8 +6,8 @@ import { describe, expect, test } from "bun:test" import { createEffect, createRoot } from "solid-js" import { createBindingLookup } from "@opentui/keymap/extras" -import { TuiKeybind } from "@/cli/cmd/tui/config/keybind" -import { TuiConfig } from "@/cli/cmd/tui/config/tui" +import { TuiKeybind } from "@tui/config/keybind" +import { TuiConfig } from "@tui/config" import { KiloTuiConfig } from "@/kilocode/cli/cmd/tui/context/tui-config" import { KiloTerminalTitle } from "@/kilocode/cli/cmd/tui/terminal-title" @@ -33,6 +33,7 @@ function resolve(input: TuiConfig.Info): TuiConfig.Resolved { bindingDefaults: TuiKeybind.bindingDefaults(), }), leader_timeout: input.leader_timeout ?? 1_000, + mouse: input.mouse ?? true, } } diff --git a/packages/opencode/test/kilocode/cli/tui/thread.test.ts b/packages/opencode/test/kilocode/cli/tui/thread.test.ts index a6076a03bd..d484707e1f 100644 --- a/packages/opencode/test/kilocode/cli/tui/thread.test.ts +++ b/packages/opencode/test/kilocode/cli/tui/thread.test.ts @@ -2,7 +2,7 @@ import { afterEach, describe, expect, mock, spyOn, test } from "bun:test" import fs from "fs/promises" import path from "path" import { tmpdir } from "../../../fixture/fixture" -import { resolveThreadDirectory } from "../../../../src/cli/cmd/tui/thread" +import { resolveThreadDirectory } from "../../../../src/cli/cmd/tui" import { KiloTuiThreadDaemon } from "../../../../src/kilocode/cli/cmd/tui/thread" import { DaemonClient } from "../../../../src/kilocode/daemon/client" @@ -106,12 +106,12 @@ describe("kilo tui thread", () => { }, }), })) - mock.module("@/cli/cmd/tui/validate-session", () => ({ + mock.module("@/cli/tui/validate-session", () => ({ validateSession: async (input: { sessionID?: string }) => { seen.push(input.sessionID ?? "") }, })) - mock.module("@/cli/cmd/tui/config/tui", () => ({ + mock.module("@/config/tui", () => ({ TuiConfig: { get: async () => ({}), }, diff --git a/packages/opencode/test/kilocode/compaction-payload-recovery.test.ts b/packages/opencode/test/kilocode/compaction-payload-recovery.test.ts index 8d917052bf..f7f18cff17 100644 --- a/packages/opencode/test/kilocode/compaction-payload-recovery.test.ts +++ b/packages/opencode/test/kilocode/compaction-payload-recovery.test.ts @@ -23,7 +23,6 @@ import { MessageV2 } from "../../src/session/message-v2" import * as SessionProcessorModule from "../../src/session/processor" import { Session as SessionNs } from "../../src/session/session" import { MessageID, PartID, SessionID } from "../../src/session/schema" -import { Reference } from "../../src/reference/reference" import { SessionCompaction } from "../../src/session/compaction" import { SessionStatus } from "../../src/session/status" import { SessionSummary } from "../../src/session/summary" @@ -178,11 +177,9 @@ function runtime(layer: Layer.Layer, config = Config.defaultLayer) Layer.provide(config), Layer.provide(RuntimeFlags.layer()), Layer.provide(scope), - Layer.provide(Reference.defaultLayer), Layer.provide(SyncEvent.defaultLayer), Layer.provide(EventV2Bridge.defaultLayer), Layer.provide(Database.defaultLayer), - Layer.provide(Reference.defaultLayer), ), ) } diff --git a/packages/opencode/test/kilocode/instruction.test.ts b/packages/opencode/test/kilocode/instruction.test.ts index 3f8bc529d3..a30feb2a83 100644 --- a/packages/opencode/test/kilocode/instruction.test.ts +++ b/packages/opencode/test/kilocode/instruction.test.ts @@ -7,28 +7,14 @@ import { NodeFileSystem } from "@effect/platform-node" import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner" import { FSUtil } from "@opencode-ai/core/fs-util" import { RuntimeFlags } from "../../src/effect/runtime-flags" -import { Reference } from "../../src/reference/reference" import { Instruction } from "../../src/session/instruction" import { Global } from "@opencode-ai/core/global" import { TestConfig } from "../fixture/config" import { provideInstance, testInstanceStoreLayer, tmpdirScoped } from "../fixture/fixture" import { testEffect } from "../lib/effect" -const reference = Layer.mock(Reference.Service)({ - init: () => Effect.void, - list: () => Effect.succeed([]), - get: () => Effect.succeed(undefined), - ensure: () => Effect.void, - contains: () => Effect.succeed(false), -}) const it = testEffect( - Layer.mergeAll( - CrossSpawnSpawner.defaultLayer, - NodeFileSystem.layer, - reference, - RuntimeFlags.layer(), - testInstanceStoreLayer, - ), + Layer.mergeAll(CrossSpawnSpawner.defaultLayer, NodeFileSystem.layer, RuntimeFlags.layer(), testInstanceStoreLayer), ) const configLayer = TestConfig.layer() diff --git a/packages/opencode/test/kilocode/plan-followup.test.ts b/packages/opencode/test/kilocode/plan-followup.test.ts index 9e6b01acc7..4a1125dbff 100644 --- a/packages/opencode/test/kilocode/plan-followup.test.ts +++ b/packages/opencode/test/kilocode/plan-followup.test.ts @@ -5,7 +5,7 @@ import { Global } from "@opencode-ai/core/global" import * as Log from "@opencode-ai/core/util/log" import { Agent } from "../../src/agent/agent" import { GlobalBus } from "../../src/bus/global" -import { TuiEvent } from "../../src/cli/cmd/tui/event" +import { TuiEvent } from "../../src/server/tui-event" import { Identifier } from "../../src/id/id" import { SessionID, MessageID, PartID } from "../../src/session/schema" import { ProviderV2 } from "@opencode-ai/core/provider" @@ -68,16 +68,11 @@ const todo = { const session = makeRuntime(Session.Service, Session.defaultLayer) const store = { - create: (input?: Parameters[0]) => - session.runPromise((svc) => svc.create(input)), - get: (id: SessionID) => - session.runPromise((svc) => svc.get(id)), - messages: (input: Parameters[0]) => - session.runPromise((svc) => svc.messages(input)), - updateMessage: (msg: T) => - session.runPromise((svc) => svc.updateMessage(msg)), - updatePart: (part: T) => - session.runPromise((svc) => svc.updatePart(part)), + create: (input?: Parameters[0]) => session.runPromise((svc) => svc.create(input)), + get: (id: SessionID) => session.runPromise((svc) => svc.get(id)), + messages: (input: Parameters[0]) => session.runPromise((svc) => svc.messages(input)), + updateMessage: (msg: T) => session.runPromise((svc) => svc.updateMessage(msg)), + updatePart: (part: T) => session.runPromise((svc) => svc.updatePart(part)), } const model = { @@ -901,7 +896,9 @@ describe("plan follow-up", () => { test("ask - falls back to configured code model when saved CLI code model is unavailable", () => withInstance(async () => { - await writeState({ model: { code: { providerID: ProviderV2.ID.make("missing"), modelID: ModelV2.ID.make("ghost") } } }) + await writeState({ + model: { code: { providerID: ProviderV2.ID.make("missing"), modelID: ModelV2.ID.make("ghost") } }, + }) const get = spyOn(PlanFollowupRuntime, "agent").mockImplementation(async (name: string) => { if (name === "code") { return { diff --git a/packages/opencode/test/kilocode/session-compaction-cap.test.ts b/packages/opencode/test/kilocode/session-compaction-cap.test.ts index 5419c7fbac..9760ace328 100644 --- a/packages/opencode/test/kilocode/session-compaction-cap.test.ts +++ b/packages/opencode/test/kilocode/session-compaction-cap.test.ts @@ -18,7 +18,7 @@ import { RuntimeFlags } from "../../src/effect/runtime-flags" import { EventV2Bridge } from "../../src/event-v2-bridge" import * as CrossSpawnSpawner from "@opencode-ai/core/cross-spawn-spawner" import { Env } from "../../src/env" -import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep" +import { Ripgrep } from "@opencode-ai/core/ripgrep" import { FSUtil } from "@opencode-ai/core/fs-util" import { Format } from "../../src/format" import { Git } from "../../src/git" @@ -33,8 +33,7 @@ import { Provider as ProviderSvc } from "../../src/provider/provider" import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" import { Question } from "../../src/question" -import { Reference } from "../../src/reference/reference" -import { RepositoryCache } from "../../src/reference/repository-cache" +import { RepositoryCache } from "@opencode-ai/core/repository-cache" import { Session } from "../../src/session/session" import { SessionCompaction } from "../../src/session/compaction" import { Instruction } from "../../src/session/instruction" @@ -154,7 +153,6 @@ function makeHttp() { SyncEvent.defaultLayer, EventV2Bridge.defaultLayer, Database.defaultLayer, - Reference.defaultLayer, status, MemoryService.layer, ).pipe(Layer.provideMerge(infra)) @@ -208,7 +206,6 @@ function makeHttp() { Bus.layer, infra, Storage.defaultLayer, - Reference.defaultLayer, ), ), ) diff --git a/packages/opencode/test/kilocode/session-compaction-chunks.test.ts b/packages/opencode/test/kilocode/session-compaction-chunks.test.ts index d9d84a2908..222235437a 100644 --- a/packages/opencode/test/kilocode/session-compaction-chunks.test.ts +++ b/packages/opencode/test/kilocode/session-compaction-chunks.test.ts @@ -22,7 +22,6 @@ import { KiloCompactionChunks } from "../../src/kilocode/session/compaction-chun import { KiloSessionCompaction } from "../../src/kilocode/session/compaction" import { LLM } from "../../src/session/llm" import { MessageV2 } from "../../src/session/message-v2" -import { Reference } from "../../src/reference/reference" import { SessionCompaction } from "../../src/session/compaction" import * as SessionProcessorModule from "../../src/session/processor" import type { SessionProcessor } from "../../src/session/processor" @@ -40,6 +39,9 @@ import { remove as cleanup } from "./cleanup" const providerID = ProviderV2.ID.make("test") const modelID = ModelV2.ID.make("test-model") const ref = { providerID, modelID } +const agents = Layer.mock(Agent.Service)({ + get: () => Effect.succeed({ name: "compaction", mode: "primary", permission: [], options: {} } satisfies Agent.Info), +}) const previous = Flag.KILO_DB const dbfile = path.join(os.tmpdir(), `kilo-compaction-chunks-${process.pid}-${crypto.randomUUID()}.db`) @@ -227,13 +229,12 @@ function fakeRuntime(outputTokenMax?: number, error?: MessageV2.Assistant["error Layer.mergeAll(SessionCompaction.layer.pipe(Layer.provide(processor)), processor, bus).pipe( Layer.provide(ProviderTest.fake({ model }).layer), Layer.provide(SessionNs.defaultLayer), - Layer.provide(Agent.defaultLayer), + Layer.provide(agents), Layer.provide(Plugin.defaultLayer), Layer.provide(SyncEvent.defaultLayer), Layer.provide(EventV2Bridge.defaultLayer), Layer.provide(Database.defaultLayer), Layer.provide(RuntimeFlags.layer({ outputTokenMax })), - Layer.provide(Reference.defaultLayer), Layer.provide(bus), Layer.provide( Layer.mock(Config.Service)({ @@ -309,7 +310,6 @@ function liveRuntime(layer: Layer.Layer, context = 10_000) { Layer.provide(EventV2Bridge.defaultLayer), Layer.provide(Database.defaultLayer), Layer.provide(RuntimeFlags.layer()), - Layer.provide(Reference.defaultLayer), Layer.provide(status), Layer.provide(bus), Layer.provide( diff --git a/packages/opencode/test/kilocode/session-processor-empty-tool-calls.test.ts b/packages/opencode/test/kilocode/session-processor-empty-tool-calls.test.ts index d76d8c6d10..3c53f10bdd 100644 --- a/packages/opencode/test/kilocode/session-processor-empty-tool-calls.test.ts +++ b/packages/opencode/test/kilocode/session-processor-empty-tool-calls.test.ts @@ -16,7 +16,6 @@ import { Plugin } from "../../src/plugin" import type { Provider } from "../../src/provider/provider" import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" -import { Reference } from "../../src/reference/reference" import { Session } from "../../src/session/session" import { LLM } from "../../src/session/llm" import { MessageV2 } from "../../src/session/message-v2" @@ -100,13 +99,6 @@ const llm = Layer.unwrap( }), ) -const reference = Layer.mock(Reference.Service)({ - init: () => Effect.void, - list: () => Effect.succeed([]), - get: () => Effect.succeed(undefined), - ensure: () => Effect.void, - contains: () => Effect.succeed(false), -}) const status = Layer.mergeAll(SessionStatus.defaultLayer, Bus.layer) const infra = Layer.mergeAll(NodeFileSystem.layer, CrossSpawnSpawner.defaultLayer) const deps = Layer.mergeAll( @@ -117,7 +109,6 @@ const deps = Layer.mergeAll( Plugin.defaultLayer, Config.defaultLayer, RuntimeFlags.layer(), - reference, SessionSummary.defaultLayer, Image.defaultLayer, SyncEvent.defaultLayer, @@ -126,7 +117,7 @@ const deps = Layer.mergeAll( status, llm, ).pipe(Layer.provideMerge(infra)) -const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps), Layer.provide(reference)) +const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps)) const it = testEffect(env) @@ -489,9 +480,7 @@ describe("session processor empty tool-calls", () => { LLMEvent.stepFinish({ index: 0, reason: "stop", usage: usage() }), LLMEvent.finish({ reason: "stop", usage: usage() }), ).pipe( - Stream.tap((event) => - event.type === "step-finish" ? state.session.remove(state.chat.id) : Effect.void, - ), + Stream.tap((event) => (event.type === "step-finish" ? state.session.remove(state.chat.id) : Effect.void)), ), ) const result = yield* state.handle.process(state.input) diff --git a/packages/opencode/test/kilocode/session-processor-network-offline.test.ts b/packages/opencode/test/kilocode/session-processor-network-offline.test.ts index 022f6baf27..1d04473d5c 100644 --- a/packages/opencode/test/kilocode/session-processor-network-offline.test.ts +++ b/packages/opencode/test/kilocode/session-processor-network-offline.test.ts @@ -16,7 +16,6 @@ import { Plugin } from "../../src/plugin" import type { Provider } from "../../src/provider/provider" import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" -import { Reference } from "../../src/reference/reference" import { Session } from "../../src/session/session" import { LLM } from "../../src/session/llm" import { MessageV2 } from "../../src/session/message-v2" @@ -98,13 +97,6 @@ const llm = Layer.unwrap( }), ) -const reference = Layer.mock(Reference.Service)({ - init: () => Effect.void, - list: () => Effect.succeed([]), - get: () => Effect.succeed(undefined), - ensure: () => Effect.void, - contains: () => Effect.succeed(false), -}) const status = Layer.mergeAll(SessionStatus.defaultLayer, Bus.layer) const infra = Layer.mergeAll(NodeFileSystem.layer, CrossSpawnSpawner.defaultLayer) const deps = Layer.mergeAll( @@ -115,7 +107,6 @@ const deps = Layer.mergeAll( Plugin.defaultLayer, Config.defaultLayer, RuntimeFlags.layer(), - reference, SessionSummary.defaultLayer, Image.defaultLayer, SyncEvent.defaultLayer, @@ -124,7 +115,7 @@ const deps = Layer.mergeAll( status, llm, ).pipe(Layer.provideMerge(infra)) -const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps), Layer.provide(reference)) +const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps)) const it = testEffect(env) diff --git a/packages/opencode/test/kilocode/session-processor-retry-limit.test.ts b/packages/opencode/test/kilocode/session-processor-retry-limit.test.ts index 266da10cc5..f7220f1084 100644 --- a/packages/opencode/test/kilocode/session-processor-retry-limit.test.ts +++ b/packages/opencode/test/kilocode/session-processor-retry-limit.test.ts @@ -23,7 +23,6 @@ import { Plugin } from "../../src/plugin" import type { Provider } from "../../src/provider/provider" import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" -import { Reference } from "../../src/reference/reference" import { Session } from "../../src/session/session" import { LLM } from "../../src/session/llm" import { MessageV2 } from "../../src/session/message-v2" @@ -111,13 +110,6 @@ const llm = Layer.unwrap( }), ) -const reference = Layer.mock(Reference.Service)({ - init: () => Effect.void, - list: () => Effect.succeed([]), - get: () => Effect.succeed(undefined), - ensure: () => Effect.void, - contains: () => Effect.succeed(false), -}) const status = Layer.mergeAll(SessionStatus.defaultLayer, Bus.layer) const infra = Layer.mergeAll(NodeFileSystem.layer, CrossSpawnSpawner.defaultLayer) const deps = Layer.mergeAll( @@ -128,7 +120,6 @@ const deps = Layer.mergeAll( Plugin.defaultLayer, Config.defaultLayer, RuntimeFlags.layer(), - reference, SessionSummary.defaultLayer, Image.defaultLayer, SyncEvent.defaultLayer, @@ -137,7 +128,7 @@ const deps = Layer.mergeAll( status, llm, ).pipe(Layer.provideMerge(infra)) -const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps), Layer.provide(reference)) +const env = SessionProcessor.layer.pipe(Layer.provideMerge(deps)) const it = testEffect(env) diff --git a/packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts b/packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts index 40a69e0a7d..003218c596 100644 --- a/packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts +++ b/packages/opencode/test/kilocode/session-prompt-compaction-safety.test.ts @@ -17,7 +17,7 @@ import { RuntimeFlags } from "../../src/effect/runtime-flags" import { EventV2Bridge } from "../../src/event-v2-bridge" import * as CrossSpawnSpawner from "@opencode-ai/core/cross-spawn-spawner" import { Env } from "../../src/env" -import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep" +import { Ripgrep } from "@opencode-ai/core/ripgrep" import { FSUtil } from "@opencode-ai/core/fs-util" import { Format } from "../../src/format" import { Git } from "../../src/git" @@ -30,8 +30,7 @@ import { Provider as ProviderSvc } from "../../src/provider/provider" import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" import { Question } from "../../src/question" -import { Reference } from "../../src/reference/reference" -import { RepositoryCache } from "../../src/reference/repository-cache" +import { RepositoryCache } from "@opencode-ai/core/repository-cache" import { Session } from "../../src/session/session" import { SessionCompaction } from "../../src/session/compaction" import { Instruction } from "../../src/session/instruction" @@ -144,7 +143,6 @@ function makeHttp() { lsp, mcp, FSUtil.defaultLayer, - Reference.defaultLayer, SyncEvent.defaultLayer, EventV2Bridge.defaultLayer, Database.defaultLayer, @@ -161,7 +159,6 @@ function makeHttp() { Layer.provide(Ripgrep.defaultLayer), Layer.provide(Format.defaultLayer), Layer.provide(Git.defaultLayer), - Layer.provide(Reference.defaultLayer), Layer.provide(Command.defaultLayer), Layer.provide(Auth.defaultLayer), // kilocode_change Layer.provideMerge(todo), @@ -202,7 +199,6 @@ function makeHttp() { Bus.layer, infra, Storage.defaultLayer, - Reference.defaultLayer, ), ), ) diff --git a/packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts b/packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts index d6ab499ebf..cfcfa64409 100644 --- a/packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts +++ b/packages/opencode/test/kilocode/session-prompt-permission-refresh.test.ts @@ -25,8 +25,7 @@ import { Permission } from "../../src/permission" import { Plugin } from "../../src/plugin" import { Provider as ProviderSvc } from "../../src/provider/provider" import { Question } from "../../src/question" -import { Reference } from "../../src/reference/reference" -import { RepositoryCache } from "../../src/reference/repository-cache" +import { RepositoryCache } from "@opencode-ai/core/repository-cache" import { SessionCompaction } from "../../src/session/compaction" import { Instruction } from "../../src/session/instruction" import { LLM } from "../../src/session/llm" @@ -43,7 +42,7 @@ import { Skill } from "../../src/skill" import { Snapshot } from "../../src/snapshot" import { Storage } from "../../src/storage/storage" import { SyncEvent } from "../../src/sync" -import { Ripgrep } from "@opencode-ai/core/filesystem/ripgrep" +import { Ripgrep } from "@opencode-ai/core/ripgrep" import { ToolRegistry } from "../../src/tool/registry" import { Truncate } from "../../src/tool/truncate" import { KiloHeadless } from "../../src/kilocode/permission/headless" @@ -139,7 +138,6 @@ function makeHttp() { lsp, mcp, FSUtil.defaultLayer, - Reference.defaultLayer, SyncEvent.defaultLayer, EventV2Bridge.defaultLayer, Database.defaultLayer, @@ -156,7 +154,6 @@ function makeHttp() { Layer.provide(Ripgrep.defaultLayer), Layer.provide(Format.defaultLayer), Layer.provide(Git.defaultLayer), - Layer.provide(Reference.defaultLayer), Layer.provide(Command.defaultLayer), Layer.provide(Auth.defaultLayer), // kilocode_change Layer.provideMerge(todo), @@ -197,7 +194,6 @@ function makeHttp() { Bus.layer, infra, Storage.defaultLayer, - Reference.defaultLayer, ), ), ) @@ -341,8 +337,8 @@ it.live("headless run: subagent permission asks fail instead of waiting forever" expect(err).toBeInstanceOf(Permission.DeniedError) expect(yield* permission.list()).toEqual([]) - expect(yield* KiloHeadless.denies(child.id)).toBe(true) - expect(yield* KiloHeadless.denies(root.id)).toBe(false) + expect(yield* KiloHeadless.denies(child.id)).toBe(true) + expect(yield* KiloHeadless.denies(root.id)).toBe(false) KiloHeadless.clear(root.id) }), diff --git a/packages/opencode/test/kilocode/tool/repo_clone.test.ts b/packages/opencode/test/kilocode/tool/repo_clone.test.ts index 9c9e68ab19..27ddeaf4ec 100644 --- a/packages/opencode/test/kilocode/tool/repo_clone.test.ts +++ b/packages/opencode/test/kilocode/tool/repo_clone.test.ts @@ -10,7 +10,7 @@ import { Global } from "@opencode-ai/core/global" import { MessageID, SessionID } from "../../../src/session/schema" import { Truncate } from "../../../src/tool/truncate" import { RepoCloneTool } from "../../../src/tool/repo_clone" -import { RepositoryCache } from "../../../src/reference/repository-cache" +import { RepositoryCache } from "@opencode-ai/core/repository-cache" import { disposeAllInstances, provideTmpdirInstance, tmpdirScoped } from "../../fixture/fixture" import { testEffect } from "../../lib/effect" diff --git a/packages/opencode/test/kilocode/tui-sync-event.test.ts b/packages/opencode/test/kilocode/tui-sync-event.test.ts index b37234d08e..b5d3041a44 100644 --- a/packages/opencode/test/kilocode/tui-sync-event.test.ts +++ b/packages/opencode/test/kilocode/tui-sync-event.test.ts @@ -1,8 +1,8 @@ /** @jsxImportSource @opentui/solid */ import { describe, expect, test } from "bun:test" import type { BackgroundProcessInfo, GlobalEvent } from "@kilocode/sdk/v2" -import { normalizeSyncEvent } from "../../src/cli/cmd/tui/context/event" -import { mount, wait } from "../cli/cmd/tui/sync-fixture" +import { normalizeSyncEvent } from "@tui/context/event" +import { mount, wait } from "../../../tui/test/cli/cmd/tui/sync-fixture" function processInfo(id: string, sessionID: string, lifetime: BackgroundProcessInfo["lifetime"], updated: number) { return { @@ -80,7 +80,7 @@ describe("TUI sync event wire format", () => { try { emit({ directory: "/tmp/opencode/packages/opencode", - project: "proj_test", + project: "proj_other", payload: { type: "background_process.updated", properties: { diff --git a/packages/opencode/test/kilocode/tui/signal.test.ts b/packages/opencode/test/kilocode/tui/signal.test.ts index d9349730d1..4fe09db430 100644 --- a/packages/opencode/test/kilocode/tui/signal.test.ts +++ b/packages/opencode/test/kilocode/tui/signal.test.ts @@ -1,6 +1,5 @@ import { describe, expect, test } from "bun:test" import { createRoot } from "solid-js" -import { createLeadingTrailingSignal } from "@tui/feature-plugins/session/preview-pane" import { createDebouncedSignal } from "@tui/util/signal" describe("TUI scheduling", () => { @@ -17,24 +16,4 @@ describe("TUI scheduling", () => { dispose() }) }) - - test("updates on the leading and trailing edges", async () => { - await createRoot(async (dispose) => { - const [value, , schedule] = createLeadingTrailingSignal("initial", 10) - - schedule("leading") - expect(value()).toBe("leading") - - schedule("middle") - schedule("trailing") - expect(value()).toBe("leading") - - await Bun.sleep(30) - expect(value()).toBe("trailing") - - schedule("next") - expect(value()).toBe("next") - dispose() - }) - }) }) diff --git a/packages/opencode/test/lib/effect.ts b/packages/opencode/test/lib/effect.ts index 0a8a1f7bd1..dbcb90be68 100644 --- a/packages/opencode/test/lib/effect.ts +++ b/packages/opencode/test/lib/effect.ts @@ -6,7 +6,6 @@ import * as TestClock from "effect/testing/TestClock" import * as TestConsole from "effect/testing/TestConsole" import { memoMap } from "@opencode-ai/core/effect/memo-map" import type { Config } from "@/config/config" -import { Reference } from "@/reference/reference" // kilocode_change import { TestInstance, withTmpdirInstance } from "../fixture/fixture" import { InstanceStore } from "@/project/instance-store" @@ -138,10 +137,8 @@ const liveEnv = TestConsole.layer export const it = make(testEnv, liveEnv) // kilocode_change start -export const testEffect = (layer: Layer.Layer) => { - const full = Layer.merge(layer, Reference.defaultLayer) - return make(Layer.provideMerge(full, testEnv), Layer.provideMerge(full, liveEnv)) -} +export const testEffect = (layer: Layer.Layer) => + make(Layer.provideMerge(layer, testEnv), Layer.provideMerge(layer, liveEnv)) export const testEffectBare = (layer: Layer.Layer) => make(Layer.provideMerge(layer, testEnv), Layer.provideMerge(layer, liveEnv)) // kilocode_change end diff --git a/packages/opencode/test/preload.ts b/packages/opencode/test/preload.ts index c171389d9d..8148df53a1 100644 --- a/packages/opencode/test/preload.ts +++ b/packages/opencode/test/preload.ts @@ -3,6 +3,7 @@ import os from "os" import path from "path" import fs from "fs/promises" +import { setTimeout as sleep } from "node:timers/promises" import { afterAll } from "bun:test" import { remove as cleanup } from "./kilocode/cleanup" // kilocode_change diff --git a/packages/opencode/test/server/httpapi-event.test.ts b/packages/opencode/test/server/httpapi-event.test.ts index b3620538be..a9240e9a02 100644 --- a/packages/opencode/test/server/httpapi-event.test.ts +++ b/packages/opencode/test/server/httpapi-event.test.ts @@ -259,7 +259,7 @@ describe("event HttpApi", () => { timestamp, messageID: SessionMessageID.ID.create(), delivery: "queue", - prompt: new Prompt({ text: "hello", files: [], agents: [], references: [] }), // kilocode_change - upstream made prompt a Prompt class + prompt: new Prompt({ text: "hello", files: [], agents: [] }), // kilocode_change - upstream made prompt a Prompt class }) expect(properties(yield* Fiber.join(prompted))).toMatchObject({ timestamp: 1_234, diff --git a/packages/opencode/test/session/processor-effect.test.ts b/packages/opencode/test/session/processor-effect.test.ts index 80cdf1f91d..a27348a489 100644 --- a/packages/opencode/test/session/processor-effect.test.ts +++ b/packages/opencode/test/session/processor-effect.test.ts @@ -187,15 +187,15 @@ const env = LayerNode.buildLayer(LayerNode.group([root, LayerNode.make(TestLLMSe const it = testEffect(env) // kilocode_change start - exercise non-default output token ceilings in the processor const capped = testEffect( - Layer.mergeAll( - TestLLMServer.layer, - SessionProcessor.layer.pipe( - Layer.provide(summary), - Layer.provide(Image.defaultLayer), - Layer.provide(RuntimeFlags.layer({ experimentalEventSystem: true, outputTokenMax: 8_000 })), - Layer.provideMerge(deps), - ), - ), + LayerNode.buildLayer(LayerNode.group([root, LayerNode.make(TestLLMServer.layer, [])]), { + replacements: [ + LayerNode.replace(SessionSummary.node, summary), + LayerNode.replace( + RuntimeFlags.node, + RuntimeFlags.layer({ experimentalEventSystem: true, outputTokenMax: 8_000 }), + ), + ], + }), ) // kilocode_change end diff --git a/packages/opencode/test/session/prompt.test.ts b/packages/opencode/test/session/prompt.test.ts index d9dc7a8c92..e8332ff7fd 100644 --- a/packages/opencode/test/session/prompt.test.ts +++ b/packages/opencode/test/session/prompt.test.ts @@ -63,6 +63,7 @@ import { awaitWithTimeout, pollWithTimeout, testEffect } from "../lib/effect" import { reply, TestLLMServer } from "../lib/llm-server" import { RuntimeFlags } from "@/effect/runtime-flags" import { MemoryService } from "@kilocode/kilo-memory/effect/service" // kilocode_change +import { RepositoryCache } from "@opencode-ai/core/repository-cache" // kilocode_change import { ProviderV2 } from "@opencode-ai/core/provider" import { ModelV2 } from "@opencode-ai/core/model" @@ -225,6 +226,7 @@ function makePrompt(input?: { processor?: "blocking" }) { Layer.provide(CrossSpawnSpawner.defaultLayer), Layer.provide(Git.defaultLayer), Layer.provide(Ripgrep.defaultLayer), + Layer.provide(RepositoryCache.defaultLayer), // kilocode_change - RepoCloneTool dependency Layer.provide(Format.defaultLayer), Layer.provide(RuntimeFlags.layer({ experimentalEventSystem: true })), Layer.provide(Auth.defaultLayer), // kilocode_change @@ -705,7 +707,7 @@ it.instance("loop surfaces content-filter finishes as session errors", () => const off = yield* events.listen((event) => { if (event.type !== Session.Event.Error.type) return Effect.void const data = event.data as typeof Session.Event.Error.data.Type - if (data.sessionID === chat.id && data.error) errors.push(data.error) + if (data.sessionID === chat.id && data.error?.name === "ContentFilterError") errors.push(data.error) return Effect.void }) @@ -1046,7 +1048,7 @@ it.instance("subtask child inherits parent session external_directory allow", () }), ) -noLLMServer.instance("prompt tools replace previous prompt tool rules", () => +noLLMServer.instance("prompt tools replace matching rules and preserve existing restrictions", () => Effect.gen(function* () { const prompt = yield* SessionPrompt.Service const sessions = yield* Session.Service @@ -1068,8 +1070,13 @@ noLLMServer.instance("prompt tools replace previous prompt tool rules", () => }) const reloaded = yield* sessions.get(session.id) - expect(reloaded.permission).toEqual([{ permission: "read", pattern: "*", action: "allow" }]) - expect(Permission.evaluate("bash", "anything", reloaded.permission ?? []).action).toBe("ask") + // kilocode_change start - Kilo preserves existing restrictions that the new prompt does not override + expect(reloaded.permission).toEqual([ + { permission: "bash", pattern: "*", action: "deny" }, + { permission: "read", pattern: "*", action: "allow" }, + ]) + expect(Permission.evaluate("bash", "anything", reloaded.permission ?? []).action).toBe("deny") + // kilocode_change end }), ) diff --git a/packages/opencode/test/tool/task.test.ts b/packages/opencode/test/tool/task.test.ts index 2726abb08b..306ffb473c 100644 --- a/packages/opencode/test/tool/task.test.ts +++ b/packages/opencode/test/tool/task.test.ts @@ -489,7 +489,7 @@ describe("tool.task", () => { ]), ) // kilocode_change end - expect(seen?.tools).toBeUndefined({ + expect(seen?.tools).toEqual({ question: false, // kilocode_change - subagents cannot prompt the user directly interactive_terminal: false, // kilocode_change - subagents cannot take over the user's terminal todowrite: false, diff --git a/packages/opencode/tsconfig.json b/packages/opencode/tsconfig.json index bd4cbe0554..af90a833ab 100644 --- a/packages/opencode/tsconfig.json +++ b/packages/opencode/tsconfig.json @@ -10,6 +10,7 @@ "customConditions": ["browser"], "paths": { "@/*": ["./src/*"], + "@tui/*": ["../tui/src/*"], // kilocode_change - extracted TUI imports used by Kilo-owned components "@test/*": ["./test/*"] } } diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 92be5458f6..0a7cdc371d 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -5,7 +5,35 @@ export type ClientOptions = { } export type Event = - | EventModelsDevRefreshed + | EventServerInstanceDisposed + | EventSessionNetworkAsked + | EventSessionNetworkReplied + | EventSessionNetworkRejected + | EventSessionNetworkRestored + | EventBackgroundProcessUpdated + | EventBackgroundProcessDeleted + | EventInteractiveTerminalUpdated + | EventInteractiveTerminalData + | EventInteractiveTerminalDeleted + | EventSessionTurnOpen + | EventSessionTurnClose + | EventSandboxStatusChanged + | EventSuggestionShown + | EventSuggestionAccepted + | EventSuggestionDismissed + | EventKilocodeAgentManagerStart + | EventKilocodeNotebookRequested + | EventKilocodeNotebookCancelled + | EventLspClientDiagnostics + | EventKiloSessionsRemoteStatusChanged + | EventMemoryStatus1 + | EventMemoryUpdated1 + | EventMemoryError1 + | EventIndexingStatus + | EventIndexingWarning + | EventServerConnected + | EventGlobalDisposed + | EventGlobalConfigUpdated | EventCredentialAdded | EventCredentialRemoved | EventCredentialSwitched @@ -49,16 +77,28 @@ export type Event = | EventSessionNextCompactionStarted | EventSessionNextCompactionDelta | EventSessionNextCompactionEnded + | EventQuestionAsked + | EventQuestionReplied + | EventQuestionRejected + | EventTuiPromptAppend + | EventTuiCommandExecute + | EventTuiToastShow1 + | EventTuiSessionSelect + | EventMcpToolsChanged + | EventMcpBrowserOpenFailed | EventMessagePartDelta | EventSessionDiff | EventSessionError + | EventModelsDevRefreshed | EventInstallationUpdated | EventInstallationUpdateAvailable - | EventFileEdited + | EventPermissionAsked + | EventPermissionReplied | EventConnectorUpdated | EventPermissionV2Asked | EventPermissionV2Replied | EventReferenceUpdated + | EventFileEdited | EventFileWatcherUpdated | EventPtyCreated | EventPtyUpdated @@ -68,33 +108,19 @@ export type Event = | EventQuestionV2Replied | EventQuestionV2Rejected | EventTodoUpdated - | EventLspUpdated - | EventPermissionAsked - | EventPermissionReplied - | EventTuiPromptAppend2 - | EventTuiCommandExecute2 - | EventTuiToastShow2 - | EventTuiSessionSelect2 - | EventMcpToolsChanged - | EventMcpBrowserOpenFailed - | EventCommandExecuted - | EventProjectDirectoriesUpdated - | EventProjectUpdated - | EventVcsBranchUpdated - | EventQuestionAsked - | EventQuestionReplied - | EventQuestionRejected | EventSessionStatus | EventSessionIdle | EventSessionCompacted - | EventWorktreeReady - | EventWorktreeFailed + | EventCommandExecuted + | EventProjectDirectoriesUpdated + | EventProjectUpdated + | EventLspUpdated + | EventVcsBranchUpdated | EventWorkspaceReady | EventWorkspaceFailed | EventWorkspaceStatus - | EventServerConnected - | EventGlobalDisposed - | EventServerInstanceDisposed + | EventWorktreeReady + | EventWorktreeFailed export type QuestionReplied = { sessionID: string @@ -150,6 +176,156 @@ export type MoveSessionError = { } } +export type SessionNetworkWait = { + id: string + sessionID: string + message: string + restored: boolean + time: { + created: number + restored?: number + } +} + +export type BackgroundProcessInfo = { + id: string + sessionID: string + pid?: number + command: string + cwd: string + description?: string + ports: Array + status: "starting" | "running" | "ready" | "exited" | "failed" | "stopping" | "stopped" + lifetime: "session" | "parent" | "persistent" + ready: boolean + exitCode?: number + signal?: string + output: string + time: { + started: number + updated: number + ended?: number + } +} + +export type InteractiveTerminalInfo = { + id: string + sessionID: string + pid: number + command: string + cwd: string + description?: string + status: "running" | "closed" + cols: number + rows: number + exitCode?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + signal?: string + closedBy?: "exit" | "user" | "abort" + time: { + started: number + updated: number + ended?: number + } +} + +export type SuggestionRequest = { + id: string + sessionID: string + text: string + actions: Array<{ + /** + * Button or option label (1-5 words) + */ + label: string + description?: string + /** + * Synthetic user prompt to inject when this action is accepted + */ + prompt: string + }> + blocking?: boolean + tool?: { + messageID: string + callID: string + } +} + +export type NotebookRequestId = string + +export type NotebookReadRequest = { + id: NotebookRequestId + sessionID: string + path: string + operation: "read" + includeOutputs: boolean +} + +export type NotebookEditRequest = { + id: NotebookRequestId + sessionID: string + path: string + operation: "edit" + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + expectedRevision?: string + /** + * Zero-based cell index + */ + index: number + edit: + | { + action: "insert" + kind: "code" | "markdown" + language?: string + source: string + } + | { + action: "replace" + kind: "code" | "markdown" + language?: string + source: string + } + | { + action: "delete" + } + | { + action: "create" + } +} + +export type NotebookExecuteRequest = { + id: NotebookRequestId + sessionID: string + path: string + operation: "execute" + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + expectedRevision: string + /** + * Zero-based cell index + */ + index: number +} + +export type NotebookRequest = NotebookReadRequest | NotebookEditRequest | NotebookExecuteRequest + +export type IndexingStatusState = "Disabled" | "In Progress" | "Complete" | "Error" | "Standby" + +export type IndexingStatus = { + state: IndexingStatusState + message: string + processedFiles: number + totalFiles: number + percent: number +} + +export type IndexingWarning = { + code: "qdrant.version-incompatible" | "qdrant.version-unavailable" + message: string +} + export type SnapshotFileDiff = { file?: string patch?: string @@ -260,6 +436,12 @@ export type UserMessage = { tools?: { [key: string]: boolean } + editorContext?: { + visibleFiles?: Array + openTabs?: Array + activeFile?: string + shell?: string + } } export type ProviderAuthError = { @@ -560,6 +742,10 @@ export type StepFinishPart = { type: "step-finish" reason: string snapshot?: string + model?: { + providerID: string + modelID: string + } cost: number tokens: { total?: number @@ -645,31 +831,6 @@ export type Prompt = { agents?: Array } -export type Pty = { - id: string - title: string - command: string - args: Array - cwd: string - status: "running" | "exited" - pid: number -} - -export type Todo = { - /** - * Brief description of the task - */ - content: string - /** - * Current status of the task: pending, in_progress, completed, cancelled - */ - status: string - /** - * Priority level of the task: high, medium, low - */ - priority: string -} - export type QuestionOption = { /** * Display text (1-5 words, concise) @@ -679,6 +840,9 @@ export type QuestionOption = { * Explanation of choice */ description: string + labelKey?: string + descriptionKey?: string + mode?: string } export type QuestionInfo = { @@ -695,6 +859,8 @@ export type QuestionInfo = { */ options: Array multiple?: boolean + questionKey?: string + headerKey?: string custom?: boolean } @@ -705,6 +871,111 @@ export type QuestionTool = { export type QuestionAnswer = Array +export type EventTuiPromptAppend = { + id: string + type: "tui.prompt.append" + properties: { + text: string + } +} + +export type EventTuiCommandExecute = { + id: string + type: "tui.command.execute" + properties: { + command: + | "session.list" + | "session.new" + | "session.share" + | "session.interrupt" + | "session.compact" + | "session.page.up" + | "session.page.down" + | "session.line.up" + | "session.line.down" + | "session.half.page.up" + | "session.half.page.down" + | "session.first" + | "session.last" + | "prompt.clear" + | "prompt.submit" + | "agent.cycle" + | string + } +} + +export type EventTuiToastShow = { + id: string + type: "tui.toast.show" + properties: { + title?: string + message: string + variant: "info" | "success" | "warning" | "error" + duration?: number + } +} + +export type EventTuiSessionSelect = { + id: string + type: "tui.session.select" + properties: { + /** + * Session ID to navigate to + */ + sessionID: string + } +} + +export type AgentRequirementError = { + name: "AgentRequirementError" + data: { + message: string + agent: string + directory: string + state: "blocked" | "error" + skills: Array<{ + name: string + status: "ready" | "missing" | "error" + message?: string + }> + mcps: Array<{ + name: string + status: "ready" | "missing" | "error" + message?: string + }> + vscode_extensions: Array<{ + name: string + id: string + }> + } +} + +export type Pty = { + id: string + title: string + command: string + args: Array + cwd: string + status: "running" | "exited" + pid: number + sessionID?: string | null +} + +export type Todo = { + /** + * Brief description of the task + */ + content: string + /** + * Current status of the task: pending, in_progress, completed, cancelled + */ + status: string + /** + * Priority level of the task: high, medium, low + */ + priority: string +} + export type SessionStatus = | { type: "idle" @@ -726,930 +997,133 @@ export type SessionStatus = | { type: "busy" } + | { + type: "offline" + requestID: string + message: string + } export type GlobalEvent = { directory: string project?: string workspace?: string payload: - | { - id: string - type: "models-dev.refreshed" - properties: { - [key: string]: unknown - } - } - | { - id: string - type: "credential.added" - properties: { - credential: CredentialInfo - } - } - | { - id: string - type: "credential.removed" - properties: { - credential: CredentialInfo - } - } - | { - id: string - type: "credential.switched" - properties: { - connectorID: string - from?: string - to?: string - } - } - | { - id: string - type: "plugin.added" - properties: { - id: string - } - } - | { - id: string - type: "catalog.model.updated" - properties: { - model: ModelV2Info - } - } - | { - id: string - type: "session.created" - properties: { - sessionID: string - info: Session - } - } - | { - id: string - type: "session.updated" - properties: { - sessionID: string - info: Session - } - } - | { - id: string - type: "session.deleted" - properties: { - sessionID: string - info: Session - } - } - | { - id: string - type: "message.updated" - properties: { - sessionID: string - info: Message - } - } - | { - id: string - type: "message.removed" - properties: { - sessionID: string - messageID: string - } - } - | { - id: string - type: "message.part.updated" - properties: { - sessionID: string - part: Part - time: number - } - } - | { - id: string - type: "message.part.removed" - properties: { - sessionID: string - messageID: string - partID: string - } - } - | { - id: string - type: "session.next.agent.switched" - properties: { - timestamp: number - sessionID: string - messageID: string - agent: string - } - } - | { - id: string - type: "session.next.model.switched" - properties: { - timestamp: number - sessionID: string - messageID: string - model: { - id: string - providerID: string - variant?: string - } - } - } - | { - id: string - type: "session.next.moved" - properties: { - timestamp: number - sessionID: string - location: LocationRef - subdirectory?: string - } - } - | { - id: string - type: "session.next.prompted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - delivery: "steer" | "queue" - } - } - | { - id: string - type: "session.next.prompt.admitted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - delivery: "steer" | "queue" - } - } - | { - id: string - type: "session.next.prompt.promoted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - timeCreated: number - } - } - | { - id: string - type: "session.next.interrupt.requested" - properties: { - timestamp: number - sessionID: string - } - } - | { - id: string - type: "session.next.context.updated" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } - } - | { - id: string - type: "session.next.synthetic" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } - } - | { - id: string - type: "session.next.shell.started" - properties: { - timestamp: number - sessionID: string - messageID: string - callID: string - command: string - } - } - | { - id: string - type: "session.next.shell.ended" - properties: { - timestamp: number - sessionID: string - callID: string - output: string - } - } - | { - id: string - type: "session.next.step.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - agent: string - model: { - id: string - providerID: string - variant?: string - } - snapshot?: string - } - } - | { - id: string - type: "session.next.step.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - finish: string - cost: number - tokens: { - input: number - output: number - reasoning: number - cache: { - read: number - write: number - } - } - snapshot?: string - } - } - | { - id: string - type: "session.next.step.failed" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - error: SessionErrorUnknown - } - } - | { - id: string - type: "session.next.text.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - } - } - | { - id: string - type: "session.next.text.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - delta: string - } - } - | { - id: string - type: "session.next.text.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - text: string - } - } - | { - id: string - type: "session.next.reasoning.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - providerMetadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } - | { - id: string - type: "session.next.reasoning.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - delta: string - } - } - | { - id: string - type: "session.next.reasoning.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - text: string - providerMetadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } - | { - id: string - type: "session.next.tool.input.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - name: string - } - } - | { - id: string - type: "session.next.tool.input.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - delta: string - } - } - | { - id: string - type: "session.next.tool.input.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - text: string - } - } - | { - id: string - type: "session.next.tool.called" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - tool: string - input: { - [key: string]: unknown - } - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } - } - | { - id: string - type: "session.next.tool.progress" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - structured: { - [key: string]: unknown - } - content: Array - } - } - | { - id: string - type: "session.next.tool.success" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - structured: { - [key: string]: unknown - } - content: Array - outputPaths?: Array - result?: unknown - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } - } - | { - id: string - type: "session.next.tool.failed" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - error: SessionErrorUnknown - result?: unknown - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } - } - | { - id: string - type: "session.next.retried" - properties: { - timestamp: number - sessionID: string - attempt: number - error: SessionNextRetryError - } - } - | { - id: string - type: "session.next.compaction.started" - properties: { - timestamp: number - sessionID: string - messageID: string - reason: "auto" | "manual" - } - } - | { - id: string - type: "session.next.compaction.delta" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } - } - | { - id: string - type: "session.next.compaction.ended" - properties: { - timestamp: number - sessionID: string - messageID: string - reason: "auto" | "manual" - text: string - recent: string - } - } - | { - id: string - type: "message.part.delta" - properties: { - sessionID: string - messageID: string - partID: string - field: string - delta: string - } - } - | { - id: string - type: "session.diff" - properties: { - sessionID: string - diff: Array - } - } - | { - id: string - type: "session.error" - properties: { - sessionID?: string - error?: - | ProviderAuthError - | UnknownError - | MessageOutputLengthError - | MessageAbortedError - | StructuredOutputError - | ContextOverflowError - | ContentFilterError - | ApiError - } - } - | { - id: string - type: "installation.updated" - properties: { - version: string - } - } - | { - id: string - type: "installation.update-available" - properties: { - version: string - } - } - | { - id: string - type: "file.edited" - properties: { - file: string - } - } - | { - id: string - type: "connector.updated" - properties: { - [key: string]: unknown - } - } - | { - id: string - type: "permission.v2.asked" - properties: { - id: string - sessionID: string - action: string - resources: Array - save?: Array - metadata?: { - [key: string]: unknown - } - source?: PermissionV2Source - } - } - | { - id: string - type: "permission.v2.replied" - properties: { - sessionID: string - requestID: string - reply: PermissionV2Reply - } - } - | { - id: string - type: "reference.updated" - properties: { - [key: string]: unknown - } - } - | { - id: string - type: "file.watcher.updated" - properties: { - file: string - event: "add" | "change" | "unlink" - } - } - | { - id: string - type: "pty.created" - properties: { - info: Pty - } - } - | { - id: string - type: "pty.updated" - properties: { - info: Pty - } - } - | { - id: string - type: "pty.exited" - properties: { - id: string - exitCode: number - } - } - | { - id: string - type: "pty.deleted" - properties: { - id: string - } - } - | { - id: string - type: "question.v2.asked" - properties: { - id: string - sessionID: string - /** - * Questions to ask - */ - questions: Array - tool?: QuestionV2Tool - } - } - | { - id: string - type: "question.v2.replied" - properties: { - sessionID: string - requestID: string - answers: Array - } - } - | { - id: string - type: "question.v2.rejected" - properties: { - sessionID: string - requestID: string - } - } - | { - id: string - type: "todo.updated" - properties: { - sessionID: string - todos: Array - } - } - | { - id: string - type: "lsp.updated" - properties: { - [key: string]: unknown - } - } - | { - id: string - type: "permission.asked" - properties: { - id: string - sessionID: string - permission: string - patterns: Array - metadata: { - [key: string]: unknown - } - always: Array - tool?: { - messageID: string - callID: string - } - } - } - | { - id: string - type: "permission.replied" - properties: { - sessionID: string - requestID: string - reply: "once" | "always" | "reject" - } - } - | { - id: string - type: "tui.prompt.append" - properties: { - text: string - } - } - | { - id: string - type: "tui.command.execute" - properties: { - command: - | "session.list" - | "session.new" - | "session.share" - | "session.interrupt" - | "session.compact" - | "session.page.up" - | "session.page.down" - | "session.line.up" - | "session.line.down" - | "session.half.page.up" - | "session.half.page.down" - | "session.first" - | "session.last" - | "prompt.clear" - | "prompt.submit" - | "agent.cycle" - | string - } - } - | { - id: string - type: "tui.toast.show" - properties: { - title?: string - message: string - variant: "info" | "success" | "warning" | "error" - duration?: number - } - } - | { - id: string - type: "tui.session.select" - properties: { - /** - * Session ID to navigate to - */ - sessionID: string - } - } - | { - id: string - type: "mcp.tools.changed" - properties: { - server: string - } - } - | { - id: string - type: "mcp.browser.open.failed" - properties: { - mcpName: string - url: string - } - } - | { - id: string - type: "command.executed" - properties: { - name: string - sessionID: string - arguments: string - messageID: string - } - } - | { - id: string - type: "project.directories.updated" - properties: { - projectID: string - } - } - | { - id: string - type: "project.updated" - properties: { - id: string - worktree: string - vcs?: "git" - name?: string - icon?: { - url?: string - override?: string - color?: string - } - commands?: { - /** - * Startup script to run when creating a new workspace (worktree) - */ - start?: string - } - time: { - created: number - updated: number - initialized?: number - } - sandboxes: Array - } - } - | { - id: string - type: "vcs.branch.updated" - properties: { - branch?: string - } - } - | { - id: string - type: "question.asked" - properties: { - id: string - sessionID: string - /** - * Questions to ask - */ - questions: Array - tool?: QuestionTool - } - } - | { - id: string - type: "question.replied" - properties: { - sessionID: string - requestID: string - answers: Array - } - } - | { - id: string - type: "question.rejected" - properties: { - sessionID: string - requestID: string - } - } - | { - id: string - type: "session.status" - properties: { - sessionID: string - status: SessionStatus - } - } - | { - id: string - type: "session.idle" - properties: { - sessionID: string - } - } - | { - id: string - type: "session.compacted" - properties: { - sessionID: string - } - } - | { - id: string - type: "worktree.ready" - properties: { - name: string - branch?: string - } - } - | { - id: string - type: "worktree.failed" - properties: { - message: string - } - } - | { - id: string - type: "workspace.ready" - properties: { - name: string - } - } - | { - id: string - type: "workspace.failed" - properties: { - message: string - } - } - | { - id: string - type: "workspace.status" - properties: { - workspaceID: string - status: "connected" | "connecting" | "disconnected" | "error" - } - } - | { - id: string - type: "server.connected" - properties: { - [key: string]: unknown - } - } - | { - id: string - type: "global.disposed" - properties: { - [key: string]: unknown - } - } | EventServerInstanceDisposed + | EventSessionNetworkAsked + | EventSessionNetworkReplied + | EventSessionNetworkRejected + | EventSessionNetworkRestored + | EventBackgroundProcessUpdated + | EventBackgroundProcessDeleted + | EventInteractiveTerminalUpdated + | EventInteractiveTerminalData + | EventInteractiveTerminalDeleted + | EventSessionTurnOpen + | EventSessionTurnClose + | EventSandboxStatusChanged + | EventSuggestionShown + | EventSuggestionAccepted + | EventSuggestionDismissed + | EventKilocodeAgentManagerStart + | EventKilocodeNotebookRequested + | EventKilocodeNotebookCancelled + | EventLspClientDiagnostics + | EventKiloSessionsRemoteStatusChanged + | EventMemoryStatus + | EventMemoryUpdated + | EventMemoryError + | EventIndexingStatus + | EventIndexingWarning + | EventServerConnected + | EventGlobalDisposed + | EventGlobalConfigUpdated + | EventCredentialAdded + | EventCredentialRemoved + | EventCredentialSwitched + | EventPluginAdded + | EventCatalogModelUpdated + | EventSessionCreated + | EventSessionUpdated + | EventSessionDeleted + | EventMessageUpdated + | EventMessageRemoved + | EventMessagePartUpdated + | EventMessagePartRemoved + | EventSessionNextAgentSwitched + | EventSessionNextModelSwitched + | EventSessionNextMoved + | EventSessionNextPrompted + | EventSessionNextPromptAdmitted + | EventSessionNextPromptPromoted + | EventSessionNextInterruptRequested + | EventSessionNextContextUpdated + | EventSessionNextSynthetic + | EventSessionNextShellStarted + | EventSessionNextShellEnded + | EventSessionNextStepStarted + | EventSessionNextStepEnded + | EventSessionNextStepFailed + | EventSessionNextTextStarted + | EventSessionNextTextDelta + | EventSessionNextTextEnded + | EventSessionNextReasoningStarted + | EventSessionNextReasoningDelta + | EventSessionNextReasoningEnded + | EventSessionNextToolInputStarted + | EventSessionNextToolInputDelta + | EventSessionNextToolInputEnded + | EventSessionNextToolCalled + | EventSessionNextToolProgress + | EventSessionNextToolSuccess + | EventSessionNextToolFailed + | EventSessionNextRetried + | EventSessionNextCompactionStarted + | EventSessionNextCompactionDelta + | EventSessionNextCompactionEnded + | EventQuestionAsked + | EventQuestionReplied + | EventQuestionRejected + | EventTuiPromptAppend + | EventTuiCommandExecute + | EventTuiToastShow + | EventTuiSessionSelect + | EventMcpToolsChanged + | EventMcpBrowserOpenFailed + | EventMessagePartDelta + | EventSessionDiff + | EventSessionError + | EventModelsDevRefreshed + | EventInstallationUpdated + | EventInstallationUpdateAvailable + | EventPermissionAsked + | EventPermissionReplied + | EventConnectorUpdated + | EventPermissionV2Asked + | EventPermissionV2Replied + | EventReferenceUpdated + | EventFileEdited + | EventFileWatcherUpdated + | EventPtyCreated + | EventPtyUpdated + | EventPtyExited + | EventPtyDeleted + | EventQuestionV2Asked + | EventQuestionV2Replied + | EventQuestionV2Rejected + | EventTodoUpdated + | EventSessionStatus + | EventSessionIdle + | EventSessionCompacted + | EventCommandExecuted + | EventProjectDirectoriesUpdated + | EventProjectUpdated + | EventLspUpdated + | EventVcsBranchUpdated + | EventWorkspaceReady + | EventWorkspaceFailed + | EventWorkspaceStatus + | EventWorktreeReady + | EventWorktreeFailed | SyncEventSessionCreated | SyncEventSessionUpdated | SyncEventSessionDeleted @@ -1702,6 +1176,70 @@ export type ServerConfig = { cors?: Array } +export type IndexingConfig = { + enabled?: boolean + provider?: + | "kilo" + | "openai" + | "ollama" + | "openai-compatible" + | "gemini" + | "mistral" + | "vercel-ai-gateway" + | "bedrock" + | "openrouter" + | "voyage" + model?: string | null + dimension?: number | null + vectorStore?: "lancedb" | "qdrant" + kilo?: { + apiKey?: string + baseUrl?: string + organizationId?: string + } + openai?: { + apiKey?: string + } + ollama?: { + baseUrl?: string + } + "openai-compatible"?: { + baseUrl?: string + apiKey?: string + } + gemini?: { + apiKey?: string + } + mistral?: { + apiKey?: string + } + "vercel-ai-gateway"?: { + apiKey?: string + } + bedrock?: { + region?: string + profile?: string + } + openrouter?: { + apiKey?: string + specificProvider?: string + } + voyage?: { + apiKey?: string + } + qdrant?: { + url?: string + apiKey?: string + } + lancedb?: { + directory?: string + } + searchMinScore?: number + searchMaxResults?: number + embeddingBatchSize?: number + scannerMaxBatchRetries?: number +} + export type PermissionActionConfig = "ask" | "allow" | "deny" export type PermissionObjectConfig = { @@ -1728,6 +1266,10 @@ export type PermissionConfig = lsp?: PermissionRuleConfig doom_loop?: PermissionActionConfig skill?: PermissionRuleConfig + agent_manager?: PermissionRuleConfig + notebook_read?: PermissionRuleConfig + notebook_edit?: PermissionRuleConfig + notebook_execute?: PermissionRuleConfig [key: string]: PermissionRuleConfig | PermissionActionConfig | undefined } @@ -1743,6 +1285,8 @@ export type AgentConfig = { disable?: boolean description?: string mode?: "subagent" | "primary" | "all" + displayName?: string + source?: string hidden?: boolean options?: { [key: string]: unknown @@ -1754,6 +1298,14 @@ export type AgentConfig = { steps?: number maxSteps?: number permission?: PermissionConfig + requirements?: { + skills?: Array + mcps?: Array + vscode_extensions?: Array<{ + name: string + id: string + }> + } [key: string]: | unknown | string @@ -1778,6 +1330,14 @@ export type AgentConfig = { | "info" | number | PermissionConfig + | { + skills?: Array + mcps?: Array + vscode_extensions?: Array<{ + name: string + id: string + }> + } | undefined } @@ -1810,6 +1370,9 @@ export type ProviderConfig = { id?: string name?: string family?: string + prompt?: "codex" | "gemini" | "beast" | "anthropic" | "trinity" | "anthropic_without_todo" | "ling" | "gpt55" + isFree?: boolean + ai_sdk_provider?: "alibaba" | "anthropic" | "mistral" | "openai" | "openai-compatible" | "openrouter" release_date?: string attachment?: boolean reasoning?: boolean @@ -1867,18 +1430,14 @@ export type ProviderConfig = { } export type McpLocalConfig = { - /** - * Type of MCP server connection - */ type: "local" - /** - * Command and arguments to run the MCP server - */ command: Array - cwd?: string environment?: { [key: string]: string } + env?: { + [key: string]: string + } enabled?: boolean timeout?: number } @@ -1973,8 +1532,47 @@ export type Config = { autoupdate?: boolean | "notify" disabled_providers?: Array enabled_providers?: Array + remote_control?: boolean + auto_collapse_reasoning?: boolean + indexing?: IndexingConfig + console?: { + /** + * Width of the Kilo Console project context sidebar in pixels + */ + context_sidebar_width?: number + diff_style?: "unified" | "split" + } + terminal_command_display?: "expanded" | "collapsed" + code_edit_display?: "expanded" | "collapsed" + hide_prompt_training_models?: boolean + /** + * Sandbox configuration for agent tools + */ + sandbox?: { + /** + * Enable sandbox confinement for new sessions (default: false) + */ + enabled?: boolean + /** + * Control outbound network access from sandboxed tools (default: deny) + */ + network?: "allow" | "deny" + /** + * Additional filesystem paths that sandboxed tools may write to + */ + writable_paths?: Array + /** + * Exact network destinations sandboxed tools may access while network restriction is enabled + */ + allowed_hosts?: Array + } model?: string small_model?: string + subagent_model?: string + subagent_variant?: string + subagent_variant_overrides?: { + [key: string]: string + } default_agent?: string username?: string mode?: { @@ -1985,15 +1583,19 @@ export type Config = { agent?: { plan?: AgentConfig build?: AgentConfig + debug?: AgentConfig + orchestrator?: AgentConfig + ask?: AgentConfig general?: AgentConfig explore?: AgentConfig + scout?: AgentConfig title?: AgentConfig summary?: AgentConfig compaction?: AgentConfig [key: string]: AgentConfig | undefined } provider?: { - [key: string]: ProviderConfig + [key: string]: ProviderConfig | null } mcp?: { [key: string]: @@ -2050,12 +1652,19 @@ export type Config = { enterprise?: { url?: string } + commit_message?: { + prompt?: string + } tool_output?: { max_lines?: number max_bytes?: number } compaction?: { auto?: boolean + /** + * Percentage of the model input/context window that triggers automatic compaction. The reserved safety buffer still applies if it would compact sooner. + */ + threshold_percent?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" prune?: boolean tail_turns?: number preserve_recent_tokens?: number @@ -2064,9 +1673,20 @@ export type Config = { experimental?: { disable_paste_summary?: boolean batch_tool?: boolean + codebase_search?: boolean + image_generation?: boolean + image_generation_model?: string + agent_requirements?: boolean + native_notebook_tools?: boolean + speech_to_text_model?: string openTelemetry?: boolean primary_tools?: Array continue_loop_on_deny?: boolean + sandbox?: boolean + sandbox_restrict_network?: boolean + sandbox_writable_paths?: Array + swe_pruner?: boolean + swe_pruner_model?: string mcp_timeout?: number policies?: Array } @@ -2153,14 +1773,33 @@ export type Model = { [key: string]: unknown } } + recommendedIndex?: number + prompt?: "codex" | "gemini" | "beast" | "anthropic" | "trinity" | "anthropic_without_todo" | "ling" | "gpt55" + isFree?: boolean + mayTrainOnYourPrompts?: boolean + hasUserByokAvailable?: boolean + terminalBench?: { + overallScore: number + avgAttemptCostUsd: number + } + autoRouting?: { + models: Array + } + ai_sdk_provider?: "alibaba" | "anthropic" | "mistral" | "openai" | "openai-compatible" | "openrouter" } export type Provider = { id: string name: string + description?: string source: "env" | "config" | "custom" | "api" env: Array key?: string + metadata?: { + noteKey?: string + icon?: string + priority?: number + } options: { [key: string]: unknown } @@ -2189,6 +1828,11 @@ export type ToolList = Array export type ToolIds = Array +export type WorktreeListItem = { + directory: string + managed: boolean +} + export type WorktreeError = { name: | "WorktreeNotGitError" @@ -2225,6 +1869,27 @@ 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 SnapshotSummaryFileDiff = { + file?: string + additions: number + deletions: number + status?: "added" | "deleted" | "modified" +} + export type ProjectSummary = { id: string name?: string @@ -2243,7 +1908,7 @@ export type GlobalSession = { additions: number deletions: number files: number - diffs?: Array + diffs?: Array } cost?: number tokens?: { @@ -2283,6 +1948,7 @@ export type GlobalSession = { diff?: string } project: ProjectSummary | null + worktreeName?: string } export type McpResource = { @@ -2388,7 +2054,10 @@ export type Command = { export type Agent = { name: string + displayName?: string + source?: string description?: string + deprecated?: boolean mode: "subagent" | "primary" | "all" native?: boolean hidden?: boolean @@ -2405,6 +2074,14 @@ export type Agent = { options: { [key: string]: unknown } + requirements?: { + skills?: Array + mcps?: Array + vscode_extensions?: Array<{ + name: string + id: string + }> + } steps?: number } @@ -2516,6 +2193,7 @@ export type QuestionRequest = { * Questions to ask */ questions: Array + blocking?: boolean tool?: QuestionTool } @@ -2600,6 +2278,112 @@ export type ProviderAuthError1 = { } } +export type Session1 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session2 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + export type NotFoundError = { name: "NotFoundError" data: { @@ -2607,6 +2391,271 @@ export type NotFoundError = { } } +export type Session3 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session4 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session5 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session6 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session7 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + export type TextPartInput = { id?: string type: "text" @@ -2661,14 +2710,120 @@ export type SessionBusyError = { message: string } -export type EventTuiPromptAppend = { +export type Session8 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type Session9 = { + id: string + slug: string + projectID: string + workspaceID?: string + directory: string + path?: string + parentID?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array + } + cost?: number + tokens?: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + share?: { + url: string + } + title: string + agent?: string + model?: { + id: string + providerID: string + variant?: string + } + version: string + metadata?: { + [key: string]: unknown + } + time: { + created: number + updated: number + compacting?: number + archived?: number + } + permission?: PermissionRuleset + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } +} + +export type EventTuiPromptAppend2 = { type: "tui.prompt.append" properties: { text: string } } -export type EventTuiCommandExecute = { +export type EventTuiCommandExecute2 = { type: "tui.command.execute" properties: { command: @@ -2692,7 +2847,7 @@ export type EventTuiCommandExecute = { } } -export type EventTuiToastShow = { +export type EventTuiToastShow2 = { type: "tui.toast.show" properties: { title?: string @@ -2702,7 +2857,7 @@ export type EventTuiToastShow = { } } -export type EventTuiSessionSelect = { +export type EventTuiSessionSelect2 = { type: "tui.session.select" properties: { /** @@ -2737,6 +2892,411 @@ export type WorkspaceWarpError = { } } +export type BackgroundProcessLogs = { + id: string + sessionID: string + output: string +} + +export type CommitMessageNoChangesError = { + message: 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 + 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 + 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 ConfigRulesResponse = { + scope: "project" + target: string + files: Array<{ + name: string + path: string + exists: boolean + editable: boolean + content: 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 + } + /** + * Status icon style shown in terminal titles + */ + title_icon?: "none" | "unicode" | "emojis" + scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + scroll_acceleration?: { + enabled: boolean + } + diff_style?: "auto" | "stacked" + mouse?: boolean + attention?: { + enabled?: boolean + notifications?: boolean + sound?: boolean + volume?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } +} + +export type TuiKeybindInfo = { + id: string + label: string + group: string + default: string + description: string +} + +export type TuiKeybindListResponse = { + keybinds: Array +} + +export type KiloEmbeddingModelCatalog = { + defaultModel: string + models: Array<{ + id: string + name: string + dimension: number + scoreThreshold: number + note?: string + }> + aliases: { + [key: string]: string + } +} + +export type ConflictError = { + _tag: "ConflictError" + message: string + resource?: string +} + +export type InteractiveTerminalSnapshot = { + info: InteractiveTerminalInfo + output: string + cursor: number +} + +export type InteractiveTerminalWriteInput = { + data: string +} + +export type InteractiveTerminalResizeInput = { + cols: number + rows: number +} + +export type EffectHttpApiErrorUnauthorized = { + _tag: "Unauthorized" +} + +export type EffectHttpApiErrorServiceUnavailable = { + _tag: "ServiceUnavailable" +} + +export type AgentRequirementResult = { + agent: string + directory: string + enabled: boolean + state: "disabled" | "ready" | "blocked" | "error" + skills: Array<{ + name: string + status: "ready" | "missing" | "error" + message?: string + }> + mcps: Array<{ + name: string + status: "ready" | "missing" | "error" + message?: string + }> + vscode_extensions: Array<{ + name: string + id: string + }> + error?: { + code: "unknown_agent" | "malformed_declaration" | "discovery_failed" | "mcp_status_failed" + message: string + } +} + +export type NotebookOutput = { + mime: string + text?: string + name?: string + message?: string + stack?: string + omitted?: boolean + truncated?: boolean +} + +export type NotebookCell = { + /** + * Zero-based cell index + */ + index: number + kind: "code" | "markdown" + language: string + source: string + execution?: { + order?: number + success?: boolean + started?: number + ended?: number + } + outputs?: Array +} + +export type NotebookReadResult = { + operation: "read" + path: string + requestPath: string + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + revision: string + cells: Array + truncated?: boolean +} + +export type NotebookEditResult = { + operation: "edit" + path: string + requestPath: string + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + revision: string + /** + * Zero-based cell index + */ + index: number + action: "insert" | "replace" | "delete" | "create" + cell?: NotebookCell +} + +export type NotebookExecuteResult = { + operation: "execute" + path: string + requestPath: string + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + revision: string + /** + * Zero-based cell index + */ + index: number + status: "success" | "error" + outputs: Array + truncated?: boolean +} + +export type NotebookResult = NotebookReadResult | NotebookEditResult | NotebookExecuteResult + +export type NotebookFailure = { + code: + | "already_exists" + | "cancelled" + | "closed" + | "disconnected" + | "execution_failed" + | "invalid_cell" + | "invalid_path" + | "no_kernel" + | "not_found" + | "stale_revision" + | "timeout" + | "unsupported" + message: string + path?: string + /** + * Zero-based cell index + */ + index?: number + /** + * Opaque notebook content revision; pass it back unchanged and do not parse or increment it + */ + currentRevision?: string +} + +export type AnacondaDesktopStatus = + | { + type: "unsupported-platform" + platform: string + } + | { + type: "not-installed" + downloadURL: string + } + | { + type: "not-running" + } + | { + type: "invalid-config" + reason: "missing" | "malformed" | "missing-key" | "invalid-port" + } + | { + type: "signed-out" + } + | { + type: "management-unauthorized" + } + | { + type: "management-unavailable" + reason: "timeout" | "unexpected-response" + } + | { + type: "no-downloaded-model" + } + | { + type: "no-running-server" + downloadedModels: number + } + | { + type: "inference-unhealthy" + serverID: string + } + | { + type: "ready" + serverID: string + serverName?: string + models: Array<{ + id: string + name: string + }> + context: number + toolcall: "supported" | "unsupported" | "unknown" + } + +export type AnacondaDesktopConflictError = { + code: "unsupported-platform" | "not-installed" | "not-ready" | "acknowledgement-required" + message: string + status?: AnacondaDesktopStatus +} + +export type AnacondaDesktopOperationError = { + operation: "open" | "sync" + message: string +} + +export type KilocodeSessionImportResult = { + ok: boolean + id: string + skipped?: boolean +} + +export type MemoryApiClientError = { + name: "MemoryApiClientError" + data: { + code: string + message: string + } +} + +export type MemoryApiServerError = { + name: "MemoryApiServerError" + data: { + code: string + message: string + } +} + export type UnauthorizedError = { _tag: "UnauthorizedError" message: string @@ -2761,12 +3321,6 @@ export type SessionNotFoundError = { message: string } -export type ConflictError = { - _tag: "ConflictError" - message: string - resource?: string -} - export type ServiceUnavailableError = { _tag: "ServiceUnavailableError" message: string @@ -2797,58 +3351,23 @@ export type EffectHttpApiErrorForbidden = { _tag: "Forbidden" } -export type EventTuiPromptAppend2 = { +export type InteractiveTerminalInfo1 = { id: string - type: "tui.prompt.append" - properties: { - text: string - } -} - -export type EventTuiCommandExecute2 = { - id: string - type: "tui.command.execute" - properties: { - command: - | "session.list" - | "session.new" - | "session.share" - | "session.interrupt" - | "session.compact" - | "session.page.up" - | "session.page.down" - | "session.line.up" - | "session.line.down" - | "session.half.page.up" - | "session.half.page.down" - | "session.first" - | "session.last" - | "prompt.clear" - | "prompt.submit" - | "agent.cycle" - | string - } -} - -export type EventTuiToastShow2 = { - id: string - type: "tui.toast.show" - properties: { - title?: string - message: string - variant: "info" | "success" | "warning" | "error" - duration?: number - } -} - -export type EventTuiSessionSelect2 = { - id: string - type: "tui.session.select" - properties: { - /** - * Session ID to navigate to - */ - sessionID: string + sessionID: string + pid: number + command: string + cwd: string + description?: string + status: "running" | "closed" + cols: number + rows: number + exitCode?: number | "NaN" | "Infinity" | "-Infinity" + signal?: string + closedBy?: "exit" | "user" | "abort" + time: { + started: number + updated: number + ended?: number } } @@ -2856,6 +3375,360 @@ export type MoveSessionDestination = { directory: string } +export type EventServerInstanceDisposed = { + id: string + type: "server.instance.disposed" + properties: { + directory: string + } +} + +export type EventSessionNetworkAsked = { + id: string + type: "session.network.asked" + properties: SessionNetworkWait +} + +export type EventSessionNetworkReplied = { + id: string + type: "session.network.replied" + properties: { + sessionID: string + requestID: string + } +} + +export type EventSessionNetworkRejected = { + id: string + type: "session.network.rejected" + properties: { + sessionID: string + requestID: string + } +} + +export type EventSessionNetworkRestored = { + id: string + type: "session.network.restored" + properties: { + sessionID: string + requestID: string + time: number + } +} + +export type EventBackgroundProcessUpdated = { + id: string + type: "background_process.updated" + properties: { + info: BackgroundProcessInfo + scope: string + } +} + +export type EventBackgroundProcessDeleted = { + id: string + type: "background_process.deleted" + properties: { + sessionID: string + processID: string + scope: string + } +} + +export type EventInteractiveTerminalUpdated = { + id: string + type: "interactive_terminal.updated" + properties: { + info: InteractiveTerminalInfo + } +} + +export type EventInteractiveTerminalData = { + id: string + type: "interactive_terminal.data" + properties: { + terminalID: string + sessionID: string + data: string + cursor: number + } +} + +export type EventInteractiveTerminalDeleted = { + id: string + type: "interactive_terminal.deleted" + properties: { + terminalID: string + sessionID: string + } +} + +export type EventSessionTurnOpen = { + id: string + type: "session.turn.open" + properties: { + sessionID: string + } +} + +export type EventSessionTurnClose = { + id: string + type: "session.turn.close" + properties: { + sessionID: string + parentID?: string + reason: "completed" | "error" | "interrupted" + } +} + +export type EventSandboxStatusChanged = { + id: string + type: "sandbox.status.changed" + properties: { + sessionID: string + directory: string + enabled: boolean + available: boolean + reason?: string + version: number + } +} + +export type EventSuggestionShown = { + id: string + type: "suggestion.shown" + properties: SuggestionRequest +} + +export type EventSuggestionAccepted = { + id: string + type: "suggestion.accepted" + properties: { + sessionID: string + requestID: string + index: number + action: { + /** + * Button or option label (1-5 words) + */ + label: string + description?: string + /** + * Synthetic user prompt to inject when this action is accepted + */ + prompt: string + } + } +} + +export type EventSuggestionDismissed = { + id: string + type: "suggestion.dismissed" + properties: { + sessionID: string + requestID: string + } +} + +export type EventKilocodeAgentManagerStart = { + id: string + type: "kilocode.agent_manager.start" + properties: { + requestID: string + sessionID: string + mode: "worktree" | "local" + versions?: boolean + tasks: Array<{ + prompt?: string + name?: string + branchName?: string + model?: { + providerID: string + modelID: string + } + variant?: string + }> + } +} + +export type EventKilocodeNotebookRequested = { + id: string + type: "kilocode.notebook.requested" + properties: NotebookRequest +} + +export type EventKilocodeNotebookCancelled = { + id: string + type: "kilocode.notebook.cancelled" + properties: { + requestID: NotebookRequestId + sessionID: string + reason: "cancelled" | "disposed" | "timeout" + } +} + +export type EventLspClientDiagnostics = { + id: string + type: "lsp.client.diagnostics" + properties: { + serverID: string + path: string + } +} + +export type EventKiloSessionsRemoteStatusChanged = { + id: string + type: "kilo-sessions.remote-status-changed" + properties: { + enabled: boolean + connected: boolean + } +} + +export type EventMemoryStatus = { + id: string + type: "memory.status" + properties: { + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + cost: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + tokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + sources?: Array + files?: Array + } + } +} + +export type EventMemoryUpdated = { + id: string + type: "memory.updated" + properties: { + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + cost: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + tokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + sources?: Array + files?: Array + } + } +} + +export type EventMemoryError = { + id: string + type: "memory.error" + properties: { + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + cost: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + tokens: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + sources?: Array + files?: Array + } + } +} + +export type EventIndexingStatus = { + id: string + type: "indexing.status" + properties: { + status: IndexingStatus + } +} + +export type EventIndexingWarning = { + id: string + type: "indexing.warning" + properties: IndexingWarning +} + +export type EventServerConnected = { + id: string + type: "server.connected" + properties: { + [key: string]: unknown + } +} + +export type EventGlobalDisposed = { + id: string + type: "global.disposed" + properties: { + [key: string]: unknown + } +} + +export type EventGlobalConfigUpdated = { + id: string + type: "global.config.updated" + properties: { + [key: string]: unknown + } +} + export type CredentialOAuth = { type: "oauth" refresh: string @@ -2884,6 +3757,40 @@ export type CredentialInfo = { value: CredentialValue } +export type EventCredentialAdded = { + id: string + type: "credential.added" + properties: { + credential: CredentialInfo + } +} + +export type EventCredentialRemoved = { + id: string + type: "credential.removed" + properties: { + credential: CredentialInfo + } +} + +export type EventCredentialSwitched = { + id: string + type: "credential.switched" + properties: { + connectorID: string + from?: string + to?: string + } +} + +export type EventPluginAdded = { + id: string + type: "plugin.added" + properties: { + id: string + } +} + export type ModelV2Info = { id: string providerID: string @@ -2980,11 +3887,121 @@ export type ModelV2Info = { } } +export type EventCatalogModelUpdated = { + id: string + type: "catalog.model.updated" + properties: { + model: ModelV2Info + } +} + +export type EventSessionCreated = { + id: string + type: "session.created" + properties: { + sessionID: string + info: Session + } +} + +export type EventSessionUpdated = { + id: string + type: "session.updated" + properties: { + sessionID: string + info: Session + } +} + +export type EventSessionDeleted = { + id: string + type: "session.deleted" + properties: { + sessionID: string + info: Session + } +} + +export type EventMessageUpdated = { + id: string + type: "message.updated" + properties: { + sessionID: string + info: Message + } +} + +export type EventMessageRemoved = { + id: string + type: "message.removed" + properties: { + sessionID: string + messageID: string + } +} + +export type EventMessagePartUpdated = { + id: string + type: "message.part.updated" + properties: { + sessionID: string + part: Part + time: number + } +} + +export type EventMessagePartRemoved = { + id: string + type: "message.part.removed" + properties: { + sessionID: string + messageID: string + partID: string + } +} + +export type EventSessionNextAgentSwitched = { + id: string + type: "session.next.agent.switched" + properties: { + timestamp: number + sessionID: string + messageID: string + agent: string + } +} + +export type EventSessionNextModelSwitched = { + id: string + type: "session.next.model.switched" + properties: { + timestamp: number + sessionID: string + messageID: string + model: { + id: string + providerID: string + variant?: string + } + } +} + export type LocationRef = { directory: string workspaceID?: string } +export type EventSessionNextMoved = { + id: string + type: "session.next.moved" + properties: { + timestamp: number + sessionID: string + location: LocationRef + subdirectory?: string + } +} + export type PromptSource = { start: number end: number @@ -3004,11 +4021,290 @@ export type PromptAgentAttachment = { source?: PromptSource } +export type EventSessionNextPrompted = { + id: string + type: "session.next.prompted" + properties: { + timestamp: number + sessionID: string + messageID: string + prompt: Prompt + delivery: "steer" | "queue" + } +} + +export type EventSessionNextPromptAdmitted = { + id: string + type: "session.next.prompt.admitted" + properties: { + timestamp: number + sessionID: string + messageID: string + prompt: Prompt + delivery: "steer" | "queue" + } +} + +export type EventSessionNextPromptPromoted = { + id: string + type: "session.next.prompt.promoted" + properties: { + timestamp: number + sessionID: string + messageID: string + prompt: Prompt + timeCreated: number + } +} + +export type EventSessionNextInterruptRequested = { + id: string + type: "session.next.interrupt.requested" + properties: { + timestamp: number + sessionID: string + } +} + +export type EventSessionNextContextUpdated = { + id: string + type: "session.next.context.updated" + properties: { + timestamp: number + sessionID: string + messageID: string + text: string + } +} + +export type EventSessionNextSynthetic = { + id: string + type: "session.next.synthetic" + properties: { + timestamp: number + sessionID: string + messageID: string + text: string + } +} + +export type EventSessionNextShellStarted = { + id: string + type: "session.next.shell.started" + properties: { + timestamp: number + sessionID: string + messageID: string + callID: string + command: string + } +} + +export type EventSessionNextShellEnded = { + id: string + type: "session.next.shell.ended" + properties: { + timestamp: number + sessionID: string + callID: string + output: string + } +} + +export type EventSessionNextStepStarted = { + id: string + type: "session.next.step.started" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + agent: string + model: { + id: string + providerID: string + variant?: string + } + snapshot?: string + } +} + +export type EventSessionNextStepEnded = { + id: string + type: "session.next.step.ended" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + finish: string + cost: number + tokens: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + snapshot?: string + } +} + export type SessionErrorUnknown = { type: "unknown" message: string } +export type EventSessionNextStepFailed = { + id: string + type: "session.next.step.failed" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + error: SessionErrorUnknown + } +} + +export type EventSessionNextTextStarted = { + id: string + type: "session.next.text.started" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + textID: string + } +} + +export type EventSessionNextTextDelta = { + id: string + type: "session.next.text.delta" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + textID: string + delta: string + } +} + +export type EventSessionNextTextEnded = { + id: string + type: "session.next.text.ended" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + textID: string + text: string + } +} + +export type EventSessionNextReasoningStarted = { + id: string + type: "session.next.reasoning.started" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + reasoningID: string + providerMetadata?: { + [key: string]: { + [key: string]: unknown + } + } + } +} + +export type EventSessionNextReasoningDelta = { + id: string + type: "session.next.reasoning.delta" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + reasoningID: string + delta: string + } +} + +export type EventSessionNextReasoningEnded = { + id: string + type: "session.next.reasoning.ended" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + reasoningID: string + text: string + providerMetadata?: { + [key: string]: { + [key: string]: unknown + } + } + } +} + +export type EventSessionNextToolInputStarted = { + id: string + type: "session.next.tool.input.started" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + name: string + } +} + +export type EventSessionNextToolInputDelta = { + id: string + type: "session.next.tool.input.delta" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + delta: string + } +} + +export type EventSessionNextToolInputEnded = { + id: string + type: "session.next.tool.input.ended" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + text: string + } +} + +export type EventSessionNextToolCalled = { + id: string + type: "session.next.tool.called" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + tool: string + input: { + [key: string]: unknown + } + provider: { + executed: boolean + metadata?: { + [key: string]: { + [key: string]: unknown + } + } + } + } +} + export type ToolTextContent = { type: "text" text: string @@ -3021,6 +4317,67 @@ export type ToolFileContent = { name?: string } +export type EventSessionNextToolProgress = { + id: string + type: "session.next.tool.progress" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + structured: { + [key: string]: unknown + } + content: Array + } +} + +export type EventSessionNextToolSuccess = { + id: string + type: "session.next.tool.success" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + structured: { + [key: string]: unknown + } + content: Array + outputPaths?: Array + result?: unknown + provider: { + executed: boolean + metadata?: { + [key: string]: { + [key: string]: unknown + } + } + } + } +} + +export type EventSessionNextToolFailed = { + id: string + type: "session.next.tool.failed" + properties: { + timestamp: number + sessionID: string + assistantMessageID: string + callID: string + error: SessionErrorUnknown + result?: unknown + provider: { + executed: boolean + metadata?: { + [key: string]: { + [key: string]: unknown + } + } + } + } +} + export type SessionNextRetryError = { message: string statusCode?: number @@ -3034,14 +4391,295 @@ export type SessionNextRetryError = { } } +export type EventSessionNextRetried = { + id: string + type: "session.next.retried" + properties: { + timestamp: number + sessionID: string + attempt: number + error: SessionNextRetryError + } +} + +export type EventSessionNextCompactionStarted = { + id: string + type: "session.next.compaction.started" + properties: { + timestamp: number + sessionID: string + messageID: string + reason: "auto" | "manual" + } +} + +export type EventSessionNextCompactionDelta = { + id: string + type: "session.next.compaction.delta" + properties: { + timestamp: number + sessionID: string + messageID: string + text: string + } +} + +export type EventSessionNextCompactionEnded = { + id: string + type: "session.next.compaction.ended" + properties: { + timestamp: number + sessionID: string + messageID: string + reason: "auto" | "manual" + text: string + recent: string + } +} + +export type EventQuestionAsked = { + id: string + type: "question.asked" + properties: { + id: string + sessionID: string + /** + * Questions to ask + */ + questions: Array + blocking?: boolean + tool?: QuestionTool + } +} + +export type EventQuestionReplied = { + id: string + type: "question.replied" + properties: { + sessionID: string + requestID: string + answers: Array + } +} + +export type EventQuestionRejected = { + id: string + type: "question.rejected" + properties: { + sessionID: string + requestID: string + } +} + +export type EventMcpToolsChanged = { + id: string + type: "mcp.tools.changed" + properties: { + server: string + } +} + +export type EventMcpBrowserOpenFailed = { + id: string + type: "mcp.browser.open.failed" + properties: { + mcpName: string + url: string + } +} + +export type EventMessagePartDelta = { + id: string + type: "message.part.delta" + properties: { + sessionID: string + messageID: string + partID: string + field: string + delta: string + } +} + +export type EventSessionDiff = { + id: string + type: "session.diff" + properties: { + sessionID: string + diff: Array + } +} + +export type EventSessionError = { + id: string + type: "session.error" + properties: { + sessionID?: string + error?: + | ProviderAuthError + | UnknownError + | MessageOutputLengthError + | MessageAbortedError + | StructuredOutputError + | ContextOverflowError + | ContentFilterError + | ApiError + | AgentRequirementError + } +} + +export type EventModelsDevRefreshed = { + id: string + type: "models-dev.refreshed" + properties: { + [key: string]: unknown + } +} + +export type EventInstallationUpdated = { + id: string + type: "installation.updated" + properties: { + version: string + } +} + +export type EventInstallationUpdateAvailable = { + id: string + type: "installation.update-available" + properties: { + version: string + } +} + +export type EventPermissionAsked = { + id: string + type: "permission.asked" + properties: { + id: string + sessionID: string + permission: string + patterns: Array + metadata: { + [key: string]: unknown + } + always: Array + tool?: { + messageID: string + callID: string + } + } +} + +export type EventPermissionReplied = { + id: string + type: "permission.replied" + properties: { + sessionID: string + requestID: string + reply: "once" | "always" | "reject" + } +} + +export type EventConnectorUpdated = { + id: string + type: "connector.updated" + properties: { + [key: string]: unknown + } +} + export type PermissionV2Source = { type: "tool" messageID: string callID: string } +export type EventPermissionV2Asked = { + id: string + type: "permission.v2.asked" + properties: { + id: string + sessionID: string + action: string + resources: Array + save?: Array + metadata?: { + [key: string]: unknown + } + source?: PermissionV2Source + } +} + export type PermissionV2Reply = "once" | "always" | "reject" +export type EventPermissionV2Replied = { + id: string + type: "permission.v2.replied" + properties: { + sessionID: string + requestID: string + reply: PermissionV2Reply + } +} + +export type EventReferenceUpdated = { + id: string + type: "reference.updated" + properties: { + [key: string]: unknown + } +} + +export type EventFileEdited = { + id: string + type: "file.edited" + properties: { + file: string + } +} + +export type EventFileWatcherUpdated = { + id: string + type: "file.watcher.updated" + properties: { + file: string + event: "add" | "change" | "unlink" + } +} + +export type EventPtyCreated = { + id: string + type: "pty.created" + properties: { + info: Pty + } +} + +export type EventPtyUpdated = { + id: string + type: "pty.updated" + properties: { + info: Pty + } +} + +export type EventPtyExited = { + id: string + type: "pty.exited" + properties: { + id: string + exitCode: number + } +} + +export type EventPtyDeleted = { + id: string + type: "pty.deleted" + properties: { + id: string + } +} + export type QuestionV2Option = { /** * Display text (1-5 words, concise) @@ -3075,13 +4713,177 @@ export type QuestionV2Tool = { callID: string } +export type EventQuestionV2Asked = { + id: string + type: "question.v2.asked" + properties: { + id: string + sessionID: string + /** + * Questions to ask + */ + questions: Array + tool?: QuestionV2Tool + } +} + export type QuestionV2Answer = Array -export type EventServerInstanceDisposed = { +export type EventQuestionV2Replied = { id: string - type: "server.instance.disposed" + type: "question.v2.replied" properties: { - directory: string + sessionID: string + requestID: string + answers: Array + } +} + +export type EventQuestionV2Rejected = { + id: string + type: "question.v2.rejected" + properties: { + sessionID: string + requestID: string + } +} + +export type EventTodoUpdated = { + id: string + type: "todo.updated" + properties: { + sessionID: string + todos: Array + } +} + +export type EventSessionStatus = { + id: string + type: "session.status" + properties: { + sessionID: string + status: SessionStatus + } +} + +export type EventSessionIdle = { + id: string + type: "session.idle" + properties: { + sessionID: string + } +} + +export type EventSessionCompacted = { + id: string + type: "session.compacted" + properties: { + sessionID: string + } +} + +export type EventCommandExecuted = { + id: string + type: "command.executed" + properties: { + name: string + sessionID: string + arguments: string + messageID: string + } +} + +export type EventProjectDirectoriesUpdated = { + id: string + type: "project.directories.updated" + properties: { + projectID: string + } +} + +export type EventProjectUpdated = { + id: string + type: "project.updated" + properties: { + id: string + worktree: string + vcs?: "git" + name?: string + icon?: { + url?: string + override?: string + color?: string + } + commands?: { + /** + * Startup script to run when creating a new workspace (worktree) + */ + start?: string + } + time: { + created: number + updated: number + initialized?: number + } + sandboxes: Array + } +} + +export type EventLspUpdated = { + id: string + type: "lsp.updated" + properties: { + [key: string]: unknown + } +} + +export type EventVcsBranchUpdated = { + id: string + type: "vcs.branch.updated" + properties: { + branch?: string + } +} + +export type EventWorkspaceReady = { + id: string + type: "workspace.ready" + properties: { + name: string + } +} + +export type EventWorkspaceFailed = { + id: string + type: "workspace.failed" + properties: { + message: string + } +} + +export type EventWorkspaceStatus = { + id: string + type: "workspace.status" + properties: { + workspaceID: string + status: "connected" | "connecting" | "disconnected" | "error" + } +} + +export type EventWorktreeReady = { + id: string + type: "worktree.ready" + properties: { + name: string + branch?: string + } +} + +export type EventWorktreeFailed = { + id: string + type: "worktree.failed" + properties: { + message: string } } @@ -4263,45 +6065,108 @@ export type ReferenceInfo = { source: ReferenceLocalSource | ReferenceGitSource } -export type EventModelsDevRefreshed = { +export type EventMemoryStatus1 = { id: string - type: "models-dev.refreshed" + type: "memory.status" properties: { - [key: string]: unknown + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" + cost: number | "NaN" | "Infinity" | "-Infinity" + tokens: number | "NaN" | "Infinity" | "-Infinity" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" + sources?: Array + files?: Array + } } } -export type EventCredentialAdded = { +export type EventMemoryUpdated1 = { id: string - type: "credential.added" + type: "memory.updated" properties: { - credential: CredentialInfo + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" + cost: number | "NaN" | "Infinity" | "-Infinity" + tokens: number | "NaN" | "Infinity" | "-Infinity" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" + sources?: Array + files?: Array + } } } -export type EventCredentialRemoved = { +export type EventMemoryError1 = { id: string - type: "credential.removed" + type: "memory.error" properties: { - credential: CredentialInfo - } -} - -export type EventCredentialSwitched = { - id: string - type: "credential.switched" - properties: { - connectorID: string - from?: string - to?: string - } -} - -export type EventPluginAdded = { - id: string - type: "plugin.added" - properties: { - id: string + directory: string + sessionID?: string + enabled: boolean + state: "idle" | "checking" | "injecting" | "updating" | "skipped" | "error" + reason?: string + project: { + bytes: number | "NaN" | "Infinity" | "-Infinity" + estimatedTokens: number | "NaN" | "Infinity" | "-Infinity" + truncated: boolean + updatedAt?: number | "NaN" | "Infinity" | "-Infinity" + } + consolidation?: { + trigger: "explicit" | "turn-close" | "rebuild" + operationCount: number | "NaN" | "Infinity" | "-Infinity" + cost: number | "NaN" | "Infinity" | "-Infinity" + tokens: number | "NaN" | "Infinity" | "-Infinity" + } + detail?: { + type: "saved" | "skipped" | "recalled" + message: string + reason?: string + duplicateOf?: string + tokens?: number | "NaN" | "Infinity" | "-Infinity" + operationCount?: number | "NaN" | "Infinity" | "-Infinity" + skippedCount?: number | "NaN" | "Infinity" | "-Infinity" + sources?: Array + files?: Array + } } } @@ -4401,912 +6266,14 @@ export type ModelV2Info1 = { } } -export type EventCatalogModelUpdated = { +export type EventTuiToastShow1 = { id: string - type: "catalog.model.updated" - properties: { - model: ModelV2Info1 - } -} - -export type EventSessionCreated = { - id: string - type: "session.created" - properties: { - sessionID: string - info: Session - } -} - -export type EventSessionUpdated = { - id: string - type: "session.updated" - properties: { - sessionID: string - info: Session - } -} - -export type EventSessionDeleted = { - id: string - type: "session.deleted" - properties: { - sessionID: string - info: Session - } -} - -export type EventMessageUpdated = { - id: string - type: "message.updated" - properties: { - sessionID: string - info: Message - } -} - -export type EventMessageRemoved = { - id: string - type: "message.removed" - properties: { - sessionID: string - messageID: string - } -} - -export type EventMessagePartUpdated = { - id: string - type: "message.part.updated" - properties: { - sessionID: string - part: Part - time: number - } -} - -export type EventMessagePartRemoved = { - id: string - type: "message.part.removed" - properties: { - sessionID: string - messageID: string - partID: string - } -} - -export type EventSessionNextAgentSwitched = { - id: string - type: "session.next.agent.switched" - properties: { - timestamp: number - sessionID: string - messageID: string - agent: string - } -} - -export type EventSessionNextModelSwitched = { - id: string - type: "session.next.model.switched" - properties: { - timestamp: number - sessionID: string - messageID: string - model: { - id: string - providerID: string - variant?: string - } - } -} - -export type EventSessionNextMoved = { - id: string - type: "session.next.moved" - properties: { - timestamp: number - sessionID: string - location: LocationRef - subdirectory?: string - } -} - -export type EventSessionNextPrompted = { - id: string - type: "session.next.prompted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - delivery: "steer" | "queue" - } -} - -export type EventSessionNextPromptAdmitted = { - id: string - type: "session.next.prompt.admitted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - delivery: "steer" | "queue" - } -} - -export type EventSessionNextPromptPromoted = { - id: string - type: "session.next.prompt.promoted" - properties: { - timestamp: number - sessionID: string - messageID: string - prompt: Prompt - timeCreated: number - } -} - -export type EventSessionNextInterruptRequested = { - id: string - type: "session.next.interrupt.requested" - properties: { - timestamp: number - sessionID: string - } -} - -export type EventSessionNextContextUpdated = { - id: string - type: "session.next.context.updated" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } -} - -export type EventSessionNextSynthetic = { - id: string - type: "session.next.synthetic" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } -} - -export type EventSessionNextShellStarted = { - id: string - type: "session.next.shell.started" - properties: { - timestamp: number - sessionID: string - messageID: string - callID: string - command: string - } -} - -export type EventSessionNextShellEnded = { - id: string - type: "session.next.shell.ended" - properties: { - timestamp: number - sessionID: string - callID: string - output: string - } -} - -export type EventSessionNextStepStarted = { - id: string - type: "session.next.step.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - agent: string - model: { - id: string - providerID: string - variant?: string - } - snapshot?: string - } -} - -export type EventSessionNextStepEnded = { - id: string - type: "session.next.step.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - finish: string - cost: number - tokens: { - input: number - output: number - reasoning: number - cache: { - read: number - write: number - } - } - snapshot?: string - } -} - -export type EventSessionNextStepFailed = { - id: string - type: "session.next.step.failed" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - error: SessionErrorUnknown - } -} - -export type EventSessionNextTextStarted = { - id: string - type: "session.next.text.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - } -} - -export type EventSessionNextTextDelta = { - id: string - type: "session.next.text.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - delta: string - } -} - -export type EventSessionNextTextEnded = { - id: string - type: "session.next.text.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - textID: string - text: string - } -} - -export type EventSessionNextReasoningStarted = { - id: string - type: "session.next.reasoning.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - providerMetadata?: { - [key: string]: { - [key: string]: unknown - } - } - } -} - -export type EventSessionNextReasoningDelta = { - id: string - type: "session.next.reasoning.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - delta: string - } -} - -export type EventSessionNextReasoningEnded = { - id: string - type: "session.next.reasoning.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - reasoningID: string - text: string - providerMetadata?: { - [key: string]: { - [key: string]: unknown - } - } - } -} - -export type EventSessionNextToolInputStarted = { - id: string - type: "session.next.tool.input.started" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - name: string - } -} - -export type EventSessionNextToolInputDelta = { - id: string - type: "session.next.tool.input.delta" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - delta: string - } -} - -export type EventSessionNextToolInputEnded = { - id: string - type: "session.next.tool.input.ended" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - text: string - } -} - -export type EventSessionNextToolCalled = { - id: string - type: "session.next.tool.called" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - tool: string - input: { - [key: string]: unknown - } - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } -} - -export type EventSessionNextToolProgress = { - id: string - type: "session.next.tool.progress" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - structured: { - [key: string]: unknown - } - content: Array - } -} - -export type EventSessionNextToolSuccess = { - id: string - type: "session.next.tool.success" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - structured: { - [key: string]: unknown - } - content: Array - outputPaths?: Array - result?: unknown - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } -} - -export type EventSessionNextToolFailed = { - id: string - type: "session.next.tool.failed" - properties: { - timestamp: number - sessionID: string - assistantMessageID: string - callID: string - error: SessionErrorUnknown - result?: unknown - provider: { - executed: boolean - metadata?: { - [key: string]: { - [key: string]: unknown - } - } - } - } -} - -export type EventSessionNextRetried = { - id: string - type: "session.next.retried" - properties: { - timestamp: number - sessionID: string - attempt: number - error: SessionNextRetryError - } -} - -export type EventSessionNextCompactionStarted = { - id: string - type: "session.next.compaction.started" - properties: { - timestamp: number - sessionID: string - messageID: string - reason: "auto" | "manual" - } -} - -export type EventSessionNextCompactionDelta = { - id: string - type: "session.next.compaction.delta" - properties: { - timestamp: number - sessionID: string - messageID: string - text: string - } -} - -export type EventSessionNextCompactionEnded = { - id: string - type: "session.next.compaction.ended" - properties: { - timestamp: number - sessionID: string - messageID: string - reason: "auto" | "manual" - text: string - recent: string - } -} - -export type EventMessagePartDelta = { - id: string - type: "message.part.delta" - properties: { - sessionID: string - messageID: string - partID: string - field: string - delta: string - } -} - -export type EventSessionDiff = { - id: string - type: "session.diff" - properties: { - sessionID: string - diff: Array - } -} - -export type EventSessionError = { - id: string - type: "session.error" - properties: { - sessionID?: string - error?: - | ProviderAuthError - | UnknownError - | MessageOutputLengthError - | MessageAbortedError - | StructuredOutputError - | ContextOverflowError - | ContentFilterError - | ApiError - } -} - -export type EventInstallationUpdated = { - id: string - type: "installation.updated" - properties: { - version: string - } -} - -export type EventInstallationUpdateAvailable = { - id: string - type: "installation.update-available" - properties: { - version: string - } -} - -export type EventFileEdited = { - id: string - type: "file.edited" - properties: { - file: string - } -} - -export type EventConnectorUpdated = { - id: string - type: "connector.updated" - properties: { - [key: string]: unknown - } -} - -export type EventPermissionV2Asked = { - id: string - type: "permission.v2.asked" - properties: { - id: string - sessionID: string - action: string - resources: Array - save?: Array - metadata?: { - [key: string]: unknown - } - source?: PermissionV2Source - } -} - -export type EventPermissionV2Replied = { - id: string - type: "permission.v2.replied" - properties: { - sessionID: string - requestID: string - reply: PermissionV2Reply - } -} - -export type EventReferenceUpdated = { - id: string - type: "reference.updated" - properties: { - [key: string]: unknown - } -} - -export type EventFileWatcherUpdated = { - id: string - type: "file.watcher.updated" - properties: { - file: string - event: "add" | "change" | "unlink" - } -} - -export type EventPtyCreated = { - id: string - type: "pty.created" - properties: { - info: Pty - } -} - -export type EventPtyUpdated = { - id: string - type: "pty.updated" - properties: { - info: Pty - } -} - -export type EventPtyExited = { - id: string - type: "pty.exited" - properties: { - id: string - exitCode: number - } -} - -export type EventPtyDeleted = { - id: string - type: "pty.deleted" - properties: { - id: string - } -} - -export type EventQuestionV2Asked = { - id: string - type: "question.v2.asked" - properties: { - id: string - sessionID: string - /** - * Questions to ask - */ - questions: Array - tool?: QuestionV2Tool - } -} - -export type EventQuestionV2Replied = { - id: string - type: "question.v2.replied" - properties: { - sessionID: string - requestID: string - answers: Array - } -} - -export type EventQuestionV2Rejected = { - id: string - type: "question.v2.rejected" - properties: { - sessionID: string - requestID: string - } -} - -export type EventTodoUpdated = { - id: string - type: "todo.updated" - properties: { - sessionID: string - todos: Array - } -} - -export type EventLspUpdated = { - id: string - type: "lsp.updated" - properties: { - [key: string]: unknown - } -} - -export type EventPermissionAsked = { - id: string - type: "permission.asked" - properties: { - id: string - sessionID: string - permission: string - patterns: Array - metadata: { - [key: string]: unknown - } - always: Array - tool?: { - messageID: string - callID: string - } - } -} - -export type EventPermissionReplied = { - id: string - type: "permission.replied" - properties: { - sessionID: string - requestID: string - reply: "once" | "always" | "reject" - } -} - -export type EventMcpToolsChanged = { - id: string - type: "mcp.tools.changed" - properties: { - server: string - } -} - -export type EventMcpBrowserOpenFailed = { - id: string - type: "mcp.browser.open.failed" - properties: { - mcpName: string - url: string - } -} - -export type EventCommandExecuted = { - id: string - type: "command.executed" - properties: { - name: string - sessionID: string - arguments: string - messageID: string - } -} - -export type EventProjectDirectoriesUpdated = { - id: string - type: "project.directories.updated" - properties: { - projectID: string - } -} - -export type EventProjectUpdated = { - id: string - type: "project.updated" - properties: { - id: string - worktree: string - vcs?: "git" - name?: string - icon?: { - url?: string - override?: string - color?: string - } - commands?: { - /** - * Startup script to run when creating a new workspace (worktree) - */ - start?: string - } - time: { - created: number - updated: number - initialized?: number - } - sandboxes: Array - } -} - -export type EventVcsBranchUpdated = { - id: string - type: "vcs.branch.updated" - properties: { - branch?: string - } -} - -export type EventQuestionAsked = { - id: string - type: "question.asked" - properties: { - id: string - sessionID: string - /** - * Questions to ask - */ - questions: Array - tool?: QuestionTool - } -} - -export type EventQuestionReplied = { - id: string - type: "question.replied" - properties: { - sessionID: string - requestID: string - answers: Array - } -} - -export type EventQuestionRejected = { - id: string - type: "question.rejected" - properties: { - sessionID: string - requestID: string - } -} - -export type EventSessionStatus = { - id: string - type: "session.status" - properties: { - sessionID: string - status: SessionStatus - } -} - -export type EventSessionIdle = { - id: string - type: "session.idle" - properties: { - sessionID: string - } -} - -export type EventSessionCompacted = { - id: string - type: "session.compacted" - properties: { - sessionID: string - } -} - -export type EventWorktreeReady = { - id: string - type: "worktree.ready" - properties: { - name: string - branch?: string - } -} - -export type EventWorktreeFailed = { - id: string - type: "worktree.failed" + type: "tui.toast.show" properties: { + title?: string message: string - } -} - -export type EventWorkspaceReady = { - id: string - type: "workspace.ready" - properties: { - name: string - } -} - -export type EventWorkspaceFailed = { - id: string - type: "workspace.failed" - properties: { - message: string - } -} - -export type EventWorkspaceStatus = { - id: string - type: "workspace.status" - properties: { - workspaceID: string - status: "connected" | "connecting" | "disconnected" | "error" - } -} - -export type EventServerConnected = { - id: string - type: "server.connected" - properties: { - [key: string]: unknown - } -} - -export type EventGlobalDisposed = { - id: string - type: "global.disposed" - properties: { - [key: string]: unknown + variant: "info" | "success" | "warning" | "error" + duration?: number } } @@ -5685,6 +6652,38 @@ export type ConfigUpdateResponses = { export type ConfigUpdateResponse = ConfigUpdateResponses[keyof ConfigUpdateResponses] +export type ConfigWarningsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/config/warnings" +} + +export type ConfigWarningsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigWarningsError = ConfigWarningsErrors[keyof ConfigWarningsErrors] + +export type ConfigWarningsResponses = { + /** + * Config warnings + */ + 200: Array<{ + path: string + message: string + detail?: string + }> +} + +export type ConfigWarningsResponse = ConfigWarningsResponses[keyof ConfigWarningsResponses] + export type ConfigProvidersData = { body?: never path?: never @@ -5923,9 +6922,9 @@ export type WorktreeListError = WorktreeListErrors[keyof WorktreeListErrors] export type WorktreeListResponses = { /** - * List of worktree directories + * List of worktrees */ - 200: Array + 200: Array } export type WorktreeListResponse = WorktreeListResponses[keyof WorktreeListResponses] @@ -5986,12 +6985,103 @@ 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 = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type WorktreeDiffError = WorktreeDiffErrors[keyof WorktreeDiffErrors] + +export type WorktreeDiffResponses = { + /** + * File diffs + */ + 200: Array +} + +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 = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type WorktreeDiffSummaryError = WorktreeDiffSummaryErrors[keyof WorktreeDiffSummaryErrors] + +export type WorktreeDiffSummaryResponses = { + /** + * Diff summary items + */ + 200: Array +} + +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 = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +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?: boolean + current?: "true" | "false" roots?: boolean | "true" | "false" start?: number cursor?: number @@ -7326,6 +8416,7 @@ export type PtyGetResponse = PtyGetResponses[keyof PtyGetResponses] export type PtyUpdateData = { body?: { title?: string + sessionID?: string | null size?: { rows: number cols: number @@ -7570,6 +8661,81 @@ export type PermissionReplyResponses = { export type PermissionReplyResponse = PermissionReplyResponses[keyof PermissionReplyResponses] +export type PermissionSaveAlwaysRulesData = { + body?: { + approvedAlways?: Array + deniedAlways?: Array + } + path: { + requestID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/permission/{requestID}/always-rules" +} + +export type PermissionSaveAlwaysRulesErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * PermissionNotFoundError + */ + 404: PermissionNotFoundError +} + +export type PermissionSaveAlwaysRulesError = PermissionSaveAlwaysRulesErrors[keyof PermissionSaveAlwaysRulesErrors] + +export type PermissionSaveAlwaysRulesResponses = { + /** + * Always-rules saved + */ + 200: boolean +} + +export type PermissionSaveAlwaysRulesResponse = + PermissionSaveAlwaysRulesResponses[keyof PermissionSaveAlwaysRulesResponses] + +export type PermissionAllowEverythingData = { + body?: { + enable: boolean + requestID?: string + sessionID?: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/permission/allow-everything" +} + +export type PermissionAllowEverythingErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * PermissionNotFoundError + */ + 404: PermissionNotFoundError +} + +export type PermissionAllowEverythingError = PermissionAllowEverythingErrors[keyof PermissionAllowEverythingErrors] + +export type PermissionAllowEverythingResponses = { + /** + * Success + */ + 200: boolean +} + +export type PermissionAllowEverythingResponse = + PermissionAllowEverythingResponses[keyof PermissionAllowEverythingResponses] + export type ProviderListData = { body?: never path?: never @@ -7599,6 +8765,7 @@ export type ProviderListResponses = { [key: string]: string } connected: Array + failed: Array } } @@ -7737,7 +8904,7 @@ export type SessionListResponses = { /** * List of sessions */ - 200: Array + 200: Array } export type SessionListResponse = SessionListResponses[keyof SessionListResponses] @@ -7756,6 +8923,7 @@ export type SessionCreateData = { [key: string]: unknown } permission?: PermissionRuleset + platform?: string workspaceID?: string } path?: never @@ -7779,7 +8947,7 @@ export type SessionCreateResponses = { /** * Successfully created session */ - 200: Session + 200: Session3 } export type SessionCreateResponse = SessionCreateResponses[keyof SessionCreateResponses] @@ -7877,7 +9045,7 @@ export type SessionGetResponses = { /** * Get session */ - 200: Session + 200: Session2 } export type SessionGetResponse = SessionGetResponses[keyof SessionGetResponses] @@ -7920,7 +9088,7 @@ export type SessionUpdateResponses = { /** * Successfully updated session */ - 200: Session + 200: Session4 } export type SessionUpdateResponse = SessionUpdateResponses[keyof SessionUpdateResponses] @@ -7954,7 +9122,7 @@ export type SessionChildrenResponses = { /** * List of children */ - 200: Array + 200: Array } export type SessionChildrenResponse = SessionChildrenResponses[keyof SessionChildrenResponses] @@ -8078,6 +9246,13 @@ export type SessionPromptData = { format?: OutputFormat system?: string variant?: string + snapshotInitialization?: "wait" + editorContext?: { + visibleFiles?: Array + openTabs?: Array + activeFile?: string + shell?: string + } parts: Array } path: { @@ -8223,7 +9398,7 @@ export type SessionForkResponses = { /** * 200 */ - 200: Session + 200: Session5 } export type SessionForkResponse = SessionForkResponses[keyof SessionForkResponses] @@ -8329,7 +9504,7 @@ export type SessionUnshareResponses = { /** * Successfully unshared session */ - 200: Session + 200: Session7 } export type SessionUnshareResponse = SessionUnshareResponses[keyof SessionUnshareResponses] @@ -8367,7 +9542,7 @@ export type SessionShareResponses = { /** * Successfully shared session */ - 200: Session + 200: Session6 } export type SessionShareResponse = SessionShareResponses[keyof SessionShareResponses] @@ -8425,6 +9600,13 @@ export type SessionPromptAsyncData = { format?: OutputFormat system?: string variant?: string + snapshotInitialization?: "wait" + editorContext?: { + visibleFiles?: Array + openTabs?: Array + activeFile?: string + shell?: string + } parts: Array } path: { @@ -8467,6 +9649,7 @@ export type SessionCommandData = { arguments: string command: string variant?: string + snapshotInitialization?: "wait" parts?: Array<{ id?: string type: "file" @@ -8596,7 +9779,7 @@ export type SessionRevertResponses = { /** * Updated session */ - 200: Session + 200: Session8 } export type SessionRevertResponse = SessionRevertResponses[keyof SessionRevertResponses] @@ -8634,7 +9817,7 @@ export type SessionUnrevertResponses = { /** * Updated session */ - 200: Session + 200: Session9 } export type SessionUnrevertResponse = SessionUnrevertResponses[keyof SessionUnrevertResponses] @@ -8748,6 +9931,37 @@ export type PartUpdateResponses = { export type PartUpdateResponse = PartUpdateResponses[keyof PartUpdateResponses] +export type SessionViewedData = { + body?: { + focused?: Array + open?: Array + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/session/viewed" +} + +export type SessionViewedErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type SessionViewedError = SessionViewedErrors[keyof SessionViewedErrors] + +export type SessionViewedResponses = { + /** + * Viewed sessions updated + */ + 200: boolean +} + +export type SessionViewedResponse = SessionViewedResponses[keyof SessionViewedResponses] + export type SyncStartData = { body?: never path?: never @@ -9149,7 +10363,7 @@ export type TuiShowToastResponses = { export type TuiShowToastResponse = TuiShowToastResponses[keyof TuiShowToastResponses] export type TuiPublishData = { - body?: EventTuiPromptAppend | EventTuiCommandExecute | EventTuiToastShow | EventTuiSessionSelect + body?: EventTuiPromptAppend2 | EventTuiCommandExecute2 | EventTuiToastShow2 | EventTuiSessionSelect2 path?: never query?: { directory?: string @@ -9502,6 +10716,3465 @@ 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 + permission?: { + [key: string]: unknown + } + prompt: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/agent-builder/preview" +} + +export type AgentBuilderPreviewErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +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 + permission?: { + [key: string]: unknown + } + prompt: string + } + path: { + id: string + } + query?: { + directory?: string + workspace?: string + } + url: "/agent-builder/{id}" +} + +export type AgentBuilderSaveErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +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 + query?: { + directory?: string + workspace?: string + } + url: "/background-process" +} + +export type BackgroundProcessListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type BackgroundProcessListError = BackgroundProcessListErrors[keyof BackgroundProcessListErrors] + +export type BackgroundProcessListResponses = { + /** + * List of background processes + */ + 200: Array +} + +export type BackgroundProcessListResponse = BackgroundProcessListResponses[keyof BackgroundProcessListResponses] + +export type BackgroundProcessGetData = { + body?: never + path: { + processID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/background-process/{processID}" +} + +export type BackgroundProcessGetErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type BackgroundProcessGetError = BackgroundProcessGetErrors[keyof BackgroundProcessGetErrors] + +export type BackgroundProcessGetResponses = { + /** + * Background process info + */ + 200: BackgroundProcessInfo +} + +export type BackgroundProcessGetResponse = BackgroundProcessGetResponses[keyof BackgroundProcessGetResponses] + +export type BackgroundProcessLogsData = { + body?: never + path: { + processID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/background-process/{processID}/logs" +} + +export type BackgroundProcessLogsErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type BackgroundProcessLogsError = BackgroundProcessLogsErrors[keyof BackgroundProcessLogsErrors] + +export type BackgroundProcessLogsResponses = { + /** + * Background process logs + */ + 200: BackgroundProcessLogs +} + +export type BackgroundProcessLogsResponse = BackgroundProcessLogsResponses[keyof BackgroundProcessLogsResponses] + +export type BackgroundProcessStopData = { + body?: never + path: { + processID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/background-process/{processID}/stop" +} + +export type BackgroundProcessStopErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type BackgroundProcessStopError = BackgroundProcessStopErrors[keyof BackgroundProcessStopErrors] + +export type BackgroundProcessStopResponses = { + /** + * Stopped background process + */ + 200: BackgroundProcessInfo +} + +export type BackgroundProcessStopResponse = BackgroundProcessStopResponses[keyof BackgroundProcessStopResponses] + +export type BackgroundProcessRestartData = { + body?: never + path: { + processID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/background-process/{processID}/restart" +} + +export type BackgroundProcessRestartErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type BackgroundProcessRestartError = BackgroundProcessRestartErrors[keyof BackgroundProcessRestartErrors] + +export type BackgroundProcessRestartResponses = { + /** + * Restarted background process + */ + 200: BackgroundProcessInfo +} + +export type BackgroundProcessRestartResponse = + BackgroundProcessRestartResponses[keyof BackgroundProcessRestartResponses] + +export type BackgroundProcessStopSessionData = { + body?: never + path: { + sessionID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/background-process/session/{sessionID}/stop" +} + +export type BackgroundProcessStopSessionErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type BackgroundProcessStopSessionError = + BackgroundProcessStopSessionErrors[keyof BackgroundProcessStopSessionErrors] + +export type BackgroundProcessStopSessionResponses = { + /** + * Stopped session background processes + */ + 200: boolean +} + +export type BackgroundProcessStopSessionResponse = + BackgroundProcessStopSessionResponses[keyof BackgroundProcessStopSessionResponses] + +export type BranchNameGenerateData = { + body?: { + prompt: string + providerID?: string + modelID?: string + } + path: { + sessionID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/session/{sessionID}/branch-name" +} + +export type BranchNameGenerateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type BranchNameGenerateError = BranchNameGenerateErrors[keyof BranchNameGenerateErrors] + +export type BranchNameGenerateResponses = { + /** + * Generated branch name or null when the task is not clear yet + */ + 200: { + branch: string | null + } +} + +export type BranchNameGenerateResponse = BranchNameGenerateResponses[keyof BranchNameGenerateResponses] + +export type CommitMessageGenerateData = { + body?: { + /** + * Workspace/repo path + */ + path: string + selectedFiles?: Array + previousMessage?: string + language?: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/commit-message" +} + +export type CommitMessageGenerateErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * CommitMessageNoChangesError + */ + 422: CommitMessageNoChangesError +} + +export type CommitMessageGenerateError = CommitMessageGenerateErrors[keyof CommitMessageGenerateErrors] + +export type CommitMessageGenerateResponses = { + /** + * Generated commit message + */ + 200: { + message: string + } +} + +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 ConfigOverlayErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigOverlayError = ConfigOverlayErrors[keyof ConfigOverlayErrors] + +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> + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/config/overlay" +} + +export type ConfigOverlayUpdateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigOverlayUpdateError = ConfigOverlayUpdateErrors[keyof ConfigOverlayUpdateErrors] + +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 ConfigSourcesErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigSourcesError = ConfigSourcesErrors[keyof ConfigSourcesErrors] + +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 ConfigEffectiveErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigEffectiveError = ConfigEffectiveErrors[keyof ConfigEffectiveErrors] + +export type ConfigEffectiveResponses = { + /** + * Effective config info + */ + 200: Config +} + +export type ConfigEffectiveResponse = ConfigEffectiveResponses[keyof ConfigEffectiveResponses] + +export type ConfigRulesData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + scope?: "project" + } + url: "/config/rules" +} + +export type ConfigRulesErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigRulesError = ConfigRulesErrors[keyof ConfigRulesErrors] + +export type ConfigRulesResponses = { + /** + * Project rules + */ + 200: ConfigRulesResponse +} + +export type ConfigRulesResponse2 = ConfigRulesResponses[keyof ConfigRulesResponses] + +export type ConfigRulesUpdateData = { + body?: { + scope?: "project" + content: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/config/rules" +} + +export type ConfigRulesUpdateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigRulesUpdateError = ConfigRulesUpdateErrors[keyof ConfigRulesUpdateErrors] + +export type ConfigRulesUpdateResponses = { + /** + * Project rules after update + */ + 200: ConfigRulesResponse +} + +export type ConfigRulesUpdateResponse = ConfigRulesUpdateResponses[keyof ConfigRulesUpdateResponses] + +export type ConfigModelStateData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/config/model-state" +} + +export type ConfigModelStateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigModelStateError = ConfigModelStateErrors[keyof ConfigModelStateErrors] + +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 ConfigModelStateUpdateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type ConfigModelStateUpdateError = ConfigModelStateUpdateErrors[keyof ConfigModelStateUpdateErrors] + +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 TuiConfigGetErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TuiConfigGetError = TuiConfigGetErrors[keyof TuiConfigGetErrors] + +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 + } + /** + * Status icon style shown in terminal titles + */ + title_icon?: "none" | "unicode" | "emojis" + scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + scroll_acceleration?: { + enabled: boolean + } + diff_style?: "auto" | "stacked" + mouse?: boolean + attention?: { + enabled?: boolean + notifications?: boolean + sound?: boolean + volume?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" + } + } + path?: never + query?: { + directory?: string + workspace?: string + scope?: "project" | "global" + } + url: "/tui/config" +} + +export type TuiConfigUpdateErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +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 TuiKeybindListData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/tui/keybinds" +} + +export type TuiKeybindListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TuiKeybindListError = TuiKeybindListErrors[keyof TuiKeybindListErrors] + +export type TuiKeybindListResponses = { + /** + * TUI keybind metadata + */ + 200: TuiKeybindListResponse +} + +export type TuiKeybindListResponse2 = TuiKeybindListResponses[keyof TuiKeybindListResponses] + +export type EnhancePromptEnhanceData = { + body?: { + /** + * The user's draft prompt to enhance + */ + text: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/enhance-prompt" +} + +export type EnhancePromptEnhanceErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type EnhancePromptEnhanceError = EnhancePromptEnhanceErrors[keyof EnhancePromptEnhanceErrors] + +export type EnhancePromptEnhanceResponses = { + /** + * Enhanced prompt text + */ + 200: { + text: string + } +} + +export type EnhancePromptEnhanceResponse = EnhancePromptEnhanceResponses[keyof EnhancePromptEnhanceResponses] + +export type IndexingStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/indexing/status" +} + +export type IndexingStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type IndexingStatusError = IndexingStatusErrors[keyof IndexingStatusErrors] + +export type IndexingStatusResponses = { + /** + * Indexing status + */ + 200: IndexingStatus +} + +export type IndexingStatusResponse = IndexingStatusResponses[keyof IndexingStatusResponses] + +export type IndexingWarningsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/indexing/warnings" +} + +export type IndexingWarningsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type IndexingWarningsError = IndexingWarningsErrors[keyof IndexingWarningsErrors] + +export type IndexingWarningsResponses = { + /** + * Indexing warnings + */ + 200: Array +} + +export type IndexingWarningsResponse = IndexingWarningsResponses[keyof IndexingWarningsResponses] + +export type IndexingModelsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/indexing/models" +} + +export type IndexingModelsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type IndexingModelsError = IndexingModelsErrors[keyof IndexingModelsErrors] + +export type IndexingModelsResponses = { + /** + * Kilo embedding model catalog + */ + 200: KiloEmbeddingModelCatalog +} + +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 + query?: { + directory?: string + workspace?: string + } + url: "/interactive-terminal" +} + +export type InteractiveTerminalListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type InteractiveTerminalListError = InteractiveTerminalListErrors[keyof InteractiveTerminalListErrors] + +export type InteractiveTerminalListResponses = { + /** + * List of interactive terminals + */ + 200: Array +} + +export type InteractiveTerminalListResponse = InteractiveTerminalListResponses[keyof InteractiveTerminalListResponses] + +export type InteractiveTerminalGetData = { + body?: never + path: { + terminalID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/interactive-terminal/{terminalID}" +} + +export type InteractiveTerminalGetErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type InteractiveTerminalGetError = InteractiveTerminalGetErrors[keyof InteractiveTerminalGetErrors] + +export type InteractiveTerminalGetResponses = { + /** + * Interactive terminal snapshot + */ + 200: InteractiveTerminalSnapshot +} + +export type InteractiveTerminalGetResponse = InteractiveTerminalGetResponses[keyof InteractiveTerminalGetResponses] + +export type InteractiveTerminalWriteData = { + body?: InteractiveTerminalWriteInput + path: { + terminalID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/interactive-terminal/{terminalID}/input" +} + +export type InteractiveTerminalWriteErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type InteractiveTerminalWriteError = InteractiveTerminalWriteErrors[keyof InteractiveTerminalWriteErrors] + +export type InteractiveTerminalWriteResponses = { + /** + * Input written + */ + 200: boolean +} + +export type InteractiveTerminalWriteResponse = + InteractiveTerminalWriteResponses[keyof InteractiveTerminalWriteResponses] + +export type InteractiveTerminalResizeData = { + body?: InteractiveTerminalResizeInput + path: { + terminalID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/interactive-terminal/{terminalID}/resize" +} + +export type InteractiveTerminalResizeErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type InteractiveTerminalResizeError = InteractiveTerminalResizeErrors[keyof InteractiveTerminalResizeErrors] + +export type InteractiveTerminalResizeResponses = { + /** + * Terminal resized + */ + 200: boolean +} + +export type InteractiveTerminalResizeResponse = + InteractiveTerminalResizeResponses[keyof InteractiveTerminalResizeResponses] + +export type InteractiveTerminalCloseData = { + body?: never + path: { + terminalID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/interactive-terminal/{terminalID}/close" +} + +export type InteractiveTerminalCloseErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type InteractiveTerminalCloseError = InteractiveTerminalCloseErrors[keyof InteractiveTerminalCloseErrors] + +export type InteractiveTerminalCloseResponses = { + /** + * Terminal closed + */ + 200: boolean +} + +export type InteractiveTerminalCloseResponse = + InteractiveTerminalCloseResponses[keyof InteractiveTerminalCloseResponses] + +export type KiloProfileData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/profile" +} + +export type KiloProfileErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloProfileError = KiloProfileErrors[keyof KiloProfileErrors] + +export type KiloProfileResponses = { + /** + * Profile data + */ + 200: { + profile: { + email: string + name?: string + organizations?: Array<{ + id: string + name: string + role: string + }> + selectedOrganizationId?: string + hasPersonalAccount?: boolean + } + balance: { + balance: number + } | null + kiloPass: { + currentPeriodBaseCreditsUsd: number + currentPeriodUsageUsd: number + currentPeriodBonusCreditsUsd: number + nextBillingAt?: string | null + } | null + currentOrgId: string | null + } +} + +export type KiloProfileResponse = KiloProfileResponses[keyof KiloProfileResponses] + +export type KiloAuthStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/auth-status" +} + +export type KiloAuthStatusErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloAuthStatusError = KiloAuthStatusErrors[keyof KiloAuthStatusErrors] + +export type KiloAuthStatusResponses = { + /** + * Kilo authentication status + */ + 200: { + authenticated: boolean + type?: "api" | "oauth" + } +} + +export type KiloAuthStatusResponse = KiloAuthStatusResponses[keyof KiloAuthStatusResponses] + +export type KiloModesData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/modes" +} + +export type KiloModesErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type KiloModesError = KiloModesErrors[keyof KiloModesErrors] + +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 + provider?: string + model?: string + maxTokens?: number + temperature?: number + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/fim" +} + +export type KiloFimErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloFimError = KiloFimErrors[keyof KiloFimErrors] + +export type KiloFimResponses = { + /** + * Streaming FIM completion response + */ + 200: { + choices?: Array<{ + delta?: { + content?: string + } + text?: string + }> + usage?: { + prompt_tokens?: number + completion_tokens?: number + } + cost?: number + } +} + +export type KiloFimResponse = KiloFimResponses[keyof KiloFimResponses] + +export type KiloEditData = { + body?: { + provider?: string + model?: string + maxTokens?: number + currentFilePath: string + currentFileContent: string + cursorLine: number + cursorCharacter: number + editableRegionStartLine: number + editableRegionEndLine: number + recentlyViewedSnippets: Array<{ + filepath: string + content: string + }> + editDiffHistory: Array + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/edit" +} + +export type KiloEditErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloEditError = KiloEditErrors[keyof KiloEditErrors] + +export type KiloEditResponses = { + /** + * Next Edit completion + */ + 200: { + content: string + usage?: { + prompt_tokens?: number + completion_tokens?: number + } + } +} + +export type KiloEditResponse = KiloEditResponses[keyof KiloEditResponses] + +export type KiloAudioTranscriptionsData = { + body?: { + model: string + input_audio: { + data: string + format: string + } + language?: string + prompt?: string + temperature?: number + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/audio/transcriptions" +} + +export type KiloAudioTranscriptionsErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloAudioTranscriptionsError = KiloAudioTranscriptionsErrors[keyof KiloAudioTranscriptionsErrors] + +export type KiloAudioTranscriptionsResponses = { + /** + * Transcription response + */ + 200: { + text: string + usage?: unknown + } +} + +export type KiloAudioTranscriptionsResponse = KiloAudioTranscriptionsResponses[keyof KiloAudioTranscriptionsResponses] + +export type KiloModelsImagesData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/models/images" +} + +export type KiloModelsImagesErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloModelsImagesError = KiloModelsImagesErrors[keyof KiloModelsImagesErrors] + +export type KiloModelsImagesResponses = { + /** + * Image-capable model list + */ + 200: Array<{ + id: string + name: string + description?: string + }> +} + +export type KiloModelsImagesResponse = KiloModelsImagesResponses[keyof KiloModelsImagesResponses] + +export type KiloNotificationsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/notifications" +} + +export type KiloNotificationsErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloNotificationsError = KiloNotificationsErrors[keyof KiloNotificationsErrors] + +export type KiloNotificationsResponses = { + /** + * Notifications list + */ + 200: Array<{ + id: string + title: string + message: string + action?: { + actionText: string + actionURL: string + } + showIn?: Array + suggestModelId?: string + }> +} + +export type KiloNotificationsResponse = KiloNotificationsResponses[keyof KiloNotificationsResponses] + +export type KiloOrganizationSetData = { + body?: { + organizationId: string | null + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/organization" +} + +export type KiloOrganizationSetErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloOrganizationSetError = KiloOrganizationSetErrors[keyof KiloOrganizationSetErrors] + +export type KiloOrganizationSetResponses = { + /** + * Organization updated successfully + */ + 200: boolean +} + +export type KiloOrganizationSetResponse = KiloOrganizationSetResponses[keyof KiloOrganizationSetResponses] + +export type KiloClawStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/claw/status" +} + +export type KiloClawStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * ServiceUnavailable + */ + 503: EffectHttpApiErrorServiceUnavailable +} + +export type KiloClawStatusError = KiloClawStatusErrors[keyof KiloClawStatusErrors] + +export type KiloClawStatusResponses = { + /** + * Instance status + */ + 200: { + status: + | "provisioned" + | "starting" + | "restarting" + | "recovering" + | "running" + | "stopped" + | "destroying" + | "restoring" + | null + sandboxId?: string + flyRegion?: string + machineSize?: { + cpus: number + memory_mb: number + } + openclawVersion?: string | null + lastStartedAt?: string | null + lastStoppedAt?: string | null + channelCount?: number + secretCount?: number + userId?: string + botName?: string | null + } +} + +export type KiloClawStatusResponse = KiloClawStatusResponses[keyof KiloClawStatusResponses] + +export type KiloClawChatCredentialsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/claw/chat-credentials" +} + +export type KiloClawChatCredentialsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type KiloClawChatCredentialsError = KiloClawChatCredentialsErrors[keyof KiloClawChatCredentialsErrors] + +export type KiloClawChatCredentialsResponses = { + /** + * Kilo Chat credentials or null + */ + 200: { + token: string + expiresAt: string + kiloChatUrl: string + eventServiceUrl: string + } | null +} + +export type KiloClawChatCredentialsResponse = KiloClawChatCredentialsResponses[keyof KiloClawChatCredentialsResponses] + +export type KiloCloudSessionsData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + cursor?: string + limit?: number + gitUrl?: string + } + url: "/kilo/cloud-sessions" +} + +export type KiloCloudSessionsErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KiloCloudSessionsError = KiloCloudSessionsErrors[keyof KiloCloudSessionsErrors] + +export type KiloCloudSessionsResponses = { + /** + * Cloud sessions list + */ + 200: { + cliSessions: Array<{ + session_id: string + title: string | null + created_at: string + updated_at: string + version: number + }> + nextCursor: string | null + } +} + +export type KiloCloudSessionsResponse = KiloCloudSessionsResponses[keyof KiloCloudSessionsResponses] + +export type KiloCloudSessionGetData = { + body?: never + path: { + id: string + } + query?: { + directory?: string + workspace?: string + } + url: "/kilo/cloud/session/{id}" +} + +export type KiloCloudSessionGetErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type KiloCloudSessionGetError = KiloCloudSessionGetErrors[keyof KiloCloudSessionGetErrors] + +export type KiloCloudSessionGetResponses = { + /** + * Cloud session data + */ + 200: { + info: { + id: string + title: string + time: { + created: number + updated: number + } + } + messages: Array<{ + info: { + id: string + sessionID: string + role: "user" | "assistant" + time: { + created: number + completed?: number + } + } + parts: Array<{ + id: string + sessionID: string + messageID: string + type: string + }> + }> + } +} + +export type KiloCloudSessionGetResponse = KiloCloudSessionGetResponses[keyof KiloCloudSessionGetResponses] + +export type KiloCloudSessionImportData = { + body?: { + sessionId: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilo/cloud/session/import" +} + +export type KiloCloudSessionImportErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type KiloCloudSessionImportError = KiloCloudSessionImportErrors[keyof KiloCloudSessionImportErrors] + +export type KiloCloudSessionImportResponses = { + /** + * Imported session info + */ + 200: { + id: string + title: string + time: { + created: number + updated: number + } + } +} + +export type KiloCloudSessionImportResponse = KiloCloudSessionImportResponses[keyof KiloCloudSessionImportResponses] + +export type KilocodeHeapSnapshotData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/heap/snapshot" +} + +export type KilocodeHeapSnapshotErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeHeapSnapshotError = KilocodeHeapSnapshotErrors[keyof KilocodeHeapSnapshotErrors] + +export type KilocodeHeapSnapshotResponses = { + /** + * Heap snapshot file path + */ + 200: string +} + +export type KilocodeHeapSnapshotResponse = KilocodeHeapSnapshotResponses[keyof KilocodeHeapSnapshotResponses] + +export type KilocodeAgentRequirementsData = { + body?: never + path?: never + query: { + directory?: string + workspace?: string + agent: string + } + url: "/kilocode/agent/requirements" +} + +export type KilocodeAgentRequirementsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type KilocodeAgentRequirementsError = KilocodeAgentRequirementsErrors[keyof KilocodeAgentRequirementsErrors] + +export type KilocodeAgentRequirementsResponses = { + /** + * Agent requirement status + */ + 200: AgentRequirementResult +} + +export type KilocodeAgentRequirementsResponse = + KilocodeAgentRequirementsResponses[keyof KilocodeAgentRequirementsResponses] + +export type KilocodeRemoveSkillData = { + body?: { + location: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/skill/remove" +} + +export type KilocodeRemoveSkillErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeRemoveSkillError = KilocodeRemoveSkillErrors[keyof KilocodeRemoveSkillErrors] + +export type KilocodeRemoveSkillResponses = { + /** + * Skill removed + */ + 200: boolean +} + +export type KilocodeRemoveSkillResponse = KilocodeRemoveSkillResponses[keyof KilocodeRemoveSkillResponses] + +export type KilocodeRemoveAgentData = { + body?: { + name: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/agent/remove" +} + +export type KilocodeRemoveAgentErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeRemoveAgentError = KilocodeRemoveAgentErrors[keyof KilocodeRemoveAgentErrors] + +export type KilocodeRemoveAgentResponses = { + /** + * Agent removed + */ + 200: boolean +} + +export type KilocodeRemoveAgentResponse = KilocodeRemoveAgentResponses[keyof KilocodeRemoveAgentResponses] + +export type KilocodeNotebookListData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/notebook" +} + +export type KilocodeNotebookListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type KilocodeNotebookListError = KilocodeNotebookListErrors[keyof KilocodeNotebookListErrors] + +export type KilocodeNotebookListResponses = { + /** + * Pending notebook host requests + */ + 200: Array +} + +export type KilocodeNotebookListResponse = KilocodeNotebookListResponses[keyof KilocodeNotebookListResponses] + +export type KilocodeNotebookReplyData = { + body?: { + result: NotebookResult + } + path: { + requestID: NotebookRequestId + } + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/notebook/{requestID}/reply" +} + +export type KilocodeNotebookReplyErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type KilocodeNotebookReplyError = KilocodeNotebookReplyErrors[keyof KilocodeNotebookReplyErrors] + +export type KilocodeNotebookReplyResponses = { + /** + * Notebook reply accepted + */ + 200: boolean +} + +export type KilocodeNotebookReplyResponse = KilocodeNotebookReplyResponses[keyof KilocodeNotebookReplyResponses] + +export type KilocodeNotebookRejectData = { + body?: { + error: NotebookFailure + } + path: { + requestID: NotebookRequestId + } + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/notebook/{requestID}/reject" +} + +export type KilocodeNotebookRejectErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type KilocodeNotebookRejectError = KilocodeNotebookRejectErrors[keyof KilocodeNotebookRejectErrors] + +export type KilocodeNotebookRejectResponses = { + /** + * Notebook rejection accepted + */ + 200: boolean +} + +export type KilocodeNotebookRejectResponse = KilocodeNotebookRejectResponses[keyof KilocodeNotebookRejectResponses] + +export type KilocodeSessionModelUsageData = { + body?: never + path: { + sessionID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/session/{sessionID}/model-usage" +} + +export type KilocodeSessionModelUsageErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type KilocodeSessionModelUsageError = KilocodeSessionModelUsageErrors[keyof KilocodeSessionModelUsageErrors] + +export type KilocodeSessionModelUsageResponses = { + /** + * Model usage for a session tree + */ + 200: { + sessionIDs: Array + totals: { + steps: number + cost: number + tokens: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + } + models: Array<{ + providerID: string + modelID: string + steps: number + cost: number + tokens: { + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + }> + } +} + +export type KilocodeSessionModelUsageResponse = + KilocodeSessionModelUsageResponses[keyof KilocodeSessionModelUsageResponses] + +export type AnacondaDesktopStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/anaconda-desktop/status" +} + +export type AnacondaDesktopStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type AnacondaDesktopStatusError = AnacondaDesktopStatusErrors[keyof AnacondaDesktopStatusErrors] + +export type AnacondaDesktopStatusResponses = { + /** + * Anaconda Desktop setup status + */ + 200: AnacondaDesktopStatus +} + +export type AnacondaDesktopStatusResponse = AnacondaDesktopStatusResponses[keyof AnacondaDesktopStatusResponses] + +export type AnacondaDesktopOpenData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/anaconda-desktop/open" +} + +export type AnacondaDesktopOpenErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * AnacondaDesktopConflictError + */ + 409: AnacondaDesktopConflictError + /** + * AnacondaDesktopOperationError + */ + 500: AnacondaDesktopOperationError +} + +export type AnacondaDesktopOpenError = AnacondaDesktopOpenErrors[keyof AnacondaDesktopOpenErrors] + +export type AnacondaDesktopOpenResponses = { + /** + * Anaconda Desktop opened + */ + 200: true +} + +export type AnacondaDesktopOpenResponse = AnacondaDesktopOpenResponses[keyof AnacondaDesktopOpenResponses] + +export type AnacondaDesktopSyncData = { + body?: { + acknowledgeToolLimitations?: boolean + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/anaconda-desktop/sync" +} + +export type AnacondaDesktopSyncErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * AnacondaDesktopConflictError + */ + 409: AnacondaDesktopConflictError + /** + * AnacondaDesktopOperationError + */ + 500: AnacondaDesktopOperationError +} + +export type AnacondaDesktopSyncError = AnacondaDesktopSyncErrors[keyof AnacondaDesktopSyncErrors] + +export type AnacondaDesktopSyncResponses = { + /** + * Anaconda Desktop connection synchronized + */ + 200: { + type: "ready" + serverID: string + serverName?: string + models: Array<{ + id: string + name: string + }> + context: number + toolcall: "supported" | "unsupported" | "unknown" + } +} + +export type AnacondaDesktopSyncResponse = AnacondaDesktopSyncResponses[keyof AnacondaDesktopSyncResponses] + +export type NetworkListData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/network" +} + +export type NetworkListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type NetworkListError = NetworkListErrors[keyof NetworkListErrors] + +export type NetworkListResponses = { + /** + * List of pending network reconnect requests + */ + 200: Array +} + +export type NetworkListResponse = NetworkListResponses[keyof NetworkListResponses] + +export type NetworkReplyData = { + body?: never + path: { + requestID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/network/{requestID}/reply" +} + +export type NetworkReplyErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type NetworkReplyError = NetworkReplyErrors[keyof NetworkReplyErrors] + +export type NetworkReplyResponses = { + /** + * Network wait resumed successfully + */ + 200: boolean +} + +export type NetworkReplyResponse = NetworkReplyResponses[keyof NetworkReplyResponses] + +export type NetworkRejectData = { + body?: never + path: { + requestID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/network/{requestID}/reject" +} + +export type NetworkRejectErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type NetworkRejectError = NetworkRejectErrors[keyof NetworkRejectErrors] + +export type NetworkRejectResponses = { + /** + * Network wait rejected successfully + */ + 200: boolean +} + +export type NetworkRejectResponse = NetworkRejectResponses[keyof NetworkRejectResponses] + +export type RemoteEnableData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/remote/enable" +} + +export type RemoteEnableErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type RemoteEnableError = RemoteEnableErrors[keyof RemoteEnableErrors] + +export type RemoteEnableResponses = { + /** + * Remote connection enabled + */ + 200: { + enabled: boolean + connected: boolean + } +} + +export type RemoteEnableResponse = RemoteEnableResponses[keyof RemoteEnableResponses] + +export type RemoteDisableData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/remote/disable" +} + +export type RemoteDisableErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type RemoteDisableError = RemoteDisableErrors[keyof RemoteDisableErrors] + +export type RemoteDisableResponses = { + /** + * Remote connection disabled + */ + 200: { + enabled: boolean + connected: boolean + } +} + +export type RemoteDisableResponse = RemoteDisableResponses[keyof RemoteDisableResponses] + +export type RemoteStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/remote/status" +} + +export type RemoteStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type RemoteStatusError = RemoteStatusErrors[keyof RemoteStatusErrors] + +export type RemoteStatusResponses = { + /** + * Remote connection status + */ + 200: { + enabled: boolean + connected: boolean + } +} + +export type RemoteStatusResponse = RemoteStatusResponses[keyof RemoteStatusResponses] + +export type SandboxSupportData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/sandbox/support" +} + +export type SandboxSupportErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type SandboxSupportError = SandboxSupportErrors[keyof SandboxSupportErrors] + +export type SandboxSupportResponses = { + /** + * Sandbox backend support + */ + 200: { + available: boolean + reason?: string + } +} + +export type SandboxSupportResponse = SandboxSupportResponses[keyof SandboxSupportResponses] + +export type SandboxStatusData = { + body?: never + path: { + sessionID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/session/{sessionID}/sandbox" +} + +export type SandboxStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * NotFoundError + */ + 404: NotFoundError +} + +export type SandboxStatusError = SandboxStatusErrors[keyof SandboxStatusErrors] + +export type SandboxStatusResponses = { + /** + * Session sandbox status + */ + 200: { + directory: string + enabled: boolean + available: boolean + reason?: string + version: number + } +} + +export type SandboxStatusResponse = SandboxStatusResponses[keyof SandboxStatusResponses] + +export type SandboxToggleData = { + body?: never + path: { + sessionID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/session/{sessionID}/sandbox/toggle" +} + +export type SandboxToggleErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * NotFoundError + */ + 404: NotFoundError +} + +export type SandboxToggleError = SandboxToggleErrors[keyof SandboxToggleErrors] + +export type SandboxToggleResponses = { + /** + * Updated session sandbox status + */ + 200: { + directory: string + enabled: boolean + available: boolean + reason?: string + version: number + } +} + +export type SandboxToggleResponse = SandboxToggleResponses[keyof SandboxToggleResponses] + +export type KilocodeSessionImportProjectData = { + body?: { + id: string + worktree: string + vcs?: string + name?: string + iconUrl?: string + iconColor?: string + timeCreated: number + timeUpdated: number + timeInitialized?: number + sandboxes: Array + commands?: { + start?: string + } + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/session-import/project" +} + +export type KilocodeSessionImportProjectErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeSessionImportProjectError = + KilocodeSessionImportProjectErrors[keyof KilocodeSessionImportProjectErrors] + +export type KilocodeSessionImportProjectResponses = { + /** + * Project import result + */ + 200: KilocodeSessionImportResult +} + +export type KilocodeSessionImportProjectResponse = + KilocodeSessionImportProjectResponses[keyof KilocodeSessionImportProjectResponses] + +export type KilocodeSessionImportSessionData = { + body?: { + id: string + projectID: string + force?: boolean + workspaceID?: string + parentID?: string + slug: string + directory: string + title: string + version: string + shareURL?: string + summary?: { + additions: number + deletions: number + files: number + diffs?: Array<{ + [key: string]: unknown + }> + } + revert?: { + messageID: string + partID?: string + snapshot?: string + diff?: string + } + permission?: { + [key: string]: unknown + } + timeCreated: number + timeUpdated: number + timeCompacting?: number + timeArchived?: number + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/session-import/session" +} + +export type KilocodeSessionImportSessionErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeSessionImportSessionError = + KilocodeSessionImportSessionErrors[keyof KilocodeSessionImportSessionErrors] + +export type KilocodeSessionImportSessionResponses = { + /** + * Session import result + */ + 200: KilocodeSessionImportResult +} + +export type KilocodeSessionImportSessionResponse = + KilocodeSessionImportSessionResponses[keyof KilocodeSessionImportSessionResponses] + +export type KilocodeSessionImportMessageData = { + body?: { + id: string + sessionID: string + timeCreated: number + data: + | { + role: "user" + time: { + created: number + } + agent: string + model: { + providerID: string + modelID: string + } + tools?: { + [key: string]: boolean + } + } + | { + role: "assistant" + time: { + created: number + completed?: number + } + parentID: string + modelID: string + providerID: string + mode: string + agent: string + path: { + cwd: string + root: string + } + summary?: boolean + cost: number + tokens: { + total?: number + input: number + output: number + reasoning: number + cache: { + read: number + write: number + } + } + structured?: unknown + variant?: string + finish?: string + } + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/session-import/message" +} + +export type KilocodeSessionImportMessageErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeSessionImportMessageError = + KilocodeSessionImportMessageErrors[keyof KilocodeSessionImportMessageErrors] + +export type KilocodeSessionImportMessageResponses = { + /** + * Message import result + */ + 200: KilocodeSessionImportResult +} + +export type KilocodeSessionImportMessageResponse = + KilocodeSessionImportMessageResponses[keyof KilocodeSessionImportMessageResponses] + +export type KilocodeSessionImportPartData = { + body?: { + id: string + messageID: string + sessionID: string + timeCreated?: number + data: + | { + type: "text" + text: string + synthetic?: boolean + ignored?: boolean + time?: { + start: number + end?: number + } + metadata?: { + [key: string]: unknown + } + } + | { + type: "reasoning" + text: string + metadata?: { + [key: string]: unknown + } + time: { + start: number + end?: number + } + } + | { + type: "tool" + callID: string + tool: string + state: + | { + status: "pending" + input: { + [key: string]: unknown + } + raw: string + } + | { + status: "running" + input: { + [key: string]: unknown + } + title?: string + metadata?: { + [key: string]: unknown + } + time: { + start: number + } + } + | { + status: "completed" + input: { + [key: string]: unknown + } + output: string + title: string + metadata: { + [key: string]: unknown + } + time: { + start: number + end: number + compacted?: number + } + } + | { + status: "error" + input: { + [key: string]: unknown + } + error: string + metadata?: { + [key: string]: unknown + } + time: { + start: number + end: number + } + } + metadata?: { + [key: string]: unknown + } + } + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/kilocode/session-import/part" +} + +export type KilocodeSessionImportPartErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type KilocodeSessionImportPartError = KilocodeSessionImportPartErrors[keyof KilocodeSessionImportPartErrors] + +export type KilocodeSessionImportPartResponses = { + /** + * Part import result + */ + 200: KilocodeSessionImportResult +} + +export type KilocodeSessionImportPartResponse = + KilocodeSessionImportPartResponses[keyof KilocodeSessionImportPartResponses] + +export type SuggestionListData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/suggestion" +} + +export type SuggestionListErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type SuggestionListError = SuggestionListErrors[keyof SuggestionListErrors] + +export type SuggestionListResponses = { + /** + * List of pending suggestions + */ + 200: Array +} + +export type SuggestionListResponse = SuggestionListResponses[keyof SuggestionListResponses] + +export type SuggestionAcceptData = { + body?: { + /** + * Zero-based action index to accept + */ + index: number + } + path: { + requestID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/suggestion/{requestID}/accept" +} + +export type SuggestionAcceptErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type SuggestionAcceptError = SuggestionAcceptErrors[keyof SuggestionAcceptErrors] + +export type SuggestionAcceptResponses = { + /** + * Suggestion accepted successfully + */ + 200: boolean +} + +export type SuggestionAcceptResponse = SuggestionAcceptResponses[keyof SuggestionAcceptResponses] + +export type SuggestionDismissData = { + body?: never + path: { + requestID: string + } + query?: { + directory?: string + workspace?: string + } + url: "/suggestion/{requestID}/dismiss" +} + +export type SuggestionDismissErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError + /** + * Not found + */ + 404: NotFoundError +} + +export type SuggestionDismissError = SuggestionDismissErrors[keyof SuggestionDismissErrors] + +export type SuggestionDismissResponses = { + /** + * Suggestion dismissed successfully + */ + 200: boolean +} + +export type SuggestionDismissResponse = SuggestionDismissResponses[keyof SuggestionDismissResponses] + +export type TelemetryCaptureData = { + body?: { + /** + * Event name + */ + event: string + properties?: { + [key: string]: unknown + } + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/telemetry/capture" +} + +export type TelemetryCaptureErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type TelemetryCaptureError = TelemetryCaptureErrors[keyof TelemetryCaptureErrors] + +export type TelemetryCaptureResponses = { + /** + * Event captured + */ + 200: boolean +} + +export type TelemetryCaptureResponse = TelemetryCaptureResponses[keyof TelemetryCaptureResponses] + +export type TelemetrySetEnabledData = { + body?: { + enabled: boolean + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/telemetry/setEnabled" +} + +export type TelemetrySetEnabledErrors = { + /** + * BadRequest | InvalidRequestError + */ + 400: EffectHttpApiErrorBadRequest | InvalidRequestError +} + +export type TelemetrySetEnabledError = TelemetrySetEnabledErrors[keyof TelemetrySetEnabledErrors] + +export type TelemetrySetEnabledResponses = { + /** + * State updated + */ + 200: boolean +} + +export type TelemetrySetEnabledResponse = TelemetrySetEnabledResponses[keyof TelemetrySetEnabledResponses] + +export type MemoryStatusData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/status" +} + +export type MemoryStatusErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryStatusError = MemoryStatusErrors[keyof MemoryStatusErrors] + +export type MemoryStatusResponses = { + /** + * Memory status + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + exists: { + state: boolean + index: boolean + } + index: { + bytes: number + estimatedTokens: number + preview: string + } + } +} + +export type MemoryStatusResponse = MemoryStatusResponses[keyof MemoryStatusResponses] + +export type MemoryShowData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/show" +} + +export type MemoryShowErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryShowError = MemoryShowErrors[keyof MemoryShowErrors] + +export type MemoryShowResponses = { + /** + * Memory source and index + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + sources: { + project: string + environment: string + corrections: string + } + index: string + items: string + changes: string + decisions: string + } +} + +export type MemoryShowResponse = MemoryShowResponses[keyof MemoryShowResponses] + +export type MemoryEnableData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/enable" +} + +export type MemoryEnableErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryEnableError = MemoryEnableErrors[keyof MemoryEnableErrors] + +export type MemoryEnableResponses = { + /** + * Memory enabled + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + index: { + text: string + bytes: number + tokens: number + truncated: boolean + } + } +} + +export type MemoryEnableResponse = MemoryEnableResponses[keyof MemoryEnableResponses] + +export type MemoryDisableData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/disable" +} + +export type MemoryDisableErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryDisableError = MemoryDisableErrors[keyof MemoryDisableErrors] + +export type MemoryDisableResponses = { + /** + * Memory disabled + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + } +} + +export type MemoryDisableResponse = MemoryDisableResponses[keyof MemoryDisableResponses] + +export type MemoryConfigureData = { + body?: { + autoConsolidate?: boolean + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/configure" +} + +export type MemoryConfigureErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryConfigureError = MemoryConfigureErrors[keyof MemoryConfigureErrors] + +export type MemoryConfigureResponses = { + /** + * Memory configured + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + } +} + +export type MemoryConfigureResponse = MemoryConfigureResponses[keyof MemoryConfigureResponses] + +export type MemoryRebuildData = { + body?: never + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/rebuild" +} + +export type MemoryRebuildErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryRebuildError = MemoryRebuildErrors[keyof MemoryRebuildErrors] + +export type MemoryRebuildResponses = { + /** + * Memory rebuilt + */ + 200: { + root: string + state: { + version: 1 + enabled: boolean + scope: "project" + autoInject: boolean + autoConsolidate: boolean + capture: { + mode: "selective" + turnClose: boolean + explicit: boolean + maxOpsPerRun: number + minIntervalMs: number + timeoutMs: number + } + limits: { + maxProjectIndexBytes: number + maxSessionFiles: number + maxRecentSessions: number + maxConsolidationInputBytes: number + maxLineChars: number + maxSessionLineChars: number + } + stats: { + lastInjectedAt: number + lastInjectedBytes: number + lastInjectedTokens: number + lastInjectedSessionID: string + lastTypedConsolidationAt: number + lastSessionSavedAt: number + lastConsolidationCost: number + lastConsolidationTokens: number + lastOperationCount: number + lastRecallAt: number + lastRecallCount: number + lastRecallSessionID: string + } + } + index: { + text: string + bytes: number + tokens: number + truncated: boolean + } + } +} + +export type MemoryRebuildResponse = MemoryRebuildResponses[keyof MemoryRebuildResponses] + +export type MemoryRememberData = { + body?: { + text: string + key?: string + file?: "project.md" | "environment.md" | "corrections.md" + section?: string + sessionID?: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/remember" +} + +export type MemoryRememberErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryRememberError = MemoryRememberErrors[keyof MemoryRememberErrors] + +export type MemoryRememberResponses = { + /** + * Memory operation result + */ + 200: { + operationCount: number + added: number + removed: number + skipped: Array<{ + reason: "self_referential" | "out_of_scope" | "secret" + text?: string + }> + index: { + text: string + bytes: number + tokens: number + truncated: boolean + } + } +} + +export type MemoryRememberResponse = MemoryRememberResponses[keyof MemoryRememberResponses] + +export type MemoryCorrectData = { + body?: { + text: string + key?: string + sessionID?: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/correct" +} + +export type MemoryCorrectErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryCorrectError = MemoryCorrectErrors[keyof MemoryCorrectErrors] + +export type MemoryCorrectResponses = { + /** + * Memory correction result + */ + 200: { + operationCount: number + added: number + removed: number + skipped: Array<{ + reason: "self_referential" | "out_of_scope" | "secret" + text?: string + }> + index: { + text: string + bytes: number + tokens: number + truncated: boolean + } + } +} + +export type MemoryCorrectResponse = MemoryCorrectResponses[keyof MemoryCorrectResponses] + +export type MemoryForgetData = { + body?: { + query: string + sessionID?: string + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/forget" +} + +export type MemoryForgetErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryForgetError = MemoryForgetErrors[keyof MemoryForgetErrors] + +export type MemoryForgetResponses = { + /** + * Memory forget result + */ + 200: { + operationCount: number + added: number + removed: number + skipped: Array<{ + reason: "self_referential" | "out_of_scope" | "secret" + text?: string + }> + index: { + text: string + bytes: number + tokens: number + truncated: boolean + } + } +} + +export type MemoryForgetResponse = MemoryForgetResponses[keyof MemoryForgetResponses] + +export type MemoryPurgeData = { + body?: { + confirm: true + } + path?: never + query?: { + directory?: string + workspace?: string + } + url: "/memory/purge" +} + +export type MemoryPurgeErrors = { + /** + * MemoryApiClientError | InvalidRequestError + */ + 400: MemoryApiClientError | InvalidRequestError + /** + * MemoryApiServerError + */ + 503: MemoryApiServerError +} + +export type MemoryPurgeError = MemoryPurgeErrors[keyof MemoryPurgeErrors] + +export type MemoryPurgeResponses = { + /** + * Memory purged + */ + 200: { + root: string + purged: boolean + } +} + +export type MemoryPurgeResponse = MemoryPurgeResponses[keyof MemoryPurgeResponses] + export type V2HealthGetData = { body?: never path?: never diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 553f2acb26..3fac440a76 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -4309,14 +4309,6 @@ }, "required": true }, - { - "name": "directory", - "in": "query", - "schema": { - "type": "string" - }, - "required": false - }, { "name": "workspace", "in": "query", @@ -4358,9 +4350,12 @@ "properties": { "directory": { "type": "string" + }, + "force": { + "type": "boolean" } }, - "required": ["directory"], + "required": ["directory", "force"], "additionalProperties": false } } @@ -19596,7 +19591,7 @@ }, "/api/health": { "get": { - "tags": ["kilo experimental HttpApi"], + "tags": ["Kilo HttpApi"], "operationId": "v2.health.get", "parameters": [], "security": [], @@ -19640,8 +19635,8 @@ } } }, - "description": "Check whether the v2 API server is ready to accept requests.", - "summary": "Check v2 server health", + "description": "Check whether the API server is ready to accept requests.", + "summary": "Check server health", "x-codeSamples": [ { "lang": "js", @@ -19650,9 +19645,77 @@ ] } }, + "/api/location": { + "get": { + "tags": ["Kilo HttpApi"], + "operationId": "v2.location.get", + "parameters": [ + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Location.Info", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LocationInfo" + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Resolve the requested location or the server default location.", + "summary": "Get location", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.location.get({\n ...\n})" + } + ] + } + }, "/api/agent": { "get": { - "tags": ["kilo experimental HttpApi"], + "tags": ["Kilo HttpApi"], "operationId": "v2.agent.list", "parameters": [ { @@ -19721,8 +19784,8 @@ } } }, - "description": "Retrieve currently registered v2 agents.", - "summary": "List v2 agents", + "description": "Retrieve currently registered agents.", + "summary": "List agents", "x-codeSamples": [ { "lang": "js", @@ -19733,7 +19796,7 @@ }, "/api/session": { "get": { - "tags": ["v2"], + "tags": ["sessions"], "operationId": "v2.session.list", "parameters": [ { @@ -19807,11 +19870,11 @@ "security": [], "responses": { "200": { - "description": "V2SessionsResponse", + "description": "SessionsResponse", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2SessionsResponse" + "$ref": "#/components/schemas/SessionsResponse" } } } @@ -19848,18 +19911,192 @@ } }, "description": "Retrieve sessions in the requested order. Items keep that order across pages; use cursor.next or cursor.previous to move through the ordered list.", - "summary": "List v2 sessions", + "summary": "List sessions", "x-codeSamples": [ { "lang": "js", "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.list({\n ...\n})" } ] + }, + "post": { + "tags": ["sessions"], + "operationId": "v2.session.create", + "parameters": [], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SessionV2Info" + } + }, + "required": ["data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Create a session at the requested location.", + "summary": "Create session", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "^ses" + }, + "agent": { + "type": "string" + }, + "model": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "providerID": { + "type": "string" + }, + "variant": { + "type": "string" + } + }, + "required": ["id", "providerID"], + "additionalProperties": false + }, + "location": { + "$ref": "#/components/schemas/LocationRef" + } + }, + "additionalProperties": false + } + } + }, + "required": true + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.create({\n ...\n})" + } + ] + } + }, + "/api/session/{sessionID}": { + "get": { + "tags": ["sessions"], + "operationId": "v2.session.get", + "parameters": [ + { + "name": "sessionID", + "in": "path", + "schema": { + "type": "string", + "pattern": "^ses.*" + }, + "required": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SessionV2Info" + } + }, + "required": ["data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + }, + "404": { + "description": "SessionNotFoundError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] + } + } + } + } + }, + "description": "Retrieve a session by ID.", + "summary": "Get session", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.get({\n ...\n})" + } + ] } }, "/api/session/{sessionID}/prompt": { "post": { - "tags": ["v2"], + "tags": ["sessions"], "operationId": "v2.session.prompt", "parameters": [ { @@ -19916,7 +20153,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] } } } @@ -19932,8 +20176,8 @@ } } }, - "description": "Durably admit one v2 session input and schedule agent-loop execution unless resume is false.", - "summary": "Send v2 message", + "description": "Durably admit one session input and schedule agent-loop execution unless resume is false.", + "summary": "Send message", "requestBody": { "content": { "application/json": { @@ -19972,7 +20216,7 @@ }, "/api/session/{sessionID}/compact": { "post": { - "tags": ["v2"], + "tags": ["sessions"], "operationId": "v2.session.compact", "parameters": [ { @@ -20015,7 +20259,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] } } } @@ -20031,8 +20282,8 @@ } } }, - "description": "Compact a v2 session conversation.", - "summary": "Compact v2 session", + "description": "Compact a session conversation.", + "summary": "Compact session", "x-codeSamples": [ { "lang": "js", @@ -20043,7 +20294,7 @@ }, "/api/session/{sessionID}/wait": { "post": { - "tags": ["v2"], + "tags": ["sessions"], "operationId": "v2.session.wait", "parameters": [ { @@ -20086,7 +20337,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] } } } @@ -20102,8 +20360,8 @@ } } }, - "description": "Wait for a v2 session agent loop to become idle.", - "summary": "Wait for v2 session", + "description": "Wait for a session agent loop to become idle.", + "summary": "Wait for session", "x-codeSamples": [ { "lang": "js", @@ -20114,7 +20372,7 @@ }, "/api/session/{sessionID}/context": { "get": { - "tags": ["v2"], + "tags": ["sessions"], "operationId": "v2.session.context", "parameters": [ { @@ -20174,7 +20432,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] } } } @@ -20190,8 +20455,8 @@ } } }, - "description": "Retrieve the active context messages for a v2 session (all messages after the last compaction).", - "summary": "Get v2 session context", + "description": "Retrieve the active context messages for a session (all messages after the last compaction).", + "summary": "Get session context", "x-codeSamples": [ { "lang": "js", @@ -20202,7 +20467,7 @@ }, "/api/session/{sessionID}/message": { "get": { - "tags": ["v2 messages"], + "tags": ["messages"], "operationId": "v2.session.messages", "parameters": [ { @@ -20244,11 +20509,11 @@ "security": [], "responses": { "200": { - "description": "V2SessionMessagesResponse", + "description": "SessionMessagesResponse", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/V2SessionMessagesResponse" + "$ref": "#/components/schemas/SessionMessagesResponse" } } } @@ -20285,7 +20550,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] } } } @@ -20301,8 +20573,8 @@ } } }, - "description": "Retrieve projected v2 messages for a session. Items keep the requested order across pages; use cursor.next or cursor.previous to move through the ordered timeline.", - "summary": "Get v2 session messages", + "description": "Retrieve projected messages for a session. Items keep the requested order across pages; use cursor.next or cursor.previous to move through the ordered timeline.", + "summary": "Get session messages", "x-codeSamples": [ { "lang": "js", @@ -20313,7 +20585,7 @@ }, "/api/model": { "get": { - "tags": ["v2 models"], + "tags": ["models"], "operationId": "v2.model.list", "parameters": [ { @@ -20392,8 +20664,8 @@ } } }, - "description": "Retrieve available v2 models ordered by release date.", - "summary": "List v2 models", + "description": "Retrieve available models ordered by release date.", + "summary": "List models", "x-codeSamples": [ { "lang": "js", @@ -20404,7 +20676,7 @@ }, "/api/provider": { "get": { - "tags": ["v2 providers"], + "tags": ["providers"], "operationId": "v2.provider.list", "parameters": [ { @@ -20483,8 +20755,8 @@ } } }, - "description": "Retrieve active v2 AI providers so clients can show provider availability and configuration.", - "summary": "List v2 providers", + "description": "Retrieve active AI providers so clients can show provider availability and configuration.", + "summary": "List providers", "x-codeSamples": [ { "lang": "js", @@ -20495,7 +20767,7 @@ }, "/api/provider/{providerID}": { "get": { - "tags": ["v2 providers"], + "tags": ["providers"], "operationId": "v2.provider.get", "parameters": [ { @@ -20589,8 +20861,8 @@ } } }, - "description": "Retrieve a single v2 AI provider so clients can inspect its availability and endpoint settings.", - "summary": "Get v2 provider", + "description": "Retrieve a single AI provider so clients can inspect its availability and endpoint settings.", + "summary": "Get provider", "x-codeSamples": [ { "lang": "js", @@ -20599,9 +20871,905 @@ ] } }, + "/api/connector": { + "get": { + "tags": ["connectors"], + "operationId": "v2.connector.list", + "parameters": [ + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConnectorInfo" + } + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Retrieve available connectors and their authentication methods.", + "summary": "List connectors", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.list({\n ...\n})" + } + ] + } + }, + "/api/connector/{connectorID}": { + "get": { + "tags": ["connectors"], + "operationId": "v2.connector.get", + "parameters": [ + { + "name": "connectorID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "$ref": "#/components/schemas/ConnectorInfo" + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Retrieve one connector and its authentication methods.", + "summary": "Get connector", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.get({\n ...\n})" + } + ] + } + }, + "/api/connector/{connectorID}/connect/key": { + "post": { + "tags": ["connectors"], + "operationId": "v2.connector.connect.key", + "parameters": [ + { + "name": "connectorID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "204": { + "description": "" + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/InvalidRequestError" + }, + { + "$ref": "#/components/schemas/InvalidRequestError" + } + ] + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Run a key authentication method and store the resulting credential.", + "summary": "Connect with key", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "methodID": { + "type": "string" + }, + "key": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "label": { + "type": "string" + } + }, + "required": ["methodID", "key", "inputs"], + "additionalProperties": false + } + } + }, + "required": true + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.connect.key({\n ...\n})" + } + ] + } + }, + "/api/connector/{connectorID}/connect/oauth": { + "post": { + "tags": ["connectors"], + "operationId": "v2.connector.connect.oauth.begin", + "parameters": [ + { + "name": "connectorID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "$ref": "#/components/schemas/ConnectorAttempt" + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/InvalidRequestError" + }, + { + "$ref": "#/components/schemas/InvalidRequestError" + } + ] + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Start an OAuth attempt and return the authorization details.", + "summary": "Begin OAuth connection", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "methodID": { + "type": "string" + }, + "inputs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "label": { + "type": "string" + } + }, + "required": ["methodID", "inputs"], + "additionalProperties": false + } + } + }, + "required": true + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.connect.oauth.begin({\n ...\n})" + } + ] + } + }, + "/api/connector/oauth/{attemptID}": { + "get": { + "tags": ["connectors"], + "operationId": "v2.connector.connect.oauth.status", + "parameters": [ + { + "name": "attemptID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "anyOf": [ + { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": ["pending"] + }, + "time": { + "type": "object", + "properties": { + "created": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "expires": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + } + }, + "required": ["created", "expires"], + "additionalProperties": false + } + }, + "required": ["status", "time"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": ["complete"] + }, + "time": { + "type": "object", + "properties": { + "created": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "expires": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + } + }, + "required": ["created", "expires"], + "additionalProperties": false + } + }, + "required": ["status", "time"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": ["failed"] + }, + "message": { + "type": "string" + }, + "time": { + "type": "object", + "properties": { + "created": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "expires": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + } + }, + "required": ["created", "expires"], + "additionalProperties": false + } + }, + "required": ["status", "message", "time"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "status": { + "type": "string", + "enum": ["expired"] + }, + "time": { + "type": "object", + "properties": { + "created": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "expires": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + } + }, + "required": ["created", "expires"], + "additionalProperties": false + } + }, + "required": ["status", "time"], + "additionalProperties": false + } + ] + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Poll the current status of an OAuth attempt.", + "summary": "Get OAuth attempt status", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.connect.oauth.status({\n ...\n})" + } + ] + }, + "delete": { + "tags": ["connectors"], + "operationId": "v2.connector.connect.oauth.cancel", + "parameters": [ + { + "name": "attemptID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "204": { + "description": "" + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Cancel an OAuth attempt and release its resources.", + "summary": "Cancel OAuth connection", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.connect.oauth.cancel({\n ...\n})" + } + ] + } + }, + "/api/connector/oauth/{attemptID}/complete": { + "post": { + "tags": ["connectors"], + "operationId": "v2.connector.connect.oauth.complete", + "parameters": [ + { + "name": "attemptID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "204": { + "description": "" + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/InvalidRequestError" + }, + { + "$ref": "#/components/schemas/InvalidRequestError" + } + ] + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Complete a code-based OAuth attempt and store the resulting credential.", + "summary": "Complete OAuth connection", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, + "required": true + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.connector.connect.oauth.complete({\n ...\n})" + } + ] + } + }, "/api/permission/request": { "get": { - "tags": ["v2 permissions"], + "tags": ["permissions"], "operationId": "v2.permission.request.list", "parameters": [ { @@ -20680,184 +21848,9 @@ ] } }, - "/api/session/{sessionID}/permission/request": { - "get": { - "tags": ["v2 session permissions"], - "operationId": "v2.session.permission.list", - "parameters": [ - { - "name": "sessionID", - "in": "path", - "schema": { - "type": "string", - "pattern": "^ses.*" - }, - "required": true - } - ], - "security": [], - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PermissionV2Request" - } - } - }, - "required": ["data"], - "additionalProperties": false - } - } - } - }, - "400": { - "description": "InvalidRequestError", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InvalidRequestError" - } - } - } - }, - "401": { - "description": "UnauthorizedError", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedError" - } - } - } - }, - "404": { - "description": "SessionNotFoundError", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SessionNotFoundError" - } - } - } - } - }, - "description": "Retrieve pending permission requests owned by a session.", - "summary": "List session permission requests", - "x-codeSamples": [ - { - "lang": "js", - "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.permission.list({\n ...\n})" - } - ] - } - }, - "/api/session/{sessionID}/permission/request/{requestID}/reply": { - "post": { - "tags": ["v2 session permissions"], - "operationId": "v2.session.permission.reply", - "parameters": [ - { - "name": "sessionID", - "in": "path", - "schema": { - "type": "string", - "pattern": "^ses.*" - }, - "required": true - }, - { - "name": "requestID", - "in": "path", - "schema": { - "type": "string", - "pattern": "^per" - }, - "required": true - } - ], - "security": [], - "responses": { - "204": { - "description": "" - }, - "400": { - "description": "InvalidRequestError", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/InvalidRequestError" - } - } - } - }, - "401": { - "description": "UnauthorizedError", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorizedError" - } - } - } - }, - "404": { - "description": "SessionNotFoundError | PermissionNotFoundError", - "content": { - "application/json": { - "schema": { - "anyOf": [ - { - "$ref": "#/components/schemas/SessionNotFoundError" - }, - { - "$ref": "#/components/schemas/PermissionNotFoundError" - } - ] - } - } - } - } - }, - "description": "Respond to a pending permission request owned by a session.", - "summary": "Reply to pending permission request", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "reply": { - "$ref": "#/components/schemas/PermissionV2Reply" - }, - "message": { - "type": "string" - } - }, - "required": ["reply"], - "additionalProperties": false - } - } - }, - "required": true - }, - "x-codeSamples": [ - { - "lang": "js", - "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.permission.reply({\n ...\n})" - } - ] - } - }, "/api/permission/saved": { "get": { - "tags": ["v2 saved permissions"], + "tags": ["permissions"], "operationId": "v2.permission.saved.list", "parameters": [ { @@ -20924,7 +21917,7 @@ }, "/api/permission/saved/{id}": { "delete": { - "tags": ["v2 saved permissions"], + "tags": ["permissions"], "operationId": "v2.permission.saved.remove", "parameters": [ { @@ -20972,9 +21965,194 @@ ] } }, - "/api/fs/read": { + "/api/session/{sessionID}/permission": { "get": { - "tags": ["v2 filesystem"], + "tags": ["permissions"], + "operationId": "v2.session.permission.list", + "parameters": [ + { + "name": "sessionID", + "in": "path", + "schema": { + "type": "string", + "pattern": "^ses.*" + }, + "required": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PermissionV2Request" + } + } + }, + "required": ["data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + }, + "404": { + "description": "SessionNotFoundError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] + } + } + } + } + }, + "description": "Retrieve pending permission requests owned by a session.", + "summary": "List session permission requests", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.permission.list({\n ...\n})" + } + ] + } + }, + "/api/session/{sessionID}/permission/{requestID}/reply": { + "post": { + "tags": ["permissions"], + "operationId": "v2.session.permission.reply", + "parameters": [ + { + "name": "sessionID", + "in": "path", + "schema": { + "type": "string", + "pattern": "^ses.*" + }, + "required": true + }, + { + "name": "requestID", + "in": "path", + "schema": { + "type": "string", + "pattern": "^per" + }, + "required": true + } + ], + "security": [], + "responses": { + "204": { + "description": "" + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + }, + "404": { + "description": "SessionNotFoundError | PermissionNotFoundError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/PermissionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] + } + } + } + } + }, + "description": "Respond to a pending permission request owned by a session.", + "summary": "Reply to pending permission request", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "reply": { + "$ref": "#/components/schemas/PermissionV2Reply" + }, + "message": { + "type": "string" + } + }, + "required": ["reply"], + "additionalProperties": false + } + } + }, + "required": true + }, + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.permission.reply({\n ...\n})" + } + ] + } + }, + "/api/fs/read/*": { + "get": { + "tags": ["filesystem"], "operationId": "v2.fs.read", "parameters": [ { @@ -20995,22 +22173,6 @@ "required": false, "style": "deepObject", "explode": true - }, - { - "name": "path", - "in": "query", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "reference", - "in": "query", - "schema": { - "type": "string" - }, - "required": false } ], "security": [], @@ -21018,26 +22180,10 @@ "200": { "description": "Success", "content": { - "application/json": { + "application/octet-stream": { "schema": { - "type": "object", - "properties": { - "location": { - "$ref": "#/components/schemas/LocationInfo" - }, - "data": { - "anyOf": [ - { - "$ref": "#/components/schemas/FileSystemTextContent" - }, - { - "$ref": "#/components/schemas/FileSystemBinaryContent" - } - ] - } - }, - "required": ["location", "data"], - "additionalProperties": false + "type": "string", + "format": "binary" } } } @@ -21063,7 +22209,7 @@ } } }, - "description": "Read one file relative to the requested location.", + "description": "Serve one file relative to the requested location.", "summary": "Read file", "x-codeSamples": [ { @@ -21075,7 +22221,7 @@ }, "/api/fs/list": { "get": { - "tags": ["v2 filesystem"], + "tags": ["filesystem"], "operationId": "v2.fs.list", "parameters": [ { @@ -21104,14 +22250,6 @@ "type": "string" }, "required": false - }, - { - "name": "reference", - "in": "query", - "schema": { - "type": "string" - }, - "required": false } ], "security": [], @@ -21170,9 +22308,115 @@ ] } }, + "/api/fs/find": { + "get": { + "tags": ["filesystem"], + "operationId": "v2.fs.find", + "parameters": [ + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + }, + { + "name": "query", + "in": "query", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": ["file", "directory"] + }, + "required": false + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "string" + }, + "required": false + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileSystemEntry" + } + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "Find recursively ranked filesystem entries relative to the requested location.", + "summary": "Find files", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.fs.find({\n ...\n})" + } + ] + } + }, "/api/command": { "get": { - "tags": ["v2 commands"], + "tags": ["commands"], "operationId": "v2.command.list", "parameters": [ { @@ -21241,8 +22485,8 @@ } } }, - "description": "Retrieve currently registered v2 commands.", - "summary": "List v2 commands", + "description": "Retrieve currently registered commands.", + "summary": "List commands", "x-codeSamples": [ { "lang": "js", @@ -21253,7 +22497,7 @@ }, "/api/skill": { "get": { - "tags": ["v2 skills"], + "tags": ["skills"], "operationId": "v2.skill.list", "parameters": [ { @@ -21322,8 +22566,8 @@ } } }, - "description": "Retrieve currently registered v2 skills.", - "summary": "List v2 skills", + "description": "Retrieve currently registered skills.", + "summary": "List skills", "x-codeSamples": [ { "lang": "js", @@ -21334,7 +22578,7 @@ }, "/api/event": { "get": { - "tags": ["v2 events"], + "tags": ["events"], "operationId": "v2.event.subscribe", "parameters": [ { @@ -21390,8 +22634,8 @@ } } }, - "description": "Subscribe to native EventV2 payloads for a location.", - "summary": "Subscribe to v2 events", + "description": "Subscribe to native event payloads for a location.", + "summary": "Subscribe to events", "x-codeSamples": [ { "lang": "js", @@ -21402,7 +22646,7 @@ }, "/api/question/request": { "get": { - "tags": ["v2 questions"], + "tags": ["session questions"], "operationId": "v2.question.request.list", "parameters": [ { @@ -21481,9 +22725,94 @@ ] } }, - "/api/session/{sessionID}/question/request/{requestID}/reply": { + "/api/session/{sessionID}/question": { + "get": { + "tags": ["session questions"], + "operationId": "v2.session.question.list", + "parameters": [ + { + "name": "sessionID", + "in": "path", + "schema": { + "type": "string", + "pattern": "^ses.*" + }, + "required": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/QuestionV2Request" + } + } + }, + "required": ["data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + }, + "404": { + "description": "SessionNotFoundError", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/SessionNotFoundError" + }, + { + "$ref": "#/components/schemas/SessionNotFoundError" + } + ] + } + } + } + } + }, + "description": "Retrieve pending question requests owned by a session.", + "summary": "List session question requests", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.session.question.list({\n ...\n})" + } + ] + } + }, + "/api/session/{sessionID}/question/{requestID}/reply": { "post": { - "tags": ["v2 session questions"], + "tags": ["session questions"], "operationId": "v2.session.question.reply", "parameters": [ { @@ -21536,11 +22865,14 @@ "application/json": { "schema": { "anyOf": [ + { + "$ref": "#/components/schemas/QuestionNotFoundError" + }, { "$ref": "#/components/schemas/SessionNotFoundError" }, { - "$ref": "#/components/schemas/QuestionNotFoundError" + "$ref": "#/components/schemas/SessionNotFoundError" } ] } @@ -21568,9 +22900,9 @@ ] } }, - "/api/session/{sessionID}/question/request/{requestID}/reject": { + "/api/session/{sessionID}/question/{requestID}/reject": { "post": { - "tags": ["v2 session questions"], + "tags": ["session questions"], "operationId": "v2.session.question.reject", "parameters": [ { @@ -21623,11 +22955,14 @@ "application/json": { "schema": { "anyOf": [ + { + "$ref": "#/components/schemas/QuestionNotFoundError" + }, { "$ref": "#/components/schemas/SessionNotFoundError" }, { - "$ref": "#/components/schemas/QuestionNotFoundError" + "$ref": "#/components/schemas/SessionNotFoundError" } ] } @@ -21645,6 +22980,87 @@ ] } }, + "/api/reference": { + "get": { + "tags": ["reference"], + "operationId": "v2.reference.list", + "parameters": [ + { + "name": "location", + "in": "query", + "schema": { + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "workspace": { + "type": "string" + } + }, + "additionalProperties": false + }, + "required": false, + "style": "deepObject", + "explode": true + } + ], + "security": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "location": { + "$ref": "#/components/schemas/LocationInfo" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReferenceInfo" + } + } + }, + "required": ["location", "data"], + "additionalProperties": false + } + } + } + }, + "400": { + "description": "InvalidRequestError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidRequestError" + } + } + } + }, + "401": { + "description": "UnauthorizedError", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorizedError" + } + } + } + } + }, + "description": "List references available in the requested location.", + "summary": "List references", + "x-codeSamples": [ + { + "lang": "js", + "source": "import { createKiloClient } from \"@kilocode/sdk\"\n\nconst client = createKiloClient()\nawait client.v2.reference.list({\n ...\n})" + } + ] + } + }, "/pty/{ptyID}/connect": { "get": { "tags": ["pty"], @@ -21823,6 +23239,15 @@ { "$ref": "#/components/schemas/EventGlobalConfigUpdated" }, + { + "$ref": "#/components/schemas/EventCredentialAdded" + }, + { + "$ref": "#/components/schemas/EventCredentialRemoved" + }, + { + "$ref": "#/components/schemas/EventCredentialSwitched" + }, { "$ref": "#/components/schemas/EventPluginAdded" }, @@ -21868,6 +23293,9 @@ { "$ref": "#/components/schemas/EventSessionNextPromptPromoted" }, + { + "$ref": "#/components/schemas/EventSessionNextInterruptRequested" + }, { "$ref": "#/components/schemas/EventSessionNextContextUpdated" }, @@ -21991,6 +23419,45 @@ { "$ref": "#/components/schemas/EventPermissionReplied" }, + { + "$ref": "#/components/schemas/EventConnectorUpdated" + }, + { + "$ref": "#/components/schemas/EventPermissionV2Asked" + }, + { + "$ref": "#/components/schemas/EventPermissionV2Replied" + }, + { + "$ref": "#/components/schemas/EventReferenceUpdated" + }, + { + "$ref": "#/components/schemas/EventFileEdited" + }, + { + "$ref": "#/components/schemas/EventFileWatcherUpdated" + }, + { + "$ref": "#/components/schemas/EventPtyCreated" + }, + { + "$ref": "#/components/schemas/EventPtyUpdated" + }, + { + "$ref": "#/components/schemas/EventPtyExited" + }, + { + "$ref": "#/components/schemas/EventPtyDeleted" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Asked" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Replied" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Rejected" + }, { "$ref": "#/components/schemas/EventTodoUpdated" }, @@ -22015,12 +23482,6 @@ { "$ref": "#/components/schemas/EventLspUpdated" }, - { - "$ref": "#/components/schemas/EventFileEdited" - }, - { - "$ref": "#/components/schemas/EventFileWatcherUpdated" - }, { "$ref": "#/components/schemas/EventVcsBranchUpdated" }, @@ -22039,42 +23500,6 @@ { "$ref": "#/components/schemas/EventWorktreeFailed" }, - { - "$ref": "#/components/schemas/EventAccountAdded" - }, - { - "$ref": "#/components/schemas/EventAccountRemoved" - }, - { - "$ref": "#/components/schemas/EventAccountSwitched" - }, - { - "$ref": "#/components/schemas/EventPermissionV2Asked" - }, - { - "$ref": "#/components/schemas/EventPermissionV2Replied" - }, - { - "$ref": "#/components/schemas/EventPtyCreated" - }, - { - "$ref": "#/components/schemas/EventPtyUpdated" - }, - { - "$ref": "#/components/schemas/EventPtyExited" - }, - { - "$ref": "#/components/schemas/EventPtyDeleted" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Asked" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Replied" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Rejected" - }, { "$ref": "#/components/schemas/EventServerInstanceDisposed" } @@ -23221,6 +24646,27 @@ "required": ["name", "data"], "additionalProperties": false }, + "ContentFilterError": { + "type": "object", + "properties": { + "name": { + "type": "string", + "enum": ["ContentFilterError"] + }, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"], + "additionalProperties": false + } + }, + "required": ["name", "data"], + "additionalProperties": false + }, "APIError": { "type": "object", "properties": { @@ -23314,6 +24760,9 @@ { "$ref": "#/components/schemas/ContextOverflowError" }, + { + "$ref": "#/components/schemas/ContentFilterError" + }, { "$ref": "#/components/schemas/APIError" } @@ -24245,12 +25694,6 @@ "items": { "$ref": "#/components/schemas/PromptAgentAttachment" } - }, - "references": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PromptReferenceAttachment" - } } }, "required": ["text"], @@ -24561,6 +26004,70 @@ "required": ["name", "data"], "additionalProperties": false }, + "Pty": { + "type": "object", + "properties": { + "id": { + "type": "string", + "pattern": "^pty" + }, + "title": { + "type": "string" + }, + "command": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "cwd": { + "type": "string" + }, + "status": { + "type": "string", + "enum": ["running", "exited"] + }, + "pid": { + "type": "integer", + "minimum": 0 + }, + "sessionID": { + "anyOf": [ + { + "type": "string", + "pattern": "^ses" + }, + { + "type": "null" + } + ] + } + }, + "required": ["id", "title", "command", "args", "cwd", "status", "pid"], + "additionalProperties": false + }, + "Todo": { + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "Brief description of the task" + }, + "status": { + "type": "string", + "description": "Current status of the task: pending, in_progress, completed, cancelled" + }, + "priority": { + "type": "string", + "description": "Priority level of the task: high, medium, low" + } + }, + "required": ["content", "status", "priority"], + "additionalProperties": false + }, "SessionStatus": { "anyOf": [ { @@ -24652,51 +26159,6 @@ } ] }, - "Pty": { - "type": "object", - "properties": { - "id": { - "type": "string", - "pattern": "^pty" - }, - "title": { - "type": "string" - }, - "command": { - "type": "string" - }, - "args": { - "type": "array", - "items": { - "type": "string" - } - }, - "cwd": { - "type": "string" - }, - "status": { - "type": "string", - "enum": ["running", "exited"] - }, - "pid": { - "type": "integer", - "minimum": 0 - }, - "sessionID": { - "anyOf": [ - { - "type": "string", - "pattern": "^ses" - }, - { - "type": "null" - } - ] - } - }, - "required": ["id", "title", "command", "args", "cwd", "status", "pid"], - "additionalProperties": false - }, "GlobalEvent": { "type": "object", "properties": { @@ -24798,6 +26260,15 @@ { "$ref": "#/components/schemas/EventGlobalConfigUpdated" }, + { + "$ref": "#/components/schemas/EventCredentialAdded" + }, + { + "$ref": "#/components/schemas/EventCredentialRemoved" + }, + { + "$ref": "#/components/schemas/EventCredentialSwitched" + }, { "$ref": "#/components/schemas/EventPluginAdded" }, @@ -24843,6 +26314,9 @@ { "$ref": "#/components/schemas/EventSessionNextPromptPromoted" }, + { + "$ref": "#/components/schemas/EventSessionNextInterruptRequested" + }, { "$ref": "#/components/schemas/EventSessionNextContextUpdated" }, @@ -24966,6 +26440,45 @@ { "$ref": "#/components/schemas/EventPermissionReplied" }, + { + "$ref": "#/components/schemas/EventConnectorUpdated" + }, + { + "$ref": "#/components/schemas/EventPermissionV2Asked" + }, + { + "$ref": "#/components/schemas/EventPermissionV2Replied" + }, + { + "$ref": "#/components/schemas/EventReferenceUpdated" + }, + { + "$ref": "#/components/schemas/EventFileEdited" + }, + { + "$ref": "#/components/schemas/EventFileWatcherUpdated" + }, + { + "$ref": "#/components/schemas/EventPtyCreated" + }, + { + "$ref": "#/components/schemas/EventPtyUpdated" + }, + { + "$ref": "#/components/schemas/EventPtyExited" + }, + { + "$ref": "#/components/schemas/EventPtyDeleted" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Asked" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Replied" + }, + { + "$ref": "#/components/schemas/EventQuestionV2Rejected" + }, { "$ref": "#/components/schemas/EventTodoUpdated" }, @@ -24990,12 +26503,6 @@ { "$ref": "#/components/schemas/EventLspUpdated" }, - { - "$ref": "#/components/schemas/EventFileEdited" - }, - { - "$ref": "#/components/schemas/EventFileWatcherUpdated" - }, { "$ref": "#/components/schemas/EventVcsBranchUpdated" }, @@ -25014,42 +26521,6 @@ { "$ref": "#/components/schemas/EventWorktreeFailed" }, - { - "$ref": "#/components/schemas/EventAccountAdded" - }, - { - "$ref": "#/components/schemas/EventAccountRemoved" - }, - { - "$ref": "#/components/schemas/EventAccountSwitched" - }, - { - "$ref": "#/components/schemas/EventPermissionV2Asked" - }, - { - "$ref": "#/components/schemas/EventPermissionV2Replied" - }, - { - "$ref": "#/components/schemas/EventPtyCreated" - }, - { - "$ref": "#/components/schemas/EventPtyUpdated" - }, - { - "$ref": "#/components/schemas/EventPtyExited" - }, - { - "$ref": "#/components/schemas/EventPtyDeleted" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Asked" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Replied" - }, - { - "$ref": "#/components/schemas/EventQuestionV2Rejected" - }, { "$ref": "#/components/schemas/EventServerInstanceDisposed" }, @@ -25092,6 +26563,9 @@ { "$ref": "#/components/schemas/SyncEventSessionNextPromptPromoted" }, + { + "$ref": "#/components/schemas/SyncEventSessionNextInterruptRequested" + }, { "$ref": "#/components/schemas/SyncEventSessionNextContextUpdated" }, @@ -25149,9 +26623,6 @@ { "$ref": "#/components/schemas/SyncEventSessionNextCompactionStarted" }, - { - "$ref": "#/components/schemas/SyncEventSessionNextCompactionDelta" - }, { "$ref": "#/components/schemas/SyncEventSessionNextCompactionEnded" } @@ -25192,44 +26663,6 @@ "additionalProperties": false, "description": "Server configuration for the kilo serve command" }, - "ReferenceConfigEntry": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "repository": { - "type": "string", - "description": "Git repository URL, host/path reference, or GitHub owner/repo shorthand" - }, - "branch": { - "type": "string" - } - }, - "required": ["repository"], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "path": { - "type": "string", - "description": "Absolute path, ~/ path, or workspace-relative path to a local reference directory" - } - }, - "required": ["path"], - "additionalProperties": false - } - ] - }, - "ReferenceConfig": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/ReferenceConfigEntry" - } - }, "IndexingConfig": { "type": "object", "properties": { @@ -25780,7 +27213,7 @@ "properties": { "field": { "type": "string", - "enum": ["reasoning_content", "reasoning_details"] + "enum": ["reasoning", "reasoning_content", "reasoning_details"] } }, "required": ["field"], @@ -26106,8 +27539,37 @@ }, "additionalProperties": false }, + "references": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/ConfigV2ReferenceGit" + }, + { + "$ref": "#/components/schemas/ConfigV2ReferenceLocal" + } + ] + } + }, "reference": { - "$ref": "#/components/schemas/ReferenceConfig" + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/ConfigV2ReferenceGit" + }, + { + "$ref": "#/components/schemas/ConfigV2ReferenceLocal" + } + ] + } }, "watcher": { "type": "object", @@ -26728,7 +28190,7 @@ "properties": { "field": { "type": "string", - "enum": ["reasoning_content", "reasoning_details"] + "enum": ["reasoning", "reasoning_content", "reasoning_details"] } }, "required": ["field"], @@ -28070,6 +29532,9 @@ "properties": { "message": { "type": "string" + }, + "forceRequired": { + "type": "boolean" } }, "required": ["message"], @@ -28738,25 +30203,6 @@ } } }, - "Todo": { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Brief description of the task" - }, - "status": { - "type": "string", - "description": "Current status of the task: pending, in_progress, completed, cancelled" - }, - "priority": { - "type": "string", - "description": "Priority level of the task: high, medium, low" - } - }, - "required": ["content", "status", "priority"], - "additionalProperties": false - }, "Session3": { "type": "object", "properties": { @@ -31641,7 +33087,7 @@ "required": ["_tag", "message"], "additionalProperties": false }, - "V2SessionsResponse": { + "SessionsResponse": { "type": "object", "properties": { "data": { @@ -31731,7 +33177,7 @@ "required": ["_tag", "message"], "additionalProperties": false }, - "V2SessionMessagesResponse": { + "SessionMessagesResponse": { "type": "object", "properties": { "data": { @@ -33509,6 +34955,163 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, + "CredentialOAuth": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["oauth"] + }, + "refresh": { + "type": "string" + }, + "access": { + "type": "string" + }, + "expires": { + "type": "integer", + "minimum": 0 + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": ["type", "refresh", "access", "expires"], + "additionalProperties": false + }, + "CredentialKey": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["key"] + }, + "key": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": ["type", "key"], + "additionalProperties": false + }, + "CredentialValue": { + "anyOf": [ + { + "$ref": "#/components/schemas/CredentialOAuth" + }, + { + "$ref": "#/components/schemas/CredentialKey" + } + ] + }, + "CredentialInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "connectorID": { + "type": "string" + }, + "methodID": { + "type": "string" + }, + "label": { + "type": "string" + }, + "value": { + "$ref": "#/components/schemas/CredentialValue" + } + }, + "required": ["id", "connectorID", "methodID", "label", "value"], + "additionalProperties": false + }, + "EventCredentialAdded": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["credential.added"] + }, + "properties": { + "type": "object", + "properties": { + "credential": { + "$ref": "#/components/schemas/CredentialInfo" + } + }, + "required": ["credential"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventCredentialRemoved": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["credential.removed"] + }, + "properties": { + "type": "object", + "properties": { + "credential": { + "$ref": "#/components/schemas/CredentialInfo" + } + }, + "required": ["credential"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventCredentialSwitched": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["credential.switched"] + }, + "properties": { + "type": "object", + "properties": { + "connectorID": { + "type": "string" + }, + "from": { + "type": "string" + }, + "to": { + "type": "string" + } + }, + "required": ["connectorID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, "EventPluginAdded": { "type": "object", "properties": { @@ -33629,6 +35232,182 @@ "body": { "type": "object" }, + "generation": { + "type": "object", + "properties": { + "maxTokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "topP": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "topK": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "frequencyPenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "presencePenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "seed": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "stop": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "options": { + "type": "object" + }, "variant": { "type": "string" } @@ -33652,6 +35431,182 @@ }, "body": { "type": "object" + }, + "generation": { + "type": "object", + "properties": { + "maxTokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "topP": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "topK": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "frequencyPenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "presencePenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "seed": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "stop": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "options": { + "type": "object" } }, "required": ["id", "headers", "body"], @@ -34182,41 +36137,6 @@ "required": ["name"], "additionalProperties": false }, - "PromptReferenceAttachment": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "kind": { - "type": "string", - "enum": ["local", "git", "invalid"] - }, - "uri": { - "type": "string" - }, - "repository": { - "type": "string" - }, - "branch": { - "type": "string" - }, - "target": { - "type": "string" - }, - "targetUri": { - "type": "string" - }, - "problem": { - "type": "string" - }, - "source": { - "$ref": "#/components/schemas/PromptSource" - } - }, - "required": ["name", "kind"], - "additionalProperties": false - }, "EventSessionNextPrompted": { "type": "object", "properties": { @@ -34333,6 +36253,34 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, + "EventSessionNextInterruptRequested": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["session.next.interrupt.requested"] + }, + "properties": { + "type": "object", + "properties": { + "timestamp": { + "type": "number" + }, + "sessionID": { + "type": "string", + "pattern": "^ses" + } + }, + "required": ["timestamp", "sessionID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, "EventSessionNextContextUpdated": { "type": "object", "properties": { @@ -35074,51 +37022,8 @@ "type": "string", "enum": ["file"] }, - "source": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["data"] - }, - "data": { - "type": "string" - } - }, - "required": ["type", "data"], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["url"] - }, - "url": { - "type": "string" - } - }, - "required": ["type", "url"], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["file"] - }, - "uri": { - "type": "string" - } - }, - "required": ["type", "uri"], - "additionalProperties": false - } - ] + "uri": { + "type": "string" }, "mime": { "type": "string" @@ -35127,7 +37032,7 @@ "type": "string" } }, - "required": ["type", "source", "mime"], + "required": ["type", "uri", "mime"], "additionalProperties": false }, "EventSessionNextToolProgress": { @@ -35224,6 +37129,12 @@ ] } }, + "outputPaths": { + "type": "array", + "items": { + "type": "string" + } + }, "result": {}, "provider": { "type": "object", @@ -35425,11 +37336,15 @@ "type": "string", "pattern": "^ses" }, + "messageID": { + "type": "string", + "pattern": "^msg_" + }, "text": { "type": "string" } }, - "required": ["timestamp", "sessionID", "text"], + "required": ["timestamp", "sessionID", "messageID", "text"], "additionalProperties": false } }, @@ -35456,14 +37371,22 @@ "type": "string", "pattern": "^ses" }, + "messageID": { + "type": "string", + "pattern": "^msg_" + }, + "reason": { + "type": "string", + "enum": ["auto", "manual"] + }, "text": { "type": "string" }, - "include": { + "recent": { "type": "string" } }, - "required": ["timestamp", "sessionID", "text"], + "required": ["timestamp", "sessionID", "messageID", "reason", "text", "recent"], "additionalProperties": false } }, @@ -35734,6 +37657,9 @@ { "$ref": "#/components/schemas/ContextOverflowError" }, + { + "$ref": "#/components/schemas/ContentFilterError" + }, { "$ref": "#/components/schemas/APIError" }, @@ -35908,26 +37834,7 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, - "SessionTodoInfo": { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Brief description of the task" - }, - "status": { - "type": "string", - "description": "Current status of the task: pending, in_progress, completed, cancelled" - }, - "priority": { - "type": "string", - "description": "Priority level of the task: high, medium, low" - } - }, - "required": ["content", "status", "priority"], - "additionalProperties": false - }, - "EventTodoUpdated": { + "EventConnectorUpdated": { "type": "object", "properties": { "id": { @@ -35935,259 +37842,7 @@ }, "type": { "type": "string", - "enum": ["todo.updated"] - }, - "properties": { - "type": "object", - "properties": { - "sessionID": { - "type": "string", - "pattern": "^ses" - }, - "todos": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SessionTodoInfo" - } - } - }, - "required": ["sessionID", "todos"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventSessionStatus": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["session.status"] - }, - "properties": { - "type": "object", - "properties": { - "sessionID": { - "type": "string", - "pattern": "^ses" - }, - "status": { - "$ref": "#/components/schemas/SessionStatus" - } - }, - "required": ["sessionID", "status"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventSessionIdle": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["session.idle"] - }, - "properties": { - "type": "object", - "properties": { - "sessionID": { - "type": "string", - "pattern": "^ses" - } - }, - "required": ["sessionID"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventSessionCompacted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["session.compacted"] - }, - "properties": { - "type": "object", - "properties": { - "sessionID": { - "type": "string", - "pattern": "^ses" - } - }, - "required": ["sessionID"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventCommandExecuted": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["command.executed"] - }, - "properties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "sessionID": { - "type": "string", - "pattern": "^ses" - }, - "arguments": { - "type": "string" - }, - "messageID": { - "type": "string", - "pattern": "^msg" - } - }, - "required": ["name", "sessionID", "arguments", "messageID"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventProjectDirectoriesUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["project.directories.updated"] - }, - "properties": { - "type": "object", - "properties": { - "projectID": { - "type": "string" - } - }, - "required": ["projectID"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventProjectUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["project.updated"] - }, - "properties": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "worktree": { - "type": "string" - }, - "vcs": { - "type": "string", - "enum": ["git"] - }, - "name": { - "type": "string" - }, - "icon": { - "type": "object", - "properties": { - "url": { - "type": "string" - }, - "override": { - "type": "string" - }, - "color": { - "type": "string" - } - }, - "additionalProperties": false - }, - "commands": { - "type": "object", - "properties": { - "start": { - "type": "string", - "description": "Startup script to run when creating a new workspace (worktree)" - } - }, - "additionalProperties": false - }, - "time": { - "type": "object", - "properties": { - "created": { - "type": "integer", - "minimum": 0 - }, - "updated": { - "type": "integer", - "minimum": 0 - }, - "initialized": { - "type": "integer", - "minimum": 0 - } - }, - "required": ["created", "updated"], - "additionalProperties": false - }, - "sandboxes": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": ["id", "worktree", "time", "sandboxes"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventLspUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["lsp.updated"] + "enum": ["connector.updated"] }, "properties": { "type": "object", @@ -36197,360 +37852,6 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, - "EventFileEdited": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["file.edited"] - }, - "properties": { - "type": "object", - "properties": { - "file": { - "type": "string" - } - }, - "required": ["file"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventFileWatcherUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["file.watcher.updated"] - }, - "properties": { - "type": "object", - "properties": { - "file": { - "type": "string" - }, - "event": { - "type": "string", - "enum": ["add", "change", "unlink"] - } - }, - "required": ["file", "event"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventVcsBranchUpdated": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["vcs.branch.updated"] - }, - "properties": { - "type": "object", - "properties": { - "branch": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventWorkspaceReady": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["workspace.ready"] - }, - "properties": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - }, - "required": ["name"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventWorkspaceFailed": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["workspace.failed"] - }, - "properties": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventWorkspaceStatus": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["workspace.status"] - }, - "properties": { - "type": "object", - "properties": { - "workspaceID": { - "type": "string", - "pattern": "^wrk" - }, - "status": { - "type": "string", - "enum": ["connected", "connecting", "disconnected", "error"] - } - }, - "required": ["workspaceID", "status"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventWorktreeReady": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["worktree.ready"] - }, - "properties": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "branch": { - "type": "string" - } - }, - "required": ["name"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventWorktreeFailed": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["worktree.failed"] - }, - "properties": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "AuthOAuthCredential": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["oauth"] - }, - "refresh": { - "type": "string" - }, - "access": { - "type": "string" - }, - "expires": { - "type": "integer", - "minimum": 0 - }, - "accountId": { - "type": "string" - } - }, - "required": ["type", "refresh", "access", "expires"], - "additionalProperties": false - }, - "AuthApiKeyCredential": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["api"] - }, - "key": { - "type": "string" - }, - "metadata": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - }, - "required": ["type", "key"], - "additionalProperties": false - }, - "AuthCredential": { - "anyOf": [ - { - "$ref": "#/components/schemas/AuthOAuthCredential" - }, - { - "$ref": "#/components/schemas/AuthApiKeyCredential" - } - ] - }, - "AuthInfo": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "serviceID": { - "type": "string" - }, - "description": { - "type": "string" - }, - "credential": { - "$ref": "#/components/schemas/AuthCredential" - } - }, - "required": ["id", "serviceID", "description", "credential"], - "additionalProperties": false - }, - "EventAccountAdded": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["account.added"] - }, - "properties": { - "type": "object", - "properties": { - "account": { - "$ref": "#/components/schemas/AuthInfo" - } - }, - "required": ["account"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventAccountRemoved": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["account.removed"] - }, - "properties": { - "type": "object", - "properties": { - "account": { - "$ref": "#/components/schemas/AuthInfo" - } - }, - "required": ["account"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, - "EventAccountSwitched": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string", - "enum": ["account.switched"] - }, - "properties": { - "type": "object", - "properties": { - "serviceID": { - "type": "string" - }, - "from": { - "type": "string" - }, - "to": { - "type": "string" - } - }, - "required": ["serviceID"], - "additionalProperties": false - } - }, - "required": ["id", "type", "properties"], - "additionalProperties": false - }, "PermissionV2Source": { "type": "object", "properties": { @@ -36654,6 +37955,76 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, + "EventReferenceUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["reference.updated"] + }, + "properties": { + "type": "object", + "properties": {} + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventFileEdited": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["file.edited"] + }, + "properties": { + "type": "object", + "properties": { + "file": { + "type": "string" + } + }, + "required": ["file"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventFileWatcherUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["file.watcher.updated"] + }, + "properties": { + "type": "object", + "properties": { + "file": { + "type": "string" + }, + "event": { + "type": "string", + "enum": ["add", "change", "unlink"] + } + }, + "required": ["file", "event"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, "EventPtyCreated": { "type": "object", "properties": { @@ -36921,6 +38292,427 @@ "required": ["id", "type", "properties"], "additionalProperties": false }, + "EventTodoUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["todo.updated"] + }, + "properties": { + "type": "object", + "properties": { + "sessionID": { + "type": "string", + "pattern": "^ses" + }, + "todos": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Todo" + } + } + }, + "required": ["sessionID", "todos"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventSessionStatus": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["session.status"] + }, + "properties": { + "type": "object", + "properties": { + "sessionID": { + "type": "string", + "pattern": "^ses" + }, + "status": { + "$ref": "#/components/schemas/SessionStatus" + } + }, + "required": ["sessionID", "status"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventSessionIdle": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["session.idle"] + }, + "properties": { + "type": "object", + "properties": { + "sessionID": { + "type": "string", + "pattern": "^ses" + } + }, + "required": ["sessionID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventSessionCompacted": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["session.compacted"] + }, + "properties": { + "type": "object", + "properties": { + "sessionID": { + "type": "string", + "pattern": "^ses" + } + }, + "required": ["sessionID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventCommandExecuted": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["command.executed"] + }, + "properties": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "sessionID": { + "type": "string", + "pattern": "^ses" + }, + "arguments": { + "type": "string" + }, + "messageID": { + "type": "string", + "pattern": "^msg" + } + }, + "required": ["name", "sessionID", "arguments", "messageID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventProjectDirectoriesUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["project.directories.updated"] + }, + "properties": { + "type": "object", + "properties": { + "projectID": { + "type": "string" + } + }, + "required": ["projectID"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventProjectUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["project.updated"] + }, + "properties": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "worktree": { + "type": "string" + }, + "vcs": { + "type": "string", + "enum": ["git"] + }, + "name": { + "type": "string" + }, + "icon": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "override": { + "type": "string" + }, + "color": { + "type": "string" + } + }, + "additionalProperties": false + }, + "commands": { + "type": "object", + "properties": { + "start": { + "type": "string", + "description": "Startup script to run when creating a new workspace (worktree)" + } + }, + "additionalProperties": false + }, + "time": { + "type": "object", + "properties": { + "created": { + "type": "integer", + "minimum": 0 + }, + "updated": { + "type": "integer", + "minimum": 0 + }, + "initialized": { + "type": "integer", + "minimum": 0 + } + }, + "required": ["created", "updated"], + "additionalProperties": false + }, + "sandboxes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["id", "worktree", "time", "sandboxes"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventLspUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["lsp.updated"] + }, + "properties": { + "type": "object", + "properties": {} + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventVcsBranchUpdated": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["vcs.branch.updated"] + }, + "properties": { + "type": "object", + "properties": { + "branch": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventWorkspaceReady": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["workspace.ready"] + }, + "properties": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": ["name"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventWorkspaceFailed": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["workspace.failed"] + }, + "properties": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventWorkspaceStatus": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["workspace.status"] + }, + "properties": { + "type": "object", + "properties": { + "workspaceID": { + "type": "string", + "pattern": "^wrk" + }, + "status": { + "type": "string", + "enum": ["connected", "connecting", "disconnected", "error"] + } + }, + "required": ["workspaceID", "status"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventWorktreeReady": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["worktree.ready"] + }, + "properties": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "branch": { + "type": "string" + } + }, + "required": ["name"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, + "EventWorktreeFailed": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["worktree.failed"] + }, + "properties": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"], + "additionalProperties": false + } + }, + "required": ["id", "type", "properties"], + "additionalProperties": false + }, "SyncEventSessionCreated": { "type": "object", "properties": { @@ -37645,6 +39437,56 @@ "required": ["type", "id", "syncEvent"], "additionalProperties": false }, + "SyncEventSessionNextInterruptRequested": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["sync"] + }, + "id": { + "type": "string", + "pattern": "^evt_" + }, + "syncEvent": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["session.next.interrupt.requested.1"] + }, + "id": { + "type": "string", + "pattern": "^evt_" + }, + "seq": { + "type": "number" + }, + "aggregateID": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "timestamp": { + "type": "number" + }, + "sessionID": { + "type": "string", + "pattern": "^ses" + } + }, + "required": ["timestamp", "sessionID"], + "additionalProperties": false + } + }, + "required": ["type", "id", "seq", "aggregateID", "data"], + "additionalProperties": false + } + }, + "required": ["type", "id", "syncEvent"], + "additionalProperties": false + }, "SyncEventSessionNextContextUpdated": { "type": "object", "properties": { @@ -38679,6 +40521,12 @@ ] } }, + "outputPaths": { + "type": "array", + "items": { + "type": "string" + } + }, "result": {}, "provider": { "type": "object", @@ -38907,59 +40755,6 @@ "required": ["type", "id", "syncEvent"], "additionalProperties": false }, - "SyncEventSessionNextCompactionDelta": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["sync"] - }, - "id": { - "type": "string", - "pattern": "^evt_" - }, - "syncEvent": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["session.next.compaction.delta.1"] - }, - "id": { - "type": "string", - "pattern": "^evt_" - }, - "seq": { - "type": "number" - }, - "aggregateID": { - "type": "string" - }, - "data": { - "type": "object", - "properties": { - "timestamp": { - "type": "number" - }, - "sessionID": { - "type": "string", - "pattern": "^ses" - }, - "text": { - "type": "string" - } - }, - "required": ["timestamp", "sessionID", "text"], - "additionalProperties": false - } - }, - "required": ["type", "id", "seq", "aggregateID", "data"], - "additionalProperties": false - } - }, - "required": ["type", "id", "syncEvent"], - "additionalProperties": false - }, "SyncEventSessionNextCompactionEnded": { "type": "object", "properties": { @@ -38976,7 +40771,7 @@ "properties": { "type": { "type": "string", - "enum": ["session.next.compaction.ended.1"] + "enum": ["session.next.compaction.ended.2"] }, "id": { "type": "string", @@ -38998,14 +40793,22 @@ "type": "string", "pattern": "^ses" }, + "messageID": { + "type": "string", + "pattern": "^msg_" + }, + "reason": { + "type": "string", + "enum": ["auto", "manual"] + }, "text": { "type": "string" }, - "include": { + "recent": { "type": "string" } }, - "required": ["timestamp", "sessionID", "text"], + "required": ["timestamp", "sessionID", "messageID", "reason", "text", "recent"], "additionalProperties": false } }, @@ -39016,6 +40819,41 @@ "required": ["type", "id", "syncEvent"], "additionalProperties": false }, + "ConfigV2ReferenceGit": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "branch": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "boolean" + } + }, + "required": ["repository"], + "additionalProperties": false + }, + "ConfigV2ReferenceLocal": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "boolean" + } + }, + "required": ["path"], + "additionalProperties": false + }, "PolicyEffect": { "type": "string", "enum": ["allow", "deny"] @@ -39040,7 +40878,18 @@ "ProjectDirectories": { "type": "array", "items": { - "type": "string" + "type": "object", + "properties": { + "directory": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["main", "root", "git_worktree"] + } + }, + "required": ["directory", "type"], + "additionalProperties": false } }, "ProjectCopyCopy": { @@ -39417,12 +41266,6 @@ "$ref": "#/components/schemas/PromptAgentAttachment" } }, - "references": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PromptReferenceAttachment" - } - }, "type": { "type": "string", "enum": ["user"] @@ -39650,6 +41493,12 @@ ] } }, + "outputPaths": { + "type": "array", + "items": { + "type": "string" + } + }, "structured": { "type": "object" }, @@ -39896,7 +41745,7 @@ "summary": { "type": "string" }, - "include": { + "recent": { "type": "string" }, "id": { @@ -39917,7 +41766,7 @@ "additionalProperties": false } }, - "required": ["type", "reason", "summary", "id", "time"], + "required": ["type", "reason", "summary", "recent", "id", "time"], "additionalProperties": false }, "SessionMessage": { @@ -39982,13 +41831,13 @@ "properties": { "via": { "type": "string", - "enum": ["account"] + "enum": ["credential"] }, - "service": { + "credentialID": { "type": "string" } }, - "required": ["via", "service"], + "required": ["via", "credentialID"], "additionalProperties": false }, { @@ -40074,6 +41923,244 @@ "required": ["id", "name", "enabled", "env", "api", "request"], "additionalProperties": false }, + "ConnectorWhen": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "op": { + "type": "string", + "enum": ["eq", "neq"] + }, + "value": { + "type": "string" + } + }, + "required": ["key", "op", "value"], + "additionalProperties": false + }, + "ConnectorTextPrompt": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["text"] + }, + "key": { + "type": "string" + }, + "message": { + "type": "string" + }, + "placeholder": { + "type": "string" + }, + "when": { + "$ref": "#/components/schemas/ConnectorWhen" + } + }, + "required": ["type", "key", "message"], + "additionalProperties": false + }, + "ConnectorSelectPrompt": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["select"] + }, + "key": { + "type": "string" + }, + "message": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "hint": { + "type": "string" + } + }, + "required": ["label", "value"], + "additionalProperties": false + } + }, + "when": { + "$ref": "#/components/schemas/ConnectorWhen" + } + }, + "required": ["type", "key", "message", "options"], + "additionalProperties": false + }, + "ConnectorOAuthMethod": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["oauth"] + }, + "label": { + "type": "string" + }, + "prompts": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ConnectorTextPrompt" + }, + { + "$ref": "#/components/schemas/ConnectorSelectPrompt" + } + ] + } + } + }, + "required": ["id", "type", "label"], + "additionalProperties": false + }, + "ConnectorKeyMethod": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["key"] + }, + "label": { + "type": "string" + }, + "prompts": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ConnectorTextPrompt" + }, + { + "$ref": "#/components/schemas/ConnectorSelectPrompt" + } + ] + } + } + }, + "required": ["id", "type", "label"], + "additionalProperties": false + }, + "ConnectorInfo": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "methods": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ConnectorOAuthMethod" + }, + { + "$ref": "#/components/schemas/ConnectorKeyMethod" + } + ] + } + } + }, + "required": ["id", "name", "methods"], + "additionalProperties": false + }, + "ConnectorAttempt": { + "type": "object", + "properties": { + "attemptID": { + "type": "string" + }, + "url": { + "type": "string" + }, + "instructions": { + "type": "string" + }, + "mode": { + "type": "string", + "enum": ["auto", "code"] + }, + "time": { + "type": "object", + "properties": { + "created": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + }, + "expires": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + }, + { + "type": "string", + "enum": ["Infinity", "-Infinity", "NaN"] + } + ] + } + }, + "required": ["created", "expires"], + "additionalProperties": false + } + }, + "required": ["attemptID", "url", "instructions", "mode", "time"], + "additionalProperties": false + }, "PermissionV2Request": { "type": "object", "properties": { @@ -40129,53 +42216,12 @@ "required": ["id", "projectID", "action", "resource"], "additionalProperties": false }, - "FileSystemTextContent": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["text"] - }, - "content": { - "type": "string" - }, - "mime": { - "type": "string" - } - }, - "required": ["type", "content", "mime"], - "additionalProperties": false - }, - "FileSystemBinaryContent": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": ["binary"] - }, - "content": { - "type": "string" - }, - "encoding": { - "type": "string", - "enum": ["base64"] - }, - "mime": { - "type": "string" - } - }, - "required": ["type", "content", "encoding", "mime"], - "additionalProperties": false - }, "FileSystemEntry": { "type": "object", "properties": { "path": { "type": "string" }, - "uri": { - "type": "string" - }, "type": { "type": "string", "enum": ["file", "directory"] @@ -40184,7 +42230,7 @@ "type": "string" } }, - "required": ["path", "uri", "type", "mime"], + "required": ["path", "type", "mime"], "additionalProperties": false }, "CommandV2Info": { @@ -40286,6 +42332,78 @@ "required": ["answers"], "additionalProperties": false }, + "ReferenceLocalSource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["local"] + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "boolean" + } + }, + "required": ["type", "path"], + "additionalProperties": false + }, + "ReferenceGitSource": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["git"] + }, + "repository": { + "type": "string" + }, + "branch": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "boolean" + } + }, + "required": ["type", "repository"], + "additionalProperties": false + }, + "ReferenceInfo": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "$ref": "#/components/schemas/ReferenceLocalSource" + }, + { + "$ref": "#/components/schemas/ReferenceGitSource" + } + ] + } + }, + "required": ["name", "path", "source"], + "additionalProperties": false + }, "EventMemoryStatus1": { "type": "object", "properties": { @@ -41165,6 +43283,154 @@ "body": { "type": "object" }, + "generation": { + "type": "object", + "properties": { + "maxTokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "topP": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "topK": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "frequencyPenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "presencePenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "seed": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "stop": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "options": { + "type": "object" + }, "variant": { "type": "string" } @@ -41188,6 +43454,154 @@ }, "body": { "type": "object" + }, + "generation": { + "type": "object", + "properties": { + "maxTokens": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "temperature": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "topP": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "topK": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "frequencyPenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "presencePenalty": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "seed": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string", + "enum": ["NaN"] + }, + { + "type": "string", + "enum": ["Infinity"] + }, + { + "type": "string", + "enum": ["-Infinity"] + } + ] + }, + "stop": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "options": { + "type": "object" } }, "required": ["id", "headers", "body"], @@ -41518,64 +43932,64 @@ "description": "Kilo memory routes." }, { - "name": "kilo experimental HttpApi", + "name": "Kilo HttpApi", "description": "Experimental HttpApi surface for selected instance routes." }, { - "name": "kilo experimental HttpApi", + "name": "Kilo HttpApi", "description": "Experimental HttpApi surface for selected instance routes." }, { - "name": "v2", - "description": "Experimental v2 routes." + "name": "Kilo HttpApi", + "description": "Experimental HttpApi surface for selected instance routes." }, { - "name": "v2 messages", - "description": "Experimental v2 message routes." + "name": "sessions", + "description": "Experimental session routes." }, { - "name": "v2 models", - "description": "Experimental v2 model routes." + "name": "messages", + "description": "Experimental message routes." }, { - "name": "v2 providers", - "description": "Experimental v2 provider routes." + "name": "models", + "description": "Experimental model routes." }, { - "name": "v2 permissions", - "description": "Experimental v2 permission routes." + "name": "providers", + "description": "Experimental provider routes." }, { - "name": "v2 session permissions", - "description": "Experimental v2 session permission routes." + "name": "connectors", + "description": "Connector discovery and authentication routes." }, { - "name": "v2 saved permissions", - "description": "Experimental v2 saved permission routes." + "name": "permissions", + "description": "Experimental permission routes." }, { - "name": "v2 filesystem", - "description": "Experimental v2 location-scoped filesystem routes." + "name": "filesystem", + "description": "Experimental location-scoped filesystem routes." }, { - "name": "v2 commands", - "description": "Experimental v2 command routes." + "name": "commands", + "description": "Experimental command routes." }, { - "name": "v2 skills", - "description": "Experimental v2 skill routes." + "name": "skills", + "description": "Experimental skill routes." }, { - "name": "v2 events", - "description": "Experimental v2 event stream route." + "name": "events", + "description": "Experimental event stream route." }, { - "name": "v2 questions", - "description": "Experimental v2 question routes." + "name": "session questions", + "description": "Experimental session question routes." }, { - "name": "v2 session questions", - "description": "Experimental v2 session question routes." + "name": "reference", + "description": "Location-scoped project references." }, { "name": "pty", diff --git a/packages/tui/src/app.tsx b/packages/tui/src/app.tsx index 8cdd5b1066..1a4b5e4bb8 100644 --- a/packages/tui/src/app.tsx +++ b/packages/tui/src/app.tsx @@ -63,7 +63,7 @@ import * as Model from "./util/model" import { ArgsProvider, useArgs, type Args } from "./context/args" import open from "open" import { PromptRefProvider, usePromptRef } from "./context/prompt" -import { TuiConfigProvider, useTuiConfig, type TuiConfig } from "./config" +import type { TuiConfig } from "./config" import { createTuiApiAdapters } from "./plugin/adapters" import { createTuiApi } from "./plugin/api" import { createPluginRuntime, PluginRuntimeProvider, usePluginRuntime, type TuiPluginHost } from "./plugin/runtime" @@ -290,7 +290,8 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { : undefined } > - + {/* kilocode_change - retain reactive Kilo TUI config hot reload after package extraction */} + - + @@ -362,7 +363,7 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { function App(props: { onSnapshot?: () => Promise; pluginHost: TuiPluginHost }) { const startup = useTuiStartup() - const tuiConfig = useTuiConfig() + const tuiConfig = KiloApp.KiloTuiConfig.use() // kilocode_change const route = useRoute() const dimensions = useTerminalDimensions() const renderer = useRenderer() diff --git a/packages/tui/src/component/kilo-logo.tsx b/packages/tui/src/component/kilo-logo.tsx index 32e4e59481..486a514856 100644 --- a/packages/tui/src/component/kilo-logo.tsx +++ b/packages/tui/src/component/kilo-logo.tsx @@ -2,7 +2,7 @@ import { RGBA } from "@opentui/core" import { For, type JSX } from "solid-js" import { useTheme, tint } from "@tui/context/theme" -import { tui } from "../../../../kilocode/cli/logo" +import { tui } from "@/kilocode/cli/logo" // Shadow markers (rendered chars in parens): // _ = full shadow cell (space with bg=shadow) diff --git a/packages/tui/src/config/index.tsx b/packages/tui/src/config/index.tsx index df9239763a..7f364da331 100644 --- a/packages/tui/src/config/index.tsx +++ b/packages/tui/src/config/index.tsx @@ -4,6 +4,7 @@ import { createBindingLookup } from "@opentui/keymap/extras" import { Schema } from "effect" import { createContext, type JSX, useContext } from "solid-js" import { TuiKeybind } from "./keybind" +import { KiloTitleIcon } from "@/kilocode/cli/cmd/tui/title-icon" // kilocode_change export const AttentionSoundName = Schema.Literals([ "default", @@ -58,11 +59,13 @@ export const Info = Schema.Struct({ plugin_enabled: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)), leader_timeout: Schema.optional(LeaderTimeout), attention: Schema.optional(Attention), + title_icon: Schema.optional(KiloTitleIcon.Value), // kilocode_change prompt: Schema.optional(Prompt), scroll_speed: Schema.optional(ScrollSpeed).annotate({ description: "TUI scroll speed" }), scroll_acceleration: Schema.optional(ScrollAcceleration), diff_style: Schema.optional(DiffStyle), mouse: Schema.optional(Schema.Boolean).annotate({ description: "Enable or disable mouse capture (default: true)" }), + vim: Schema.optional(Schema.Boolean), // kilocode_change - retain Kilo prompt editing mode }) export type Info = Schema.Schema.Type diff --git a/packages/tui/src/context/event.ts b/packages/tui/src/context/event.ts index 4f7aad027f..b0ec4059ab 100644 --- a/packages/tui/src/context/event.ts +++ b/packages/tui/src/context/event.ts @@ -80,7 +80,7 @@ export function useEvent() { const payload = normalizeSyncEvent(event.payload) if (!payload) return if (event.directory === "global" || event.project === project.project()) { - handler(payload, { workspace: event.workspace }) + handler(payload, { directory: event.directory, workspace: event.workspace }) } }) } diff --git a/packages/tui/src/context/sync.tsx b/packages/tui/src/context/sync.tsx index 2d7478680a..5ae918af53 100644 --- a/packages/tui/src/context/sync.tsx +++ b/packages/tui/src/context/sync.tsx @@ -23,6 +23,7 @@ import type { ConsoleState, BackgroundProcessInfo, // kilocode_change InteractiveTerminalSnapshot, // kilocode_change + IndexingStatus, // kilocode_change } from "@kilocode/sdk/v2" import { createStore, produce, reconcile } from "solid-js/store" import { useProject } from "./project" @@ -38,7 +39,6 @@ import { useKV } from "./kv" import { handleSuggestionEvent } from "@/kilocode/suggestion/tui/sync" // kilocode_change import { appendTerminalOutput } from "@/kilocode/interactive-terminal/output" // kilocode_change import { useToast } from "../ui/toast" // kilocode_change -import type { IndexingStatus } from "@kilocode/kilo-indexing/status" // kilocode_change const emptyConsoleState: ConsoleState = { consoleManagedProviders: [], @@ -123,6 +123,7 @@ export const { all: [], default: {}, connected: [], + failed: [], }, console_state: emptyConsoleState, provider_auth: {}, @@ -159,11 +160,6 @@ export const { const toast = useToast() // kilocode_change // kilocode_change start - function processScope(scope: string) { - const current = project.instance.path() - return scope === current.directory || scope === current.worktree || scope === project.data.project.worktree - } - function evict(sessionID: string) { const children = store.session.filter((session) => session.parentID === sessionID).map((session) => session.id) setStore( @@ -402,7 +398,6 @@ export const { // kilocode_change start case "background_process.updated": { - if (!processScope(event.properties.scope)) break const info = event.properties.info deleted.delete(info.id) setStore( @@ -423,7 +418,6 @@ export const { break } case "background_process.deleted": { - if (!processScope(event.properties.scope)) break deleted.add(event.properties.processID) setStore( "background_process", @@ -439,7 +433,6 @@ export const { break } case "interactive_terminal.updated": { - if (!processScope(event.properties.scope)) break const info = event.properties.info terminalDeleted.delete(info.id) const list = store.interactive_terminal[info.sessionID] ?? [] @@ -626,6 +619,126 @@ export const { } }) + // kilocode_change start - retain versioned Sync events used by Kilo clients + event.sync((event) => { + switch (event.name) { + case "session.created.1": { + const info = event.data.info + const match = search(store.session, info.id, (item) => item.id) + if (match.found) setStore("session", match.index, reconcile(info)) + if (!match.found) + setStore( + "session", + produce((draft) => draft.splice(match.index, 0, info)), + ) + break + } + case "session.updated.1": { + const id = event.data.sessionID + const match = search(store.session, id, (item) => item.id) + if (!match.found) break + setStore( + "session", + match.index, + produce((draft) => void Object.assign(draft, event.data.info)), + ) + break + } + case "session.deleted.1": { + const id = event.data.sessionID + const match = search(store.session, id, (item) => item.id) + if (match.found) + setStore( + "session", + produce((draft) => draft.splice(match.index, 1)), + ) + evict(id) + break + } + case "message.updated.1": { + touchMessage(event.data.info.sessionID, event.data.info.id) + const info = strip(event.data.info) + const messages = store.message[info.sessionID] + if (!messages) { + setStore("message", info.sessionID, [info]) + break + } + const match = search(messages, info.id, (item) => item.id) + if (match.found) { + setStore("message", info.sessionID, match.index, reconcile(info)) + break + } + setStore( + "message", + info.sessionID, + produce((draft) => draft.splice(match.index, 0, info)), + ) + const updated = store.message[info.sessionID] + if (updated.length <= 100) break + const oldest = updated[0] + batch(() => { + setStore( + "message", + info.sessionID, + produce((draft) => draft.shift()), + ) + setStore( + "part", + produce((draft) => void delete draft[oldest.id]), + ) + }) + break + } + case "message.removed.1": { + touchMessage(event.data.sessionID, event.data.messageID) + const messages = store.message[event.data.sessionID] + if (!messages) break + const match = search(messages, event.data.messageID, (item) => item.id) + if (!match.found) break + setStore( + "message", + event.data.sessionID, + produce((draft) => draft.splice(match.index, 1)), + ) + break + } + case "message.part.updated.1": { + touchPart(event.data.sessionID, event.data.part.id) + const part = event.data.part + const parts = store.part[part.messageID] + if (!parts) { + setStore("part", part.messageID, [part]) + break + } + const match = search(parts, part.id, (item) => item.id) + if (match.found) { + setStore("part", part.messageID, match.index, reconcile(part)) + break + } + setStore( + "part", + part.messageID, + produce((draft) => draft.splice(match.index, 0, part)), + ) + break + } + case "message.part.removed.1": { + touchPart(event.data.sessionID, event.data.partID) + const parts = store.part[event.data.messageID] + if (!parts) break + const match = search(parts, event.data.partID, (item) => item.id) + if (!match.found) break + setStore( + "part", + event.data.messageID, + produce((draft) => draft.splice(match.index, 1)), + ) + break + } + } + }) + // kilocode_change end + const exit = useExit() const args = useArgs() diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx index 04d7b7c038..c96768237c 100644 --- a/packages/tui/src/routes/session/index.tsx +++ b/packages/tui/src/routes/session/index.tsx @@ -2700,6 +2700,7 @@ function Question(props: ToolProps) { const { theme } = useTheme() const questions = createMemo(() => parseQuestions(props.input.questions)) const answers = createMemo(() => parseQuestionAnswers(props.metadata.answers)) + const dismissed = createMemo(() => props.metadata.dismissed === true) // kilocode_change const count = createMemo(() => questions().length) function format(answer?: ReadonlyArray) { @@ -2711,7 +2712,7 @@ function Question(props: ToolProps) { const title = createMemo(() => (dismissed() ? "# Questions (dismissed)" : "# Questions")) const subtitle = createMemo(() => { if (dismissed()) return `${count()} dismissed` - if ((props.metadata.answers?.length ?? 0) > 0) return `${count()} answered` + if ((answers()?.length ?? 0) > 0) return `${count()} answered` return `${count()} question${count() !== 1 ? "s" : ""}` }) // kilocode_change end diff --git a/packages/tui/src/routes/session/network.tsx b/packages/tui/src/routes/session/network.tsx index e1690ecda0..76d49e12ed 100644 --- a/packages/tui/src/routes/session/network.tsx +++ b/packages/tui/src/routes/session/network.tsx @@ -2,11 +2,11 @@ /** @jsxImportSource @opentui/solid */ import { Show, createEffect, createSignal, onCleanup } from "solid-js" import { useTheme } from "../../context/theme" -import { SplitBorder } from "../../component/border" +import { SplitBorder } from "../../ui/border" import { useSDK } from "../../context/sdk" import { useDialog } from "../../ui/dialog" import type { SessionNetworkWait } from "@kilocode/sdk/v2" -import { useTuiConfig } from "../../context/tui-config" +import { useTuiConfig } from "../../config" import { useBindings } from "../../keymap" export function NetworkPrompt(props: { request: SessionNetworkWait }) { diff --git a/packages/tui/src/routes/session/suggest.tsx b/packages/tui/src/routes/session/suggest.tsx index 2e01ca68b7..2a3a00eae3 100644 --- a/packages/tui/src/routes/session/suggest.tsx +++ b/packages/tui/src/routes/session/suggest.tsx @@ -1,2 +1,2 @@ // kilocode_change - new file -export { SuggestPrompt } from "../../../../../kilocode/suggestion/tui/prompt" +export { SuggestPrompt } from "@/kilocode/suggestion/tui/prompt" diff --git a/packages/tui/src/routes/session/terminal.tsx b/packages/tui/src/routes/session/terminal.tsx index 19f7a7bf8e..75a02f1bd2 100644 --- a/packages/tui/src/routes/session/terminal.tsx +++ b/packages/tui/src/routes/session/terminal.tsx @@ -3,7 +3,7 @@ import { TextAttributes, decodePasteBytes, type MouseEvent, type PasteEvent } fr import { useKeyboard, usePaste, useRenderer, useTerminalDimensions } from "@opentui/solid" import type { InteractiveTerminalSnapshot } from "@kilocode/sdk/v2" import { VtScreen } from "@/kilocode/cli/cmd/tui/vt/vt-screen" -import { SplitBorder } from "@tui/component/border" +import { SplitBorder } from "@tui/ui/border" import { useSDK } from "@tui/context/sdk" import { useSync } from "@tui/context/sync" import { useTheme } from "@tui/context/theme" diff --git a/packages/tui/src/ui/dialog-select.tsx b/packages/tui/src/ui/dialog-select.tsx index b147b5cf85..47bb76179a 100644 --- a/packages/tui/src/ui/dialog-select.tsx +++ b/packages/tui/src/ui/dialog-select.tsx @@ -45,7 +45,7 @@ export interface DialogSelectProps { } // kilocode_change start - support list-level actions when no option is selected -type DialogSelectActionBase = { +type DialogSelectActionBase = { command: string title: string side?: "left" | "right" @@ -53,7 +53,7 @@ type DialogSelectActionBase = { disabled?: boolean | ((option: DialogSelectOption | undefined) => boolean) } -type DialogSelectAction = DialogSelectActionBase & +type DialogSelectAction = DialogSelectActionBase & ( | { requiresSelection?: true diff --git a/packages/tui/test/cli/cmd/tui/sync-fixture.tsx b/packages/tui/test/cli/cmd/tui/sync-fixture.tsx index 9811a92ca5..6e313bf5e2 100644 --- a/packages/tui/test/cli/cmd/tui/sync-fixture.tsx +++ b/packages/tui/test/cli/cmd/tui/sync-fixture.tsx @@ -6,7 +6,8 @@ import { KVProvider, useKV } from "../../../../src/context/kv" import { ProjectProvider, useProject } from "../../../../src/context/project" import { SDKProvider } from "../../../../src/context/sdk" import { SyncProvider, useSync } from "../../../../src/context/sync" -import { ToastProvider } from "../../../../src/cli/cmd/tui/ui/toast" // kilocode_change +import { ToastProvider } from "../../../../src/ui/toast" // kilocode_change +import { ExitProvider } from "../../../../src/context/exit" // kilocode_change import { createEventSource, createFetch, type FetchHandler, directory } from "../../../fixture/tui-sdk" import { TestTuiContexts } from "../../../fixture/tui-environment" export { createEventSource, createFetch, directory, eventSource, json, worktree } from "../../../fixture/tui-sdk" @@ -52,9 +53,13 @@ export async function mount(override?: FetchHandler, state?: string) { {/* kilocode_change end */} - - - + {/* kilocode_change start - SyncProvider consumes the exit context */} + {}}> + + + + + {/* kilocode_change end */} {/* kilocode_change start */} diff --git a/packages/tui/test/cli/cmd/tui/sync-undefined-messages.test.tsx b/packages/tui/test/cli/cmd/tui/sync-undefined-messages.test.tsx index 06ddd6c348..6aea128692 100644 --- a/packages/tui/test/cli/cmd/tui/sync-undefined-messages.test.tsx +++ b/packages/tui/test/cli/cmd/tui/sync-undefined-messages.test.tsx @@ -7,7 +7,7 @@ * `messages.data!` while the SDK leaves `data` undefined on error. */ import { describe, expect, test } from "bun:test" -import { disposeAllInstances, provideTestInstance, tmpdir } from "../../../fixture/fixture" +import { tmpdir } from "../../../fixture/fixture" import { directory, json, mount } from "./sync-fixture" const sessionID = "ses_undef" @@ -25,26 +25,19 @@ describe("tui sync (#26560)", () => { directory, project_id: "proj_test", } - // kilocode_change start - const { app, sync } = await provideTestInstance({ - directory: tmp.path, - fn: () => - mount((url) => { - if (url.pathname === `/session/${sessionID}`) return json(sessionPayload) - if (url.pathname === `/session/${sessionID}/messages`) return json({}, { status: 500 }) - if (url.pathname === `/session/${sessionID}/todo`) return json([]) - if (url.pathname === `/session/${sessionID}/diff`) return json([]) - if (url.pathname === "/session") return json([sessionPayload]) - return undefined - }, tmp.path), - }) - // kilocode_change end + const { app, sync } = await mount((url) => { + if (url.pathname === `/session/${sessionID}`) return json(sessionPayload) + if (url.pathname === `/session/${sessionID}/messages`) return json({}, { status: 500 }) + if (url.pathname === `/session/${sessionID}/todo`) return json([]) + if (url.pathname === `/session/${sessionID}/diff`) return json([]) + if (url.pathname === "/session") return json([sessionPayload]) + return undefined + }, tmp.path) try { await expect(sync.session.sync(sessionID)).resolves.toBeUndefined() } finally { app.renderer.destroy() - await disposeAllInstances() // kilocode_change } }) }) diff --git a/packages/tui/test/cli/cmd/tui/sync.test.tsx b/packages/tui/test/cli/cmd/tui/sync.test.tsx index eeb3706ee9..e471ed1219 100644 --- a/packages/tui/test/cli/cmd/tui/sync.test.tsx +++ b/packages/tui/test/cli/cmd/tui/sync.test.tsx @@ -1,7 +1,7 @@ /** @jsxImportSource @opentui/solid */ import { describe, expect, test } from "bun:test" -import { disposeAllInstances, provideTestInstance, tmpdir } from "../../../fixture/fixture" -import { mount, wait } from "./sync-fixture" +import { tmpdir } from "../../../fixture/fixture" +import { json, mount, wait } from "./sync-fixture" import type { GlobalEvent } from "@kilocode/sdk/v2" function branchEvent(branch: string, workspace?: string): GlobalEvent { @@ -21,7 +21,7 @@ describe("tui sync", () => { test("refresh scopes sessions by default and lists project sessions when disabled", async () => { await using tmp = await tmpdir() await Bun.write(`${tmp.path}/kv.json`, "{}") - const { app, kv, sync, session } = await provideTestInstance({ directory: tmp.path, fn: () => mount(undefined, tmp.path) }) // kilocode_change + const { app, kv, sync, session } = await mount(undefined, tmp.path) try { expect(kv.get("session_directory_filter_enabled", true)).toBe(true) @@ -35,14 +35,16 @@ describe("tui sync", () => { expect(session.at(-1)?.searchParams.get("path")).toBeNull() } finally { app.renderer.destroy() - await disposeAllInstances() // kilocode_change } }) test("vcs branch updates only apply for the active workspace", async () => { await using tmp = await tmpdir() await Bun.write(`${tmp.path}/kv.json`, "{}") - const { app, emit, project, sync } = await mount(undefined, tmp.path) + const { app, emit, project, sync } = await mount( + (url) => (url.pathname === "/experimental/workspace" ? json([{ id: "ws_a" }]) : undefined), + tmp.path, + ) // kilocode_change - workspace re-bootstrap retains the selected test workspace try { expect(sync.data.vcs?.branch).toBe("main") diff --git a/packages/tui/test/fixture/tui-sdk.ts b/packages/tui/test/fixture/tui-sdk.ts index bd29a6194a..0d21c11216 100644 --- a/packages/tui/test/fixture/tui-sdk.ts +++ b/packages/tui/test/fixture/tui-sdk.ts @@ -54,8 +54,18 @@ export function createFetch(override?: FetchHandler) { ].includes(url.pathname) ) return json([]) - if (["/config", "/experimental/resource", "/mcp", "/provider/auth", "/session/status"].includes(url.pathname)) + if ( + ["/config", "/global/config", "/experimental/resource", "/mcp", "/provider/auth", "/session/status"].includes( + url.pathname, + ) + ) return json({}) + // kilocode_change start - Kilo bootstrap endpoints + if (["/network", "/background-process", "/interactive-terminal", "/config/warnings"].includes(url.pathname)) + return json([]) + if (url.pathname === "/indexing/status") + return json({ state: "Disabled", message: "Indexing disabled.", processedFiles: 0, totalFiles: 0, percent: 0 }) + // kilocode_change end if (url.pathname === "/config/providers") return json({ providers: {}, default: {} }) if (url.pathname === "/experimental/console") return json({ consoleManagedProviders: [], switchableOrgCount: 0 }) if (url.pathname === "/path") return json({ home: "", state: "", config: "", worktree, directory }) diff --git a/packages/tui/tsconfig.json b/packages/tui/tsconfig.json index ac9f4c63f7..fc2a2daa30 100644 --- a/packages/tui/tsconfig.json +++ b/packages/tui/tsconfig.json @@ -5,6 +5,13 @@ "jsx": "preserve", "jsxImportSource": "@opentui/solid", "lib": ["ESNext", "DOM", "DOM.Iterable"], - "noUncheckedIndexedAccess": false - } + "noUncheckedIndexedAccess": false, + // kilocode_change - resolve Kilo integrations retained during upstream's standalone TUI extraction + "paths": { + "@/*": ["../opencode/src/*"], + "@tui/*": ["./src/*"] + } + }, + // kilocode_change - include ambient declarations used by retained Kilo imports from opencode + "include": ["src", "test", "../opencode/src/*.d.ts"] } diff --git a/script/check-opencode-promise-facades.ts b/script/check-opencode-promise-facades.ts index e0592b9c02..5f72af6cb6 100644 --- a/script/check-opencode-promise-facades.ts +++ b/script/check-opencode-promise-facades.ts @@ -24,11 +24,12 @@ const allow: Record = { "cli/cmd/run/runtime.boot.ts": "direct run startup resolver runtime boundary", "cli/cmd/run/stream.transport.ts": "per-subscription direct run transport runtime boundary", "cli/cmd/run/variant.shared.ts": "direct run variant persistence runtime boundary with test filesystem injection", - "cli/cmd/tui/config/tui.ts": "separately tracked TUI config facade", + "config/tui.ts": "separately tracked TUI config facade moved by the upstream TUI extraction", "installation/index.ts": "existing installation facade outside #10655", } const testAllow: Record = { + "preload.ts": { count: 2, reason: "global test-suite AppRuntime cleanup boundary" }, "kilocode/config-resilience.test.ts": { count: 4, reason: "existing runtime integration test" }, "kilocode/config-validation.test.ts": { count: 2, reason: "existing runtime integration test" }, "kilocode/cli-shutdown.test.ts": { count: 1, reason: "mocked runtime boundary for shutdown unit tests" },