From 39f65efa8bc85490462b8a71ff0b7dddb1035d6a Mon Sep 17 00:00:00 2001 From: Mohammad Javad Naderi Date: Wed, 29 Jul 2026 18:50:20 +0330 Subject: [PATCH 01/25] fix(cli): skip startup work for informational commands --- .changeset/faster-cli-startup.md | 6 +++ .../src/__tests__/telemetry.test.ts | 13 ++++++ packages/kilo-telemetry/src/telemetry.ts | 2 + packages/opencode/src/kilocode/cli/setup.ts | 11 +++++ .../test/kilocode/cli-shutdown.test.ts | 46 +++++++++++++++++-- 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 .changeset/faster-cli-startup.md diff --git a/.changeset/faster-cli-startup.md b/.changeset/faster-cli-startup.md new file mode 100644 index 00000000000..6a64250c5df --- /dev/null +++ b/.changeset/faster-cli-startup.md @@ -0,0 +1,6 @@ +--- +"@kilocode/cli": patch +"@kilocode/kilo-telemetry": patch +--- + +Skip API and telemetry lifecycle work for informational CLI commands and avoid profile requests when telemetry is disabled. diff --git a/packages/kilo-telemetry/src/__tests__/telemetry.test.ts b/packages/kilo-telemetry/src/__tests__/telemetry.test.ts index 939bb5dd243..c86a249f51f 100644 --- a/packages/kilo-telemetry/src/__tests__/telemetry.test.ts +++ b/packages/kilo-telemetry/src/__tests__/telemetry.test.ts @@ -85,6 +85,19 @@ describe("TelemetryEvent", () => { }) describe("Telemetry", () => { + test("skips identity updates when disabled", async () => { + const enabled = spyOn(Client, "isEnabled").mockReturnValue(false) + const update = spyOn(Identity, "updateFromKiloAuth").mockResolvedValue() + + try { + await Telemetry.updateIdentity("token") + expect(update).not.toHaveBeenCalled() + } finally { + enabled.mockRestore() + update.mockRestore() + } + }) + test("includes host OS properties", () => { const capture = spyOn(Client, "capture").mockImplementation(() => {}) diff --git a/packages/kilo-telemetry/src/telemetry.ts b/packages/kilo-telemetry/src/telemetry.ts index 4d16051c2d8..4f3a9d1f79a 100644 --- a/packages/kilo-telemetry/src/telemetry.ts +++ b/packages/kilo-telemetry/src/telemetry.ts @@ -105,6 +105,8 @@ export namespace Telemetry { } export async function updateIdentity(token: string | null, accountId?: string): Promise { + if (!isEnabled()) return + const previousId = Identity.getDistinctId() await Identity.updateFromKiloAuth(token, accountId) diff --git a/packages/opencode/src/kilocode/cli/setup.ts b/packages/opencode/src/kilocode/cli/setup.ts index 561e5c54062..d89f118fa50 100644 --- a/packages/opencode/src/kilocode/cli/setup.ts +++ b/packages/opencode/src/kilocode/cli/setup.ts @@ -46,6 +46,13 @@ KiloShutdown.register(async () => { // (src/index.ts) only needs a handful of thin call-sites behind kilocode_change markers. // This keeps index.ts close to upstream and reduces merge conflicts on every sync. export namespace KiloCli { + function informational() { + const args = process.argv.slice(2) + const end = args.indexOf("--") + const flags = ["--help", "-h", "--version", "-v"] + return args.slice(0, end === -1 ? args.length : end).some((arg) => flags.includes(arg)) + } + // Register only the Kilo-specific commands. Upstream commands stay in index.ts's chain so // upstream merges that add or remove commands keep working without touching this file. export function register(cli: Argv): Argv { @@ -73,6 +80,8 @@ export namespace KiloCli { // Runs from the upstream `.middleware`, before any command handler. Env tagging is additive so // it never has to modify upstream's own env assignments. export async function bootstrap(): Promise { + if (informational()) return + await KiloLog.init() if (!process.env[ENV_FEATURE]) process.env[ENV_FEATURE] = process.argv.includes("serve") ? "unknown" : "cli" if (!process.env[ENV_VERSION]) process.env[ENV_VERSION] = InstallationVersion @@ -107,6 +116,8 @@ export namespace KiloCli { // Runs from the `finally` block on every exit path. export async function shutdown(): Promise { + if (informational()) return + const code = typeof process.exitCode === "number" ? process.exitCode : undefined Telemetry.trackCliExit(code) try { diff --git a/packages/opencode/test/kilocode/cli-shutdown.test.ts b/packages/opencode/test/kilocode/cli-shutdown.test.ts index 5a4babfbe09..0200d2ddf52 100644 --- a/packages/opencode/test/kilocode/cli-shutdown.test.ts +++ b/packages/opencode/test/kilocode/cli-shutdown.test.ts @@ -19,7 +19,9 @@ mock.module("@opencode-ai/core/installation/version", () => ({ mock.module("@kilocode/kilo-telemetry", () => ({ Telemetry: { - async init() {}, + async init() { + calls.push("telemetry:init") + }, async updateIdentity() {}, trackCliStart() {}, trackCliExit(code?: number) { @@ -36,16 +38,36 @@ mock.module("@kilocode/kilo-telemetry", () => ({ mock.module("@kilocode/kilo-gateway", () => ({ ENV_FEATURE: "KILO_FEATURE", ENV_VERSION: "KILO_VERSION", - async migrateLegacyKiloAuth() {}, + async migrateLegacyKiloAuth() { + calls.push("auth:migrate") + }, })) mock.module("@/effect/app-runtime", () => ({ AppRuntime: { - async runPromise() {}, + async runPromise() { + calls.push("runtime") + }, async dispose() {}, }, })) +mock.module("@/kilocode/log", () => ({ + KiloLog: { + async init() { + calls.push("log") + }, + }, +})) + +mock.module("@/kilocode/storage/json-migration", () => ({ + JsonMigration: { + async bootstrap() { + calls.push("migration") + }, + }, +})) + mock.module("@/config/config", () => ({ Config: { Service: { use: () => ({ experimental: {} }) } }, })) @@ -183,4 +205,22 @@ describe("KiloCli.shutdown", () => { expect(calls).toEqual(["track:1", "session", "telemetry", "drain", "dispose"]) expect(process.exitCode).toBe(1) }) + + test("skips lifecycle work for informational flags", async () => { + const { KiloCli } = await import("../../src/kilocode/cli/setup") + await installDrain() + + for (const flag of ["--help", "--version"]) { + process.argv.push(flag) + try { + await KiloCli.bootstrap() + await KiloCli.shutdown() + } finally { + process.argv.pop() + } + } + + expect(calls).toEqual([]) + expect(timeouts).toEqual([]) + }) }) From 7522bb1faa9eb1cd256f73e020cbb19046d0b463 Mon Sep 17 00:00:00 2001 From: Mohammad Javad Naderi Date: Wed, 29 Jul 2026 19:42:19 +0330 Subject: [PATCH 02/25] fix(cli): use parsed informational flags --- packages/opencode/src/index.ts | 2 +- packages/opencode/src/kilocode/cli/setup.ts | 14 +++++--------- .../opencode/test/kilocode/cli-shutdown.test.ts | 13 ++++--------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 1da9d9d9c89..779f51423af 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -81,7 +81,7 @@ let cli = yargs(args) // kilocode_change process.env.AGENT = "1" process.env.OPENCODE = "1" process.env.KILO_PID = String(process.pid) - await KiloCli.bootstrap() // kilocode_change - env tagging, telemetry init, legacy JSON-to-SQLite migration, and auth migration + await KiloCli.bootstrap(opts) // kilocode_change - env tagging, telemetry init, legacy JSON-to-SQLite migration, and auth migration // kilocode_change start - retain Kilo process/run correlation metadata in startup logs Log.Default.info("opencode", { version: InstallationVersion, diff --git a/packages/opencode/src/kilocode/cli/setup.ts b/packages/opencode/src/kilocode/cli/setup.ts index d89f118fa50..7f52f32db39 100644 --- a/packages/opencode/src/kilocode/cli/setup.ts +++ b/packages/opencode/src/kilocode/cli/setup.ts @@ -46,12 +46,7 @@ KiloShutdown.register(async () => { // (src/index.ts) only needs a handful of thin call-sites behind kilocode_change markers. // This keeps index.ts close to upstream and reduces merge conflicts on every sync. export namespace KiloCli { - function informational() { - const args = process.argv.slice(2) - const end = args.indexOf("--") - const flags = ["--help", "-h", "--version", "-v"] - return args.slice(0, end === -1 ? args.length : end).some((arg) => flags.includes(arg)) - } + let info = false // Register only the Kilo-specific commands. Upstream commands stay in index.ts's chain so // upstream merges that add or remove commands keep working without touching this file. @@ -79,8 +74,9 @@ export namespace KiloCli { // Runs from the upstream `.middleware`, before any command handler. Env tagging is additive so // it never has to modify upstream's own env assignments. - export async function bootstrap(): Promise { - if (informational()) return + export async function bootstrap(opts: { [key: string]: unknown }): Promise { + info = opts.help === true || opts.version === true + if (info) return await KiloLog.init() if (!process.env[ENV_FEATURE]) process.env[ENV_FEATURE] = process.argv.includes("serve") ? "unknown" : "cli" @@ -116,7 +112,7 @@ export namespace KiloCli { // Runs from the `finally` block on every exit path. export async function shutdown(): Promise { - if (informational()) return + if (info) return const code = typeof process.exitCode === "number" ? process.exitCode : undefined Telemetry.trackCliExit(code) diff --git a/packages/opencode/test/kilocode/cli-shutdown.test.ts b/packages/opencode/test/kilocode/cli-shutdown.test.ts index 0200d2ddf52..451124d1547 100644 --- a/packages/opencode/test/kilocode/cli-shutdown.test.ts +++ b/packages/opencode/test/kilocode/cli-shutdown.test.ts @@ -206,18 +206,13 @@ describe("KiloCli.shutdown", () => { expect(process.exitCode).toBe(1) }) - test("skips lifecycle work for informational flags", async () => { + test("skips lifecycle work for parsed informational flags", async () => { const { KiloCli } = await import("../../src/kilocode/cli/setup") await installDrain() - for (const flag of ["--help", "--version"]) { - process.argv.push(flag) - try { - await KiloCli.bootstrap() - await KiloCli.shutdown() - } finally { - process.argv.pop() - } + for (const flag of ["help", "version"] as const) { + await KiloCli.bootstrap({ [flag]: true }) + await KiloCli.shutdown() } expect(calls).toEqual([]) From 1864a79e03cb71cc44b757a7e961a98bb32353f1 Mon Sep 17 00:00:00 2001 From: Josh Lambert Date: Mon, 3 Aug 2026 14:55:22 -0400 Subject: [PATCH 03/25] revert(cli): stop promoting stable releases to rc --- .../opencode/script/kilocode/npm-publish.ts | 4 ---- packages/opencode/script/publish.ts | 23 ++++++++----------- .../test/kilocode/npm-publish.test.ts | 10 -------- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/packages/opencode/script/kilocode/npm-publish.ts b/packages/opencode/script/kilocode/npm-publish.ts index 8f07ed2e750..2744ff675e4 100644 --- a/packages/opencode/script/kilocode/npm-publish.ts +++ b/packages/opencode/script/kilocode/npm-publish.ts @@ -3,10 +3,6 @@ export namespace NpmPublish { const base = 10_000 const jitter = 5_000 - export function aliases(channel: string) { - return channel === "latest" ? ["rc"] : [] - } - export async function retry(input: { name: string version: string diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index cfc99cacabd..bd94c7c0e3e 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -16,21 +16,18 @@ async function publish(dir: string, name: string, version: string) { // GitHub artifact downloads can drop the executable bit, and Docker uses the // unpacked dist binaries directly rather than the published tarball. if (process.platform !== "win32") await $`chmod -R 755 .`.cwd(dir) - // kilocode_change start - const exists = await published(name, version) - if (exists) { + if (await published(name, version)) { console.log(`already published ${name}@${version}`) + return } - if (!exists) { - await $`bun pm pack`.cwd(dir) - await NpmPublish.retry({ - name, - version, - run: () => $`npm publish *.tgz --access public --tag ${Script.channel} --provenance`.cwd(dir), - exists: () => published(name, version), - }) - } - for (const tag of NpmPublish.aliases(Script.channel)) await $`npm dist-tag add ${name}@${version} ${tag}` + await $`bun pm pack`.cwd(dir) + // kilocode_change start + await NpmPublish.retry({ + name, + version, + run: () => $`npm publish *.tgz --access public --tag ${Script.channel} --provenance`.cwd(dir), + exists: () => published(name, version), + }) // kilocode_change end } diff --git a/packages/opencode/test/kilocode/npm-publish.test.ts b/packages/opencode/test/kilocode/npm-publish.test.ts index 33318925ce7..62e94349865 100644 --- a/packages/opencode/test/kilocode/npm-publish.test.ts +++ b/packages/opencode/test/kilocode/npm-publish.test.ts @@ -1,16 +1,6 @@ import { describe, expect, test } from "bun:test" import { NpmPublish } from "../../script/kilocode/npm-publish" -describe("npm publish aliases", () => { - test("promotes stable releases to the rc channel", () => { - expect(NpmPublish.aliases("latest")).toEqual(["rc"]) - }) - - test("does not promote prereleases", () => { - expect(NpmPublish.aliases("rc")).toEqual([]) - }) -}) - describe("npm publish retry", () => { test("returns after the first successful attempt", async () => { const calls = { run: 0, exists: 0, sleep: 0 } From 20aead0d8740046ddc0170ef51a15ba2408a1c0c Mon Sep 17 00:00:00 2001 From: "kilo-maintainer[bot]" Date: Tue, 4 Aug 2026 07:56:10 +0000 Subject: [PATCH 04/25] release: v7.4.19 --- .../agent-manager-modal-mode-shortcut.md | 5 -- .changeset/bright-files-count.md | 5 -- .changeset/bright-project-dnd.md | 5 -- .changeset/clean-vscode-sidebar-edge.md | 5 -- .changeset/compaction-threshold-boundary.md | 5 -- .changeset/explain-tool-auto-approval-tui.md | 5 -- .changeset/fair-subagents-route.md | 5 -- .changeset/fast-local-recall.md | 5 -- .changeset/faster-macos-speech.md | 5 -- .changeset/fix-agent-manager-focus.md | 5 -- .changeset/grep-signal-controls.md | 5 -- .changeset/instant-worktree-hover.md | 5 -- .../jetbrains-attachment-button-sync.md | 5 -- .changeset/jetbrains-diff-view-fixes.md | 5 -- .changeset/jetbrains-session-load-crop.md | 5 -- .../prompt-training-indicator-height.md | 5 -- .changeset/quick-model-search.md | 5 -- .changeset/quiet-agent-sections.md | 5 -- .changeset/quiet-metadata-generators.md | 5 -- .changeset/quiet-speech-shortcut.md | 5 -- .changeset/quiet-terminals-focus.md | 5 -- .changeset/quiet-terminals-recover.md | 5 -- .changeset/skill-shell-inline-docs.md | 5 -- .changeset/tui-paste-expand-placeholder.md | 5 -- .../vscode-skills-settings-narrow-overflow.md | 5 -- .changeset/workflow-model-variants.md | 6 --- bun.lock | 50 +++++++++---------- package.json | 2 +- packages/core/package.json | 2 +- packages/effect-drizzle-sqlite/package.json | 2 +- packages/effect-sqlite-node/package.json | 2 +- packages/extensions/zed/extension.toml | 12 ++--- packages/http-recorder/package.json | 2 +- packages/kilo-console/package.json | 2 +- packages/kilo-docs/package.json | 2 +- packages/kilo-gateway/package.json | 2 +- packages/kilo-i18n/package.json | 2 +- packages/kilo-indexing/package.json | 2 +- packages/kilo-jetbrains/CHANGELOG.md | 11 ++++ packages/kilo-memory/package.json | 2 +- packages/kilo-sandbox/package.json | 2 +- packages/kilo-telemetry/package.json | 2 +- packages/kilo-ui/package.json | 2 +- packages/kilo-vscode/CHANGELOG.md | 36 +++++++++++++ packages/kilo-vscode/package.json | 2 +- packages/kilo-vscode/tests/package.json | 2 +- packages/kilo-web-ui/package.json | 2 +- packages/llm/package.json | 2 +- packages/opencode/CHANGELOG.md | 24 +++++++++ packages/opencode/package.json | 2 +- packages/plugin-atomic-chat/package.json | 2 +- packages/plugin/package.json | 2 +- packages/script/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/server/package.json | 2 +- packages/storybook/package.json | 2 +- packages/tui/package.json | 2 +- packages/ui/package.json | 2 +- script/upstream/package.json | 2 +- 59 files changed, 130 insertions(+), 190 deletions(-) delete mode 100644 .changeset/agent-manager-modal-mode-shortcut.md delete mode 100644 .changeset/bright-files-count.md delete mode 100644 .changeset/bright-project-dnd.md delete mode 100644 .changeset/clean-vscode-sidebar-edge.md delete mode 100644 .changeset/compaction-threshold-boundary.md delete mode 100644 .changeset/explain-tool-auto-approval-tui.md delete mode 100644 .changeset/fair-subagents-route.md delete mode 100644 .changeset/fast-local-recall.md delete mode 100644 .changeset/faster-macos-speech.md delete mode 100644 .changeset/fix-agent-manager-focus.md delete mode 100644 .changeset/grep-signal-controls.md delete mode 100644 .changeset/instant-worktree-hover.md delete mode 100644 .changeset/jetbrains-attachment-button-sync.md delete mode 100644 .changeset/jetbrains-diff-view-fixes.md delete mode 100644 .changeset/jetbrains-session-load-crop.md delete mode 100644 .changeset/prompt-training-indicator-height.md delete mode 100644 .changeset/quick-model-search.md delete mode 100644 .changeset/quiet-agent-sections.md delete mode 100644 .changeset/quiet-metadata-generators.md delete mode 100644 .changeset/quiet-speech-shortcut.md delete mode 100644 .changeset/quiet-terminals-focus.md delete mode 100644 .changeset/quiet-terminals-recover.md delete mode 100644 .changeset/skill-shell-inline-docs.md delete mode 100644 .changeset/tui-paste-expand-placeholder.md delete mode 100644 .changeset/vscode-skills-settings-narrow-overflow.md delete mode 100644 .changeset/workflow-model-variants.md diff --git a/.changeset/agent-manager-modal-mode-shortcut.md b/.changeset/agent-manager-modal-mode-shortcut.md deleted file mode 100644 index 4efdaa9bc43..00000000000 --- a/.changeset/agent-manager-modal-mode-shortcut.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Fix Agent Manager mode shortcuts in the New Worktree dialog so the selected mode and its matching model stay in sync. diff --git a/.changeset/bright-files-count.md b/.changeset/bright-files-count.md deleted file mode 100644 index 84e4aa4fa2b..00000000000 --- a/.changeset/bright-files-count.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Show aggregate added and removed line counts for multi-file patch tool calls. diff --git a/.changeset/bright-project-dnd.md b/.changeset/bright-project-dnd.md deleted file mode 100644 index 750341b6225..00000000000 --- a/.changeset/bright-project-dnd.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Restore Agent Manager sections and worktree drag-and-drop when multiple projects are shown, with ordering and section moves scoped to the owning project. diff --git a/.changeset/clean-vscode-sidebar-edge.md b/.changeset/clean-vscode-sidebar-edge.md deleted file mode 100644 index dd798951ac5..00000000000 --- a/.changeset/clean-vscode-sidebar-edge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Remove the duplicate border along the Kilo Code sidebar edge. diff --git a/.changeset/compaction-threshold-boundary.md b/.changeset/compaction-threshold-boundary.md deleted file mode 100644 index 2e610dbefb0..00000000000 --- a/.changeset/compaction-threshold-boundary.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Prevent configured compaction thresholds from interrupting active tool sequences. diff --git a/.changeset/explain-tool-auto-approval-tui.md b/.changeset/explain-tool-auto-approval-tui.md deleted file mode 100644 index df3e2f5cd03..00000000000 --- a/.changeset/explain-tool-auto-approval-tui.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": minor ---- - -Show why a tool call was auto-approved or denied in the TUI, and record the denial reason on the tool call metadata (visible in `kilo export`) alongside the existing auto-approval reason. diff --git a/.changeset/fair-subagents-route.md b/.changeset/fair-subagents-route.md deleted file mode 100644 index a1d2775fc90..00000000000 --- a/.changeset/fair-subagents-route.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Keep config-defined subagents routable when an installed primary agent uses the same name. diff --git a/.changeset/fast-local-recall.md b/.changeset/fast-local-recall.md deleted file mode 100644 index a2cc81e647c..00000000000 --- a/.changeset/fast-local-recall.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Speed up local session recall searches across large conversation histories. diff --git a/.changeset/faster-macos-speech.md b/.changeset/faster-macos-speech.md deleted file mode 100644 index 2d9bd9cc258..00000000000 --- a/.changeset/faster-macos-speech.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Start voice input faster on macOS with native AVFoundation capture. diff --git a/.changeset/fix-agent-manager-focus.md b/.changeset/fix-agent-manager-focus.md deleted file mode 100644 index f8d5d6c65e3..00000000000 --- a/.changeset/fix-agent-manager-focus.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Restore keyboard focus to the prompt or pending question when switching Agent Manager worktrees and sessions. diff --git a/.changeset/grep-signal-controls.md b/.changeset/grep-signal-controls.md deleted file mode 100644 index 917e6ed2f59..00000000000 --- a/.changeset/grep-signal-controls.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Add bounded, context-aware signal-to-noise controls to grep searches. diff --git a/.changeset/instant-worktree-hover.md b/.changeset/instant-worktree-hover.md deleted file mode 100644 index e95e1af87ba..00000000000 --- a/.changeset/instant-worktree-hover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Show and hide Agent Manager worktree hover cards instantly. diff --git a/.changeset/jetbrains-attachment-button-sync.md b/.changeset/jetbrains-attachment-button-sync.md deleted file mode 100644 index dc86abba24e..00000000000 --- a/.changeset/jetbrains-attachment-button-sync.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Keep the JetBrains prompt send/stop button in sync when attachments are added or removed while a session is busy. diff --git a/.changeset/jetbrains-diff-view-fixes.md b/.changeset/jetbrains-diff-view-fixes.md deleted file mode 100644 index 9fc6246c69b..00000000000 --- a/.changeset/jetbrains-diff-view-fixes.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Fix JetBrains diff views to show compact workspace-relative file paths and keep added-file content visible in large branch diffs. diff --git a/.changeset/jetbrains-session-load-crop.md b/.changeset/jetbrains-session-load-crop.md deleted file mode 100644 index 4e515cb3041..00000000000 --- a/.changeset/jetbrains-session-load-crop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Fix JetBrains chat transcripts rendering cropped when opening existing sessions. diff --git a/.changeset/prompt-training-indicator-height.md b/.changeset/prompt-training-indicator-height.md deleted file mode 100644 index e1842cbfef4..00000000000 --- a/.changeset/prompt-training-indicator-height.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Keep the prompt controls at a consistent height when the model selector shows the prompt-training indicator. diff --git a/.changeset/quick-model-search.md b/.changeset/quick-model-search.md deleted file mode 100644 index 5b01ee44f97..00000000000 --- a/.changeset/quick-model-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Update model search results instantly and keep the active match visible while typing. diff --git a/.changeset/quiet-agent-sections.md b/.changeset/quiet-agent-sections.md deleted file mode 100644 index b6d8d079c04..00000000000 --- a/.changeset/quiet-agent-sections.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Allow Agent Manager sessions to move their worktree between sections or ungroup it through the `agent_manager` tool. diff --git a/.changeset/quiet-metadata-generators.md b/.changeset/quiet-metadata-generators.md deleted file mode 100644 index 67bb87bcbd9..00000000000 --- a/.changeset/quiet-metadata-generators.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Keep Kilo's persona out of generated conversation titles and Agent Manager branch names. diff --git a/.changeset/quiet-speech-shortcut.md b/.changeset/quiet-speech-shortcut.md deleted file mode 100644 index aa18416e3b6..00000000000 --- a/.changeset/quiet-speech-shortcut.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Bind voice input to Cmd/Ctrl+K in Kilo prompt and review comment fields, with hold-to-talk and release-to-send support. diff --git a/.changeset/quiet-terminals-focus.md b/.changeset/quiet-terminals-focus.md deleted file mode 100644 index 22715b263ae..00000000000 --- a/.changeset/quiet-terminals-focus.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Preserve prompt or Agent Manager terminal focus independently for each session when switching sessions. diff --git a/.changeset/quiet-terminals-recover.md b/.changeset/quiet-terminals-recover.md deleted file mode 100644 index 99c87f0de2f..00000000000 --- a/.changeset/quiet-terminals-recover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Start a fresh shell in the same Agent Manager terminal tab when the user types after the terminal ends. diff --git a/.changeset/skill-shell-inline-docs.md b/.changeset/skill-shell-inline-docs.md deleted file mode 100644 index a0e1e864dfb..00000000000 --- a/.changeset/skill-shell-inline-docs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": patch ---- - -Stop treating `` !`cmd` `` shown as an inline code example in skill documentation as a live command, so it no longer triggers a shell permission prompt. diff --git a/.changeset/tui-paste-expand-placeholder.md b/.changeset/tui-paste-expand-placeholder.md deleted file mode 100644 index 07b963ca0bb..00000000000 --- a/.changeset/tui-paste-expand-placeholder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/cli": minor ---- - -A second identical large paste expands its collapsed prompt placeholder. \ No newline at end of file diff --git a/.changeset/vscode-skills-settings-narrow-overflow.md b/.changeset/vscode-skills-settings-narrow-overflow.md deleted file mode 100644 index bbdb87be496..00000000000 --- a/.changeset/vscode-skills-settings-narrow-overflow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": patch ---- - -Fix skill folder path and URL rows clipping and pushing the remove (×) button off-screen in narrow Skills settings panels. Long paths and URLs now truncate within their row, and hovering a truncated value shows the full path or URL in a tooltip. diff --git a/.changeset/workflow-model-variants.md b/.changeset/workflow-model-variants.md deleted file mode 100644 index 48b090358ce..00000000000 --- a/.changeset/workflow-model-variants.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@kilocode/cli": minor -"kilo-code": minor ---- - -Configure a model and reasoning variant for each workflow from Agent Behaviour settings. diff --git a/bun.lock b/bun.lock index e2b68afdf4f..7ea40fea9de 100644 --- a/bun.lock +++ b/bun.lock @@ -32,7 +32,7 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "7.4.18", + "version": "7.4.19", "bin": { "opencode": "./bin/opencode", }, @@ -127,7 +127,7 @@ }, "packages/effect-drizzle-sqlite": { "name": "@opencode-ai/effect-drizzle-sqlite", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "drizzle-orm": "catalog:", "effect": "catalog:", @@ -141,7 +141,7 @@ }, "packages/effect-sqlite-node": { "name": "@opencode-ai/effect-sqlite-node", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "effect": "catalog:", }, @@ -153,7 +153,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@effect/platform-node": "4.0.0-beta.74", "@effect/platform-node-shared": "4.0.0-beta.74", @@ -174,7 +174,7 @@ }, "packages/kilo-console": { "name": "@kilocode/kilo-console", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/kilo-indexing": "workspace:*", "@kilocode/kilo-web-ui": "workspace:*", @@ -197,7 +197,7 @@ }, "packages/kilo-docs": { "name": "@kilocode/kilo-docs", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@docsearch/css": "^4", "@docsearch/js": "^4", @@ -227,7 +227,7 @@ }, "packages/kilo-gateway": { "name": "@kilocode/kilo-gateway", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@ai-sdk/alibaba": "1.0.17", "@ai-sdk/anthropic": "3.0.82", @@ -263,7 +263,7 @@ }, "packages/kilo-i18n": { "name": "@kilocode/kilo-i18n", - "version": "7.4.18", + "version": "7.4.19", "devDependencies": { "@tsconfig/node22": "catalog:", "@types/bun": "catalog:", @@ -273,7 +273,7 @@ }, "packages/kilo-indexing": { "name": "@kilocode/kilo-indexing", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@aws-sdk/client-bedrock-runtime": "3.1005.0", "@aws-sdk/credential-provider-ini": "3.972.31", @@ -309,7 +309,7 @@ }, "packages/kilo-memory": { "name": "@kilocode/kilo-memory", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "effect": "catalog:", "zod": "catalog:", @@ -323,7 +323,7 @@ }, "packages/kilo-sandbox": { "name": "@kilocode/sandbox", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@anthropic-ai/sandbox-runtime": "catalog:", "effect": "catalog:", @@ -338,7 +338,7 @@ }, "packages/kilo-telemetry": { "name": "@kilocode/kilo-telemetry", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/kilo-gateway": "workspace:*", "posthog-node": "4.4.0", @@ -352,7 +352,7 @@ }, "packages/kilo-ui": { "name": "@kilocode/kilo-ui", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "0.13.11", @@ -390,7 +390,7 @@ }, "packages/kilo-vscode": { "name": "kilo-code", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@anthropic-ai/sdk": "^0.39.0", "@kilocode/kilo-gateway": "workspace:*", @@ -459,7 +459,7 @@ }, "packages/kilo-web-ui": { "name": "@kilocode/kilo-web-ui", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/kilo-ui": "workspace:*", "@kobalte/core": "catalog:", @@ -476,7 +476,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@smithy/eventstream-codec": "4.2.14", "@smithy/util-utf8": "4.2.2", @@ -494,7 +494,7 @@ }, "packages/opencode": { "name": "@kilocode/cli", - "version": "7.4.18", + "version": "7.4.19", "bin": { "kilo": "./bin/kilo", "kilocode": "./bin/kilo", @@ -661,7 +661,7 @@ }, "packages/plugin": { "name": "@kilocode/plugin", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/sdk": "workspace:*", "effect": "catalog:", @@ -689,7 +689,7 @@ }, "packages/plugin-atomic-chat": { "name": "@kilocode/plugin-atomic-chat", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/plugin": "workspace:*", }, @@ -703,7 +703,7 @@ }, "packages/script": { "name": "@opencode-ai/script", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "semver": "^7.6.3", }, @@ -714,7 +714,7 @@ }, "packages/sdk/js": { "name": "@kilocode/sdk", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "cross-spawn": "catalog:", }, @@ -729,7 +729,7 @@ }, "packages/server": { "name": "@opencode-ai/server", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@opencode-ai/core": "workspace:*", "drizzle-orm": "catalog:", @@ -743,7 +743,7 @@ }, "packages/storybook": { "name": "@opencode-ai/storybook", - "version": "7.4.18", + "version": "7.4.19", "devDependencies": { "@opencode-ai/ui": "workspace:*", "@solidjs/meta": "catalog:", @@ -766,7 +766,7 @@ }, "packages/tui": { "name": "@opencode-ai/tui", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/plugin": "workspace:*", "@kilocode/sdk": "workspace:*", @@ -793,7 +793,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "7.4.18", + "version": "7.4.19", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", diff --git a/package.json b/package.json index cb7a4a91b07..4766d72cb63 100644 --- a/package.json +++ b/package.json @@ -173,6 +173,6 @@ "pacote@21.5.1": "patches/pacote@21.5.1.patch", "mammoth@1.12.0": "patches/mammoth@1.12.0.patch" }, - "version": "7.4.18", + "version": "7.4.19", "peerDependencies": {} } diff --git a/packages/core/package.json b/packages/core/package.json index e07c580a5de..4155cb0b8a2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@opencode-ai/core", "type": "module", "license": "MIT", diff --git a/packages/effect-drizzle-sqlite/package.json b/packages/effect-drizzle-sqlite/package.json index 7303d76d7ca..ced95082c5d 100644 --- a/packages/effect-drizzle-sqlite/package.json +++ b/packages/effect-drizzle-sqlite/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@opencode-ai/effect-drizzle-sqlite", "type": "module", "license": "MIT", diff --git a/packages/effect-sqlite-node/package.json b/packages/effect-sqlite-node/package.json index 2b297b5ecb3..e6522fcf363 100644 --- a/packages/effect-sqlite-node/package.json +++ b/packages/effect-sqlite-node/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@opencode-ai/effect-sqlite-node", "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 5321bca1b32..e8e25dc664a 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "kilo" name = "Kilo" description = "The open source coding agent." -version = "7.4.18" +version = "7.4.19" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/Kilo-Org/kilocode" @@ -11,26 +11,26 @@ name = "Kilo" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.18/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.19/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.18/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.19/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.18/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.19/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.18/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.19/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.18/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.19/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/http-recorder/package.json b/packages/http-recorder/package.json index ff408eb4302..907cf34a457 100644 --- a/packages/http-recorder/package.json +++ b/packages/http-recorder/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@opencode-ai/http-recorder", "description": "Record and replay Effect HTTP client traffic with deterministic cassettes", "type": "module", diff --git a/packages/kilo-console/package.json b/packages/kilo-console/package.json index c9097a403ce..adcf70e94e3 100755 --- a/packages/kilo-console/package.json +++ b/packages/kilo-console/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-console", - "version": "7.4.18", + "version": "7.4.19", "private": true, "type": "module", "scripts": { diff --git a/packages/kilo-docs/package.json b/packages/kilo-docs/package.json index 5f296eedeaf..ecf0ce5f359 100644 --- a/packages/kilo-docs/package.json +++ b/packages/kilo-docs/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-docs", - "version": "7.4.18", + "version": "7.4.19", "private": true, "scripts": { "dev": "next dev --webpack --port 3002", diff --git a/packages/kilo-gateway/package.json b/packages/kilo-gateway/package.json index e55bbbdd5df..0c2672104ef 100644 --- a/packages/kilo-gateway/package.json +++ b/packages/kilo-gateway/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-gateway", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration", diff --git a/packages/kilo-i18n/package.json b/packages/kilo-i18n/package.json index b74de939f7d..fc4da0c1937 100644 --- a/packages/kilo-i18n/package.json +++ b/packages/kilo-i18n/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-i18n", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "description": "Kilo-specific i18n translations and overrides", diff --git a/packages/kilo-indexing/package.json b/packages/kilo-indexing/package.json index 7f2e39eea54..9b562562e41 100644 --- a/packages/kilo-indexing/package.json +++ b/packages/kilo-indexing/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-indexing", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "description": "Standalone indexing engine and host helpers for Kilo Code", diff --git a/packages/kilo-jetbrains/CHANGELOG.md b/packages/kilo-jetbrains/CHANGELOG.md index 58f12c85b35..d000b8245ae 100644 --- a/packages/kilo-jetbrains/CHANGELOG.md +++ b/packages/kilo-jetbrains/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 7.4.18 + +### Patch Changes + +- [#12746](https://github.com/Kilo-Org/kilocode/pull/12746) [`1a506a7`](https://github.com/Kilo-Org/kilocode/commit/1a506a712c43d317a5a34b250df16845b641eff8) - Keep the JetBrains prompt send/stop button in sync when attachments are added or removed while a session is busy. + +- [#12746](https://github.com/Kilo-Org/kilocode/pull/12746) [`64f0373`](https://github.com/Kilo-Org/kilocode/commit/64f0373056b75546a015816dc0f18b1e380ad93f) - Fix JetBrains diff views to show compact workspace-relative file paths and keep added-file content visible in large branch diffs. + +- [#12746](https://github.com/Kilo-Org/kilocode/pull/12746) [`c1f6a75`](https://github.com/Kilo-Org/kilocode/commit/c1f6a75377b438edfc5c3b5dd85ebdc301302e7a) - Fix JetBrains chat transcripts rendering cropped when opening existing sessions. + ## 7.5.0 ### Minor Changes @@ -150,6 +160,7 @@ ## [7.0.12-rc.4] - 2026-08-01 ### Fixed + - Improve large branch diff performance by capping huge inline diff previews, compacting diff tree paths, and allowing horizontal scrolling for long file names. - Reflow existing long chat sessions after they load so transcripts lay out at the correct width without needing to resize the tool window. - Keep the prompt send/stop button synchronized when attachments are added, removed, or cleared while a session is busy. diff --git a/packages/kilo-memory/package.json b/packages/kilo-memory/package.json index 4989cfc0f2c..f86e7b323bc 100644 --- a/packages/kilo-memory/package.json +++ b/packages/kilo-memory/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-memory", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "description": "Project memory storage, indexing, recall, and command helpers for Kilo Code", diff --git a/packages/kilo-sandbox/package.json b/packages/kilo-sandbox/package.json index 1355fc2e076..1c3a8d75255 100644 --- a/packages/kilo-sandbox/package.json +++ b/packages/kilo-sandbox/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/sandbox", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "private": true, diff --git a/packages/kilo-telemetry/package.json b/packages/kilo-telemetry/package.json index 63a01315655..bd132654f5e 100644 --- a/packages/kilo-telemetry/package.json +++ b/packages/kilo-telemetry/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-telemetry", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "description": "Telemetry for Kilo CLI - PostHog analytics integration", diff --git a/packages/kilo-ui/package.json b/packages/kilo-ui/package.json index 8724dc548f9..f04bf3f4c10 100644 --- a/packages/kilo-ui/package.json +++ b/packages/kilo-ui/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-ui", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "exports": { diff --git a/packages/kilo-vscode/CHANGELOG.md b/packages/kilo-vscode/CHANGELOG.md index 5a7cdeac28a..eafd8bda91e 100644 --- a/packages/kilo-vscode/CHANGELOG.md +++ b/packages/kilo-vscode/CHANGELOG.md @@ -1,5 +1,41 @@ # kilo-code +## 7.4.19 + +### Minor Changes + +- [#12729](https://github.com/Kilo-Org/kilocode/pull/12729) [`ce7984f`](https://github.com/Kilo-Org/kilocode/commit/ce7984fc4247fb2805990ef62e1b1d9f286de9d9) - Configure a model and reasoning variant for each workflow from Agent Behaviour settings. + +### Patch Changes + +- [#12796](https://github.com/Kilo-Org/kilocode/pull/12796) [`20d1648`](https://github.com/Kilo-Org/kilocode/commit/20d1648e7a10f981fde09fc4d5e9de5c89b1dda8) - Fix Agent Manager mode shortcuts in the New Worktree dialog so the selected mode and its matching model stay in sync. + +- [#12725](https://github.com/Kilo-Org/kilocode/pull/12725) [`f239f36`](https://github.com/Kilo-Org/kilocode/commit/f239f36f65a1edb5ef89748933b49b3f21639a45) - Show aggregate added and removed line counts for multi-file patch tool calls. + +- [#12803](https://github.com/Kilo-Org/kilocode/pull/12803) [`9819c1c`](https://github.com/Kilo-Org/kilocode/commit/9819c1c315bd05631862ad6f21bbef21d73b7bdc) - Restore Agent Manager sections and worktree drag-and-drop when multiple projects are shown, with ordering and section moves scoped to the owning project. + +- [#12836](https://github.com/Kilo-Org/kilocode/pull/12836) [`4f7dfe6`](https://github.com/Kilo-Org/kilocode/commit/4f7dfe65cc85ef7d103a9d0d93f86b030f7142e0) - Remove the duplicate border along the Kilo Code sidebar edge. + +- [#12814](https://github.com/Kilo-Org/kilocode/pull/12814) [`cd7d053`](https://github.com/Kilo-Org/kilocode/commit/cd7d053f03fa7b5434b6fcae9e2c68e415b54331) - Start voice input faster on macOS with native AVFoundation capture. + +- [#12795](https://github.com/Kilo-Org/kilocode/pull/12795) [`37559f8`](https://github.com/Kilo-Org/kilocode/commit/37559f8643ef8ecb68ee04eae770c9b47feee88a) - Restore keyboard focus to the prompt or pending question when switching Agent Manager worktrees and sessions. + +- [#12799](https://github.com/Kilo-Org/kilocode/pull/12799) [`7cfaeb2`](https://github.com/Kilo-Org/kilocode/commit/7cfaeb2c8dbe7355b1d92d9a8f62d6bdfb7f6d46) - Show and hide Agent Manager worktree hover cards instantly. + +- [#12805](https://github.com/Kilo-Org/kilocode/pull/12805) [`8490124`](https://github.com/Kilo-Org/kilocode/commit/84901241c0c6dcb735d7e229bd9bce2c0f7e5c36) - Keep the prompt controls at a consistent height when the model selector shows the prompt-training indicator. + +- [#12810](https://github.com/Kilo-Org/kilocode/pull/12810) [`e04f653`](https://github.com/Kilo-Org/kilocode/commit/e04f6531bf3ef2eed5cde6e1d81a4983f276b9ca) - Update model search results instantly and keep the active match visible while typing. + +- [#12815](https://github.com/Kilo-Org/kilocode/pull/12815) [`3d4294e`](https://github.com/Kilo-Org/kilocode/commit/3d4294e3bb50630159233c8063b253dc5f3da8d3) - Allow Agent Manager sessions to move their worktree between sections or ungroup it through the `agent_manager` tool. + +- [#12798](https://github.com/Kilo-Org/kilocode/pull/12798) [`dfc1607`](https://github.com/Kilo-Org/kilocode/commit/dfc16076934decb6578730ea41f9705e2acc0923) - Bind voice input to Cmd/Ctrl+K in Kilo prompt and review comment fields, with hold-to-talk and release-to-send support. + +- [#12801](https://github.com/Kilo-Org/kilocode/pull/12801) [`4810766`](https://github.com/Kilo-Org/kilocode/commit/4810766d058f53084b8a6cb0fe4d1ff42973e89b) - Preserve prompt or Agent Manager terminal focus independently for each session when switching sessions. + +- [#12812](https://github.com/Kilo-Org/kilocode/pull/12812) [`6ae16f9`](https://github.com/Kilo-Org/kilocode/commit/6ae16f9d6272b3bfba998bb516cba7667935d6e4) - Start a fresh shell in the same Agent Manager terminal tab when the user types after the terminal ends. + +- [#12733](https://github.com/Kilo-Org/kilocode/pull/12733) [`63220e0`](https://github.com/Kilo-Org/kilocode/commit/63220e019c048d6df639a4b2fbd4c5c3f124547f) Thanks [@rakshith1928](https://github.com/rakshith1928)! - Fix skill folder path and URL rows clipping and pushing the remove (×) button off-screen in narrow Skills settings panels. Long paths and URLs now truncate within their row, and hovering a truncated value shows the full path or URL in a tooltip. + ## 7.4.18 ### Minor Changes diff --git a/packages/kilo-vscode/package.json b/packages/kilo-vscode/package.json index 71e266cd363..76e372ad917 100644 --- a/packages/kilo-vscode/package.json +++ b/packages/kilo-vscode/package.json @@ -2,7 +2,7 @@ "name": "kilo-code", "displayName": "Kilo Code: AI Coding Agent, Copilot, and Autocomplete", "description": "Open Source AI coding agent that generates code from natural language, automates tasks, and runs terminal commands. Features inline autocomplete, browser automation, automated refactoring, and custom modes for planning, coding, and debugging. Supports 500+ AI models including Claude (Anthropic), Gemini, Grok, GPT, Codex and GLM.", - "version": "7.4.18", + "version": "7.4.19", "icon": "assets/icons/logo-outline-black.png", "galleryBanner": { "color": "#FFFFFF", diff --git a/packages/kilo-vscode/tests/package.json b/packages/kilo-vscode/tests/package.json index 0219e54e36c..d967d45d874 100644 --- a/packages/kilo-vscode/tests/package.json +++ b/packages/kilo-vscode/tests/package.json @@ -1,6 +1,6 @@ { "type": "module", - "version": "7.4.18", + "version": "7.4.19", "dependencies": {}, "devDependencies": {}, "peerDependencies": {} diff --git a/packages/kilo-web-ui/package.json b/packages/kilo-web-ui/package.json index b0cc608f590..d265df1d29e 100644 --- a/packages/kilo-web-ui/package.json +++ b/packages/kilo-web-ui/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-web-ui", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "exports": { diff --git a/packages/llm/package.json b/packages/llm/package.json index f47683b9d24..1fb01cf7023 100644 --- a/packages/llm/package.json +++ b/packages/llm/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@opencode-ai/llm", "type": "module", "license": "MIT", diff --git a/packages/opencode/CHANGELOG.md b/packages/opencode/CHANGELOG.md index 42fac90936e..0176ed3cf02 100644 --- a/packages/opencode/CHANGELOG.md +++ b/packages/opencode/CHANGELOG.md @@ -1,5 +1,29 @@ # @kilocode/cli +## 7.4.19 + +### Minor Changes + +- [#12728](https://github.com/Kilo-Org/kilocode/pull/12728) [`6b27a26`](https://github.com/Kilo-Org/kilocode/commit/6b27a26f929f570275e26529189b4d2fc3c392cf) Thanks [@bagatao-anaconda](https://github.com/bagatao-anaconda)! - Show why a tool call was auto-approved or denied in the TUI, and record the denial reason on the tool call metadata (visible in `kilo export`) alongside the existing auto-approval reason. + +- [#12816](https://github.com/Kilo-Org/kilocode/pull/12816) [`63a38f5`](https://github.com/Kilo-Org/kilocode/commit/63a38f5c7ae8fb08af1461b143a7c0f6b8dbc680) - A second identical large paste expands its collapsed prompt placeholder. + +- [#12729](https://github.com/Kilo-Org/kilocode/pull/12729) [`ce7984f`](https://github.com/Kilo-Org/kilocode/commit/ce7984fc4247fb2805990ef62e1b1d9f286de9d9) - Configure a model and reasoning variant for each workflow from Agent Behaviour settings. + +### Patch Changes + +- [#12792](https://github.com/Kilo-Org/kilocode/pull/12792) [`7d3f50c`](https://github.com/Kilo-Org/kilocode/commit/7d3f50c2e8510e6ae86bb310c2706bb79f1c02ff) - Prevent configured compaction thresholds from interrupting active tool sequences. + +- [#12652](https://github.com/Kilo-Org/kilocode/pull/12652) [`c554409`](https://github.com/Kilo-Org/kilocode/commit/c554409080a59422066f93df90155e448ec9b250) Thanks [@Hardik180704](https://github.com/Hardik180704)! - Keep config-defined subagents routable when an installed primary agent uses the same name. + +- [#12726](https://github.com/Kilo-Org/kilocode/pull/12726) [`2fbd380`](https://github.com/Kilo-Org/kilocode/commit/2fbd380dfcfcbc4537e48727b15af2176451cf84) - Speed up local session recall searches across large conversation histories. + +- [#12811](https://github.com/Kilo-Org/kilocode/pull/12811) [`989f7f0`](https://github.com/Kilo-Org/kilocode/commit/989f7f06a03f3502e7ab761f1ae72b5c7b47451c) - Add bounded, context-aware signal-to-noise controls to grep searches. + +- [#12790](https://github.com/Kilo-Org/kilocode/pull/12790) [`8be3303`](https://github.com/Kilo-Org/kilocode/commit/8be33032b906f27c0d883212354f75eeb7044f35) - Keep Kilo's persona out of generated conversation titles and Agent Manager branch names. + +- [#12802](https://github.com/Kilo-Org/kilocode/pull/12802) [`5bd420a`](https://github.com/Kilo-Org/kilocode/commit/5bd420aae15787dc629d27b663f9f1b6e2cac888) Thanks [@bagatao-anaconda](https://github.com/bagatao-anaconda)! - Stop treating `` !`cmd` `` shown as an inline code example in skill documentation as a live command, so it no longer triggers a shell permission prompt. + ## 7.4.18 ### Minor Changes diff --git a/packages/opencode/package.json b/packages/opencode/package.json index ea7b37fb09d..6a8767dbc98 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.4.18", + "version": "7.4.19", "name": "@kilocode/cli", "type": "module", "license": "MIT", diff --git a/packages/plugin-atomic-chat/package.json b/packages/plugin-atomic-chat/package.json index 554a5f527bc..489eca786f1 100644 --- a/packages/plugin-atomic-chat/package.json +++ b/packages/plugin-atomic-chat/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/plugin-atomic-chat", - "version": "7.4.18", + "version": "7.4.19", "description": "Kilo Code plugin for Atomic Chat: auto-detection and dynamic model discovery (OpenAI-compatible local API)", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 305899105cc..560c202f2b2 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/plugin", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/script/package.json b/packages/script/package.json index 9c6851dab38..777f4eb3761 100644 --- a/packages/script/package.json +++ b/packages/script/package.json @@ -12,6 +12,6 @@ "exports": { ".": "./src/index.ts" }, - "version": "7.4.18", + "version": "7.4.19", "peerDependencies": {} } diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index f7f1d7ecda0..1d3b8a5dedc 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/sdk", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index 04006121d84..74bd7e3f35e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/server", - "version": "7.4.18", + "version": "7.4.19", "private": true, "type": "module", "license": "MIT", diff --git a/packages/storybook/package.json b/packages/storybook/package.json index 56bc841220c..4ba8d909a18 100644 --- a/packages/storybook/package.json +++ b/packages/storybook/package.json @@ -26,7 +26,7 @@ "typescript": "catalog:", "vite": "catalog:" }, - "version": "7.4.18", + "version": "7.4.19", "dependencies": {}, "peerDependencies": {} } diff --git a/packages/tui/package.json b/packages/tui/package.json index 3e241c725b4..3f1f649ca61 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/tui", - "version": "7.4.18", + "version": "7.4.19", "private": true, "type": "module", "license": "MIT", diff --git a/packages/ui/package.json b/packages/ui/package.json index 0346e145ec0..142bae54fae 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "7.4.18", + "version": "7.4.19", "type": "module", "license": "MIT", "exports": { diff --git a/script/upstream/package.json b/script/upstream/package.json index 6c10f20641e..de4ee8082ac 100644 --- a/script/upstream/package.json +++ b/script/upstream/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/upstream-merge", - "version": "7.4.18", + "version": "7.4.19", "private": true, "type": "module", "description": "Scripts for automating upstream opencode merges into Kilo", From 4af1d1c8abd15881f5c06554cca8e2f6133003ee Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Tue, 4 Aug 2026 10:02:29 +0200 Subject: [PATCH 05/25] fix(vscode): keep final patch file visible --- .changeset/last-file-patch.md | 5 +++++ .../kilo-ui/src/components/message-part.tsx | 17 ++++------------ .../src/stories/tool-call-lab.stories.tsx | 20 ++++++++++++++++++- 3 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 .changeset/last-file-patch.md diff --git a/.changeset/last-file-patch.md b/.changeset/last-file-patch.md new file mode 100644 index 00000000000..b9a269fa5e6 --- /dev/null +++ b/.changeset/last-file-patch.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Keep the final file visible when expanding multi-file patch results. diff --git a/packages/kilo-ui/src/components/message-part.tsx b/packages/kilo-ui/src/components/message-part.tsx index 0a61e75f6c6..4281174d125 100644 --- a/packages/kilo-ui/src/components/message-part.tsx +++ b/packages/kilo-ui/src/components/message-part.tsx @@ -2799,18 +2799,9 @@ ToolRegistry.register({ > {(file) => { - const active = createMemo(() => expanded().includes(file.filePath)) - const [visible, setVisible] = createSignal(false) - createEffect(() => { - if (!active()) { - setVisible(false) - return - } - requestAnimationFrame(() => { - if (!active()) return - setVisible(true) - }) - }) + // Diff defers its own expensive render; mounting the container + // here avoids dropping the last item during batch expansion. + const active = createMemo(() => allExpanded().includes(file.filePath)) return ( @@ -2864,7 +2855,7 @@ ToolRegistry.register({ - + {(diff) => (
Date: Tue, 4 Aug 2026 08:06:03 +0000 Subject: [PATCH 06/25] chore: update kilo-vscode visual regression baselines --- .../labs-tool-call-lab/search-previews-chromium-linux.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/labs-tool-call-lab/search-previews-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/labs-tool-call-lab/search-previews-chromium-linux.png index 6a4e3e8ba0b..e571fdb6845 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/labs-tool-call-lab/search-previews-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/labs-tool-call-lab/search-previews-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd794db4d2c038984f9e753ba70b8b0473d97a16713a9ff7255f0d2cf505d41a -size 758306 +oid sha256:033960b68a915d0b05ce539784998d0f84603f206689dbbd14005771d112faa4 +size 762429 From 744c5c4a6b244d2aac38b7acc08f98a4086544ad Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Tue, 4 Aug 2026 10:06:40 +0200 Subject: [PATCH 07/25] feat(vscode): discover speech-to-text models --- .changeset/dynamic-speech-to-text-models.md | 5 ++ packages/kilo-gateway/src/api/models.ts | 57 ++++++++++++++ packages/kilo-gateway/src/index.ts | 3 + packages/kilo-gateway/test/api/models.test.ts | 55 +++++++++++++- packages/kilo-vscode/src/KiloProvider.ts | 13 ++++ .../src/kilo-provider/early-message.ts | 5 ++ .../src/kilo-provider/handlers/auth.ts | 6 ++ .../kilo-vscode/src/speech-to-text/catalog.ts | 66 ++++++++++++++++ .../src/speech-to-text/transcribe.ts | 2 +- .../unit/speech-to-text-availability.test.ts | 8 +- .../tests/unit/speech-to-text-catalog.test.ts | 35 +++++++++ .../webview-ui/agent-manager/DiffPanel.tsx | 4 +- .../agent-manager/NewWorktreeDialog.tsx | 4 +- .../webview-ui/diff-viewer/DiffViewerApp.tsx | 7 +- .../diff-viewer/FullScreenDiffView.tsx | 4 +- .../src/components/chat/PromptInput.tsx | 4 +- .../src/components/settings/ModelsTab.tsx | 11 ++- .../components/speech-to-text/availability.ts | 14 +++- .../speech-to-text/model-selector.ts | 14 ++-- .../webview-ui/src/context/provider-shell.tsx | 9 ++- .../src/context/speech-to-text-models.tsx | 33 ++++++++ .../src/types/messages/extension-messages.ts | 7 ++ .../src/types/messages/webview-messages.ts | 5 ++ .../server/httpapi/groups/kilo-gateway.ts | 17 +++++ .../server/httpapi/handlers/kilo-gateway.ts | 25 +++++++ .../server/httpapi-exercise-scenarios.ts | 1 + .../kilocode/server/httpapi-public.test.ts | 9 +++ packages/sdk/js/src/v2/gen/sdk.gen.ts | 36 +++++++++ packages/sdk/js/src/v2/gen/types.gen.ts | 32 ++++++++ packages/sdk/openapi.json | 75 +++++++++++++++++++ 30 files changed, 539 insertions(+), 27 deletions(-) create mode 100644 .changeset/dynamic-speech-to-text-models.md create mode 100644 packages/kilo-vscode/src/speech-to-text/catalog.ts create mode 100644 packages/kilo-vscode/tests/unit/speech-to-text-catalog.test.ts create mode 100644 packages/kilo-vscode/webview-ui/src/context/speech-to-text-models.tsx diff --git a/.changeset/dynamic-speech-to-text-models.md b/.changeset/dynamic-speech-to-text-models.md new file mode 100644 index 00000000000..1d6d6225dbd --- /dev/null +++ b/.changeset/dynamic-speech-to-text-models.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Discover available speech-to-text models from the Kilo Gateway while retaining offline fallback support and organization model restrictions. diff --git a/packages/kilo-gateway/src/api/models.ts b/packages/kilo-gateway/src/api/models.ts index d0bb964ca51..8188c1f825b 100644 --- a/packages/kilo-gateway/src/api/models.ts +++ b/packages/kilo-gateway/src/api/models.ts @@ -1,6 +1,7 @@ import { z } from "zod" import { getKiloUrlFromToken } from "../auth/token.js" import { getDefaultHeaders, buildKiloHeaders } from "../headers.js" +import { resolveKiloGatewayBaseUrl } from "./url.js" import { KILO_API_BASE, KILO_OPENROUTER_BASE, MODELS_FETCH_TIMEOUT_MS, PROMPTS, AI_SDK_PROVIDERS } from "./constants.js" export type KiloModelsResult = { @@ -121,6 +122,16 @@ export type KiloImageModelsResult = { error?: { kind: "unauthorized" | "network" | "schema" | "http"; status?: number } } +export type KiloTranscriptionModel = { + id: string + name: string +} + +export type KiloTranscriptionModelsResult = { + models: KiloTranscriptionModel[] + error?: { kind: "unauthorized" | "network" | "schema" | "http"; status?: number } +} + /** * Fetch image-capable models from Kilo API (OpenRouter-compatible endpoint). * Uses the same raw fetch as {@link fetchKiloModels} but keeps only models @@ -145,6 +156,52 @@ export async function fetchKiloImageModels(options?: { return { models } } +export async function fetchKiloTranscriptionModels(options?: { + kilocodeToken?: string + kilocodeOrganizationId?: string + baseURL?: string +}): Promise { + const token = options?.kilocodeToken + const organizationId = options?.kilocodeOrganizationId + const url = new URL("transcription-models", resolveKiloGatewayBaseUrl({ baseURL: options?.baseURL, token })) + const response = await fetch(url, { + headers: { + ...getDefaultHeaders(), + ...buildKiloHeaders(undefined, { kilocodeOrganizationId: organizationId }), + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + signal: AbortSignal.timeout(MODELS_FETCH_TIMEOUT_MS), + }).catch((err: unknown) => err as Error) + + if (response instanceof Error) return { models: [], error: { kind: "network" } } + if (!response.ok) { + const kind = response.status === 401 || response.status === 403 ? "unauthorized" : "http" + return { models: [], error: { kind, status: response.status } } + } + + const json = await response.json().catch(() => null) + if (!json || !Array.isArray(json.data)) return { models: [], error: { kind: "schema" } } + + const data: unknown[] = json.data + const models = data.filter(isTranscriptionModel).map((model) => ({ + id: model.id, + name: model.name, + })) + if (models.length === 0) return { models: [], error: { kind: "schema" } } + return { models } +} + +type TranscriptionModelResponse = { + id: string + name: string +} + +function isTranscriptionModel(value: unknown): value is TranscriptionModelResponse { + if (!value || typeof value !== "object") return false + const model = value as Record + return typeof model.id === "string" && typeof model.name === "string" +} + /** * Shared raw fetch + validate used by both {@link fetchKiloModels} and {@link fetchKiloImageModels}. */ diff --git a/packages/kilo-gateway/src/index.ts b/packages/kilo-gateway/src/index.ts index cee10c2f781..4df0e8a7681 100644 --- a/packages/kilo-gateway/src/index.ts +++ b/packages/kilo-gateway/src/index.ts @@ -41,6 +41,9 @@ export { fetchKiloImageModels, type KiloImageModel, type KiloImageModelsResult, + fetchKiloTranscriptionModels, + type KiloTranscriptionModel, + type KiloTranscriptionModelsResult, } from "./api/models.js" export { EMPTY_KILO_EMBEDDING_MODEL_CATALOG, diff --git a/packages/kilo-gateway/test/api/models.test.ts b/packages/kilo-gateway/test/api/models.test.ts index 656d27eaf05..0833ec11f30 100644 --- a/packages/kilo-gateway/test/api/models.test.ts +++ b/packages/kilo-gateway/test/api/models.test.ts @@ -1,7 +1,7 @@ // Verifies fetchKiloModels typed result and 401 fallback behaviour. import { test, expect } from "bun:test" -import { fetchKiloModels } from "../../src/api/models.js" +import { fetchKiloModels, fetchKiloTranscriptionModels } from "../../src/api/models.js" const VALID_RESPONSE = JSON.stringify({ data: [ @@ -330,3 +330,56 @@ test("keeps image-output models with tools and drops models without tools", asyn expect(result.models["test/model-a"]).toBeDefined() expect(result.models["test/no-tools"]).toBeUndefined() }) + +test("fetches and filters the transcription catalog", async () => { + const orig = globalThis.fetch + const calls: string[] = [] + stubFetch(async (input) => { + calls.push(String(input)) + return new Response( + JSON.stringify({ + data: [ + { + id: "fish-audio/transcribe-1", + name: "Fish Audio: Transcribe 1", + }, + ], + }), + { status: 200, headers: { "content-type": "application/json" } }, + ) + }) + + const result = await fetchKiloTranscriptionModels({ kilocodeToken: "token" }) + + ;(globalThis as any).fetch = orig + + expect(result.error).toBeUndefined() + expect(result.models).toEqual([ + { + id: "fish-audio/transcribe-1", + name: "Fish Audio: Transcribe 1", + }, + ]) + expect(calls[0]).toContain("/api/gateway/transcription-models") +}) + +test("keeps organization catalog errors from silently falling back to personal models", async () => { + const orig = globalThis.fetch + const calls: string[] = [] + const headers: Headers[] = [] + stubFetch(async (input, init) => { + calls.push(String(input)) + headers.push(new Headers(init?.headers)) + return new Response("Forbidden", { status: 403 }) + }) + + const result = await fetchKiloTranscriptionModels({ kilocodeToken: "token", kilocodeOrganizationId: "org-1" }) + + ;(globalThis as any).fetch = orig + + expect(result.models).toEqual([]) + expect(result.error?.kind).toBe("unauthorized") + expect(calls).toHaveLength(1) + expect(calls[0]).toContain("/api/gateway/transcription-models") + expect(headers[0]?.get("X-KILOCODE-ORGANIZATIONID")).toBe("org-1") +}) diff --git a/packages/kilo-vscode/src/KiloProvider.ts b/packages/kilo-vscode/src/KiloProvider.ts index 980f8e42722..bb1d8c903e1 100644 --- a/packages/kilo-vscode/src/KiloProvider.ts +++ b/packages/kilo-vscode/src/KiloProvider.ts @@ -169,6 +169,8 @@ import type { ProjectRef, SessionRef, WorktreeRef } from "./agent-manager/projec import { indexingConsentStore, registeredProjects } from "./indexing-consent" import { fetchKiloEmbeddingModelCatalog } from "@kilocode/kilo-gateway" import { fetchImageModels } from "./image-generation/models" +import { fetchSpeechToTextModels } from "./speech-to-text/catalog" +import { SPEECH_TO_TEXT_MODELS } from "./speech-to-text/models" import { stopSessionProcesses } from "./kilo-provider/background-process" import { sandboxDefault, sandboxSessionMetadata } from "./shared/sandbox-session" import { @@ -1021,6 +1023,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper exportTranscript: (sessionID) => this.handleExportSessionTranscript(sessionID), copy: (text) => vscode.env.clipboard.writeText(text), openSessions: (ids) => this.trackOpenSessions(ids), + speechToTextModels: () => this.fetchAndSendSpeechToTextModels(), }) ) { return @@ -2701,6 +2704,15 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper this.postMessage(message) } + private async fetchAndSendSpeechToTextModels(): Promise { + const result = await fetchSpeechToTextModels(this.connectionService, this.getWorkspaceDirectory()) + if (!result.ok) { + this.postMessage({ type: "speechToTextModelsLoaded" as const, models: [...SPEECH_TO_TEXT_MODELS] }) + return + } + this.postMessage({ type: "speechToTextModelsLoaded" as const, models: result.models }) + } + /** * Seed sessionStatusMap with current session statuses on connect. * Without this, the Settings panel (which has no tracked sessions) would see @@ -3944,6 +3956,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper disposeGlobal: () => this.disposeGlobal(), fetchAndSendProviders: () => this.fetchAndSendProviders(), fetchAndSendAgents: () => this.fetchAndSendAgents(), + fetchAndSendSpeechToTextModels: () => this.fetchAndSendSpeechToTextModels(), } } diff --git a/packages/kilo-vscode/src/kilo-provider/early-message.ts b/packages/kilo-vscode/src/kilo-provider/early-message.ts index f67a2144fa1..abf79b49a02 100644 --- a/packages/kilo-vscode/src/kilo-provider/early-message.ts +++ b/packages/kilo-vscode/src/kilo-provider/early-message.ts @@ -17,6 +17,7 @@ type Ctx = { exportTranscript: (sessionID: string) => Promise copy: (text: string) => PromiseLike openSessions: (ids: string[]) => void + speechToTextModels: () => Promise } export async function routeEarlyMessage( @@ -64,6 +65,10 @@ export async function routeEarlyMessage( ctx.post(buildThroughputSettingMessage()) return true } + if (message.type === "requestSpeechToTextModels") { + await ctx.speechToTextModels() + return true + } if (message.type === "requestBrowserSettings") { ctx.browserSettings() return true diff --git a/packages/kilo-vscode/src/kilo-provider/handlers/auth.ts b/packages/kilo-vscode/src/kilo-provider/handlers/auth.ts index db6e9e6d7df..07ae712b902 100644 --- a/packages/kilo-vscode/src/kilo-provider/handlers/auth.ts +++ b/packages/kilo-vscode/src/kilo-provider/handlers/auth.ts @@ -15,6 +15,7 @@ export interface AuthContext { disposeGlobal(): Promise fetchAndSendProviders(): Promise fetchAndSendAgents(): Promise + fetchAndSendSpeechToTextModels(): Promise } /** @@ -137,6 +138,11 @@ export async function handleSetOrganization(ctx: AuthContext, organizationId: st } catch (error) { console.error("[Kilo New] KiloProvider: Failed to refresh agents after org switch:", error) } + try { + await ctx.fetchAndSendSpeechToTextModels() + } catch (error) { + console.error("[Kilo New] KiloProvider: Failed to refresh speech-to-text models after org switch:", error) + } } /** Handle profile refresh request. */ diff --git a/packages/kilo-vscode/src/speech-to-text/catalog.ts b/packages/kilo-vscode/src/speech-to-text/catalog.ts new file mode 100644 index 00000000000..f9d2724dd52 --- /dev/null +++ b/packages/kilo-vscode/src/speech-to-text/catalog.ts @@ -0,0 +1,66 @@ +import type { KiloConnectionService } from "../services/cli-backend/connection-service" +import { getErrorMessage } from "../kilo-provider-utils" +import { type SpeechToTextModelDef } from "./models" + +const PATH = "/kilo/models/transcriptions" + +type CatalogModel = { + id: string + name: string +} + +export type SpeechToTextCatalogResult = { ok: true; models: SpeechToTextModelDef[] } | { ok: false; error: string } + +export async function fetchSpeechToTextModels( + connection: KiloConnectionService, + dir: string, + signal?: AbortSignal, +): Promise { + const cfg = connection.getServerConfig() + if (!cfg) return fail("Not connected to the Kilo backend") + + const auth = Buffer.from(`kilo:${cfg.password}`).toString("base64") + const url = new URL(PATH, cfg.baseUrl) + if (dir) url.searchParams.set("directory", dir) + + try { + const res = await fetch(url, { signal, headers: { Authorization: `Basic ${auth}` } }) + if (!res.ok) return fail(`Failed to fetch speech-to-text models (HTTP ${res.status})`) + + const models = parseSpeechToTextCatalog(await res.json()) + if (!models) return fail("Invalid speech-to-text model catalog") + return { ok: true, models } + } catch (err) { + return fail(getErrorMessage(err)) + } +} + +function fail(error: string): SpeechToTextCatalogResult { + return { ok: false, error } +} + +export function parseSpeechToTextCatalog(body: unknown): SpeechToTextModelDef[] | undefined { + if (!Array.isArray(body)) return undefined + const models = body.filter(isCatalogModel).map(toModel) + return models.length > 0 ? models : undefined +} + +function isCatalogModel(value: unknown): value is CatalogModel { + if (!value || typeof value !== "object") return false + const model = value as Record + return typeof model.id === "string" && typeof model.name === "string" +} + +function toModel(model: CatalogModel): SpeechToTextModelDef { + const provider = model.name.split(":", 1)[0]?.trim() || model.id.split("/", 1)[0] || "Kilo Gateway" + return { + id: model.id, + label: model.name.includes(":") ? model.name.slice(model.name.indexOf(":") + 1).trim() : model.name, + provider, + ...(isVerbatim(model.id) ? { verbatim: true } : {}), + } +} + +function isVerbatim(id: string): boolean { + return id === "openai/gpt-4o-mini-transcribe" || id === "openai/gpt-4o-transcribe" +} diff --git a/packages/kilo-vscode/src/speech-to-text/transcribe.ts b/packages/kilo-vscode/src/speech-to-text/transcribe.ts index 1e978bf028c..f40f188ac85 100644 --- a/packages/kilo-vscode/src/speech-to-text/transcribe.ts +++ b/packages/kilo-vscode/src/speech-to-text/transcribe.ts @@ -54,7 +54,7 @@ export async function transcribeSpeech( "Content-Type": "application/json", }, body: JSON.stringify({ - model: model.id, + model: input.model ?? model.id, input_audio: { data: input.data, format: input.format, diff --git a/packages/kilo-vscode/tests/unit/speech-to-text-availability.test.ts b/packages/kilo-vscode/tests/unit/speech-to-text-availability.test.ts index 83848168963..1361f8f5166 100644 --- a/packages/kilo-vscode/tests/unit/speech-to-text-availability.test.ts +++ b/packages/kilo-vscode/tests/unit/speech-to-text-availability.test.ts @@ -23,9 +23,11 @@ describe("speech-to-text availability", () => { }) it("normalizes configured and unknown transcription models", () => { - expect(selectedSpeechToTextModel({ experimental: { speech_to_text_model: "google/chirp-3" } })).toBe( - "google/chirp-3", - ) + expect( + selectedSpeechToTextModel({ experimental: { speech_to_text_model: "google/chirp-3" } }, [ + { id: "google/chirp-3", label: "Chirp 3", provider: "Google" }, + ]), + ).toBe("google/chirp-3") expect(selectedSpeechToTextModel({ experimental: { speech_to_text_model: "unknown/model" } })).toBe( DEFAULT_SPEECH_TO_TEXT_MODEL.id, ) diff --git a/packages/kilo-vscode/tests/unit/speech-to-text-catalog.test.ts b/packages/kilo-vscode/tests/unit/speech-to-text-catalog.test.ts new file mode 100644 index 00000000000..1b1f0f3cc5f --- /dev/null +++ b/packages/kilo-vscode/tests/unit/speech-to-text-catalog.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, it } from "bun:test" +import { parseSpeechToTextCatalog } from "../../src/speech-to-text/catalog" +import { DEFAULT_SPEECH_TO_TEXT_MODEL } from "../../src/speech-to-text/models" + +describe("speech-to-text discovery", () => { + it("keeps transcription catalog metadata authoritative and exposes additions", () => { + const models = parseSpeechToTextCatalog([ + { + id: "fish-audio/transcribe-1", + name: "Fish Audio: Transcribe 1", + }, + { + id: "openai/gpt-4o-mini-transcribe", + name: "OpenAI: GPT-4o Mini Transcribe", + }, + ]) + + expect(models).toEqual([ + { id: "fish-audio/transcribe-1", label: "Transcribe 1", provider: "Fish Audio" }, + { + id: "openai/gpt-4o-mini-transcribe", + label: "GPT-4o Mini Transcribe", + provider: "OpenAI", + verbatim: true, + }, + ]) + expect(models?.find((model) => model.id === "openai/gpt-4o-mini-transcribe")?.verbatim).toBe(true) + }) + + it("rejects empty or malformed catalogs so callers can use the static fallback", () => { + expect(parseSpeechToTextCatalog([])).toBeUndefined() + expect(parseSpeechToTextCatalog({ data: [] })).toBeUndefined() + expect(DEFAULT_SPEECH_TO_TEXT_MODEL.id).toBe("openai/whisper-large-v3-turbo") + }) +}) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx index 083d892d557..ae15fa3cf6b 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx @@ -21,6 +21,7 @@ import { useProvider } from "../src/context/provider" import { useConfig } from "../src/context/config" import { canUseSpeechToText, selectedSpeechToTextModel } from "../src/components/speech-to-text/availability" import { useSpeechToText } from "../src/components/speech-to-text/useSpeechToText" +import { useSpeechToTextModels } from "../src/context/speech-to-text-models" import { getDirectory, getFilename, @@ -111,8 +112,9 @@ export const DiffPanel: Component = (props) => { const provider = useProvider() const { config } = useConfig() const speech = useSpeechToText(vscode, server, { t }) + const speechModels = useSpeechToTextModels() const canUseSpeech = () => canUseSpeechToText(config(), provider.authStates()) - const speechModel = () => selectedSpeechToTextModel(config()) + const speechModel = () => selectedSpeechToTextModel(config(), speechModels.models()) const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent) const sendAllKeybind = () => isMac ? t("agentManager.review.sendAllShortcut.mac") : t("agentManager.review.sendAllShortcut.other") diff --git a/packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx b/packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx index 65217564e36..3daeea8705e 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/NewWorktreeDialog.tsx @@ -39,6 +39,7 @@ import { import { useLanguage } from "../src/context/language" import { useImageAttachments, type ImageAttachment } from "../src/hooks/useImageAttachments" import { useSpeechToText } from "../src/components/speech-to-text/useSpeechToText" +import { useSpeechToTextModels } from "../src/context/speech-to-text-models" import { convertToMentionPath } from "../src/utils/path-mentions" import { insertSpacedText } from "../src/components/chat/prompt-input-utils" import { WandSparkles } from "@kilocode/kilo-ui/lucide" @@ -130,8 +131,9 @@ export const NewWorktreeDialog: Component<{ const sandboxRequestID = crypto.randomUUID() const sandboxVisible = () => features().sandboxControls && globalConfig().sandbox?.enabled === true const speech = useSpeechToText(vscode, server, { t }) + const speechModels = useSpeechToTextModels() const canUseSpeech = () => canUseSpeechToText(config(), provider.authStates()) - const speechModel = () => selectedSpeechToTextModel(config()) + const speechModel = () => selectedSpeechToTextModel(config(), speechModels.models()) let prior: string | null = null let request: string | undefined const cancel = () => { diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx b/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx index 5ab642292e1..08115371429 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx +++ b/packages/kilo-vscode/webview-ui/diff-viewer/DiffViewerApp.tsx @@ -24,6 +24,7 @@ import type { DiffViewerNotice } from "../src/types/messages/extension-messages" import { DiffPickerHeader } from "./DiffPickerHeader" import { BaseBranchPicker } from "./BaseBranchPicker" import { SpeechToTextPrewarm } from "../src/components/speech-to-text/SpeechToTextPrewarm" +import { SpeechToTextModelsProvider } from "../src/context/speech-to-text-models" const NOTICE_KEYS: Record = { "snapshots-disabled": "diffViewer.notice.snapshotsDisabled", @@ -306,8 +307,10 @@ export const DiffViewerApp: Component = () => { - - + + + + diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/FullScreenDiffView.tsx b/packages/kilo-vscode/webview-ui/diff-viewer/FullScreenDiffView.tsx index 73ba90e60f5..6f708f8bd91 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/FullScreenDiffView.tsx +++ b/packages/kilo-vscode/webview-ui/diff-viewer/FullScreenDiffView.tsx @@ -27,6 +27,7 @@ import { useProvider } from "../src/context/provider" import { useConfig } from "../src/context/config" import { canUseSpeechToText, selectedSpeechToTextModel } from "../src/components/speech-to-text/availability" import { useSpeechToText } from "../src/components/speech-to-text/useSpeechToText" +import { useSpeechToTextModels } from "../src/context/speech-to-text-models" import { FileTree } from "./FileTree" import { treeOrder } from "./file-tree-utils" import { getDirectory, getFilename, lineCount, sanitizeReviewComments, type ReviewComment } from "./review-comments" @@ -113,8 +114,9 @@ export const FullScreenDiffView: Component = (props) => const provider = useProvider() const { config } = useConfig() const speech = useSpeechToText(vscode, server, { t }) + const speechModels = useSpeechToTextModels() const canUseSpeech = () => canUseSpeechToText(config(), provider.authStates()) - const speechModel = () => selectedSpeechToTextModel(config()) + const speechModel = () => selectedSpeechToTextModel(config(), speechModels.models()) const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent) const sendAllKeybind = () => isMac ? t("agentManager.review.sendAllShortcut.mac") : t("agentManager.review.sendAllShortcut.other") diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx index d63b0d6a219..f6490936694 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/PromptInput.tsx @@ -34,6 +34,7 @@ import { hasGitChangesMention } from "../../hooks/git-changes-context-utils" import { useSlashCommand } from "../../hooks/useSlashCommand" import { useGhostText } from "../../hooks/useGhostText" import { useSpeechToText } from "../speech-to-text/useSpeechToText" +import { useSpeechToTextModels } from "../../context/speech-to-text-models" import { useImageAttachments, type ImageAttachment } from "../../hooks/useImageAttachments" import { convertToMentionPath } from "../../utils/path-mentions" import { SessionMentionPicker } from "./SessionMentionPicker" @@ -341,6 +342,7 @@ export const PromptInput: Component = (props) => { const ghost = useGhostText(vscode, text, () => server.isConnected()) const speech = useSpeechToText(vscode, server, language) + const speechModels = useSpeechToTextModels() const replaceReviewComments = (next: ReviewComment[]) => { setReviewComments(next) @@ -498,7 +500,7 @@ export const PromptInput: Component = (props) => { ) const isDisabled = () => !server.isConnected() const canUseSpeech = () => canUseSpeechToText(config(), provider.authStates()) - const speechModel = () => selectedSpeechToTextModel(config()) + const speechModel = () => selectedSpeechToTextModel(config(), speechModels.models()) const hasInput = () => text().trim().length > 0 || imageAttach.images().length > 0 || reviewComments().length > 0 const canSend = () => !isDisabled() && diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx index 81f57c39682..619cf17bd13 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx @@ -7,13 +7,14 @@ import { useConfig } from "../../context/config" import { useLanguage } from "../../context/language" import { useProvider } from "../../context/provider" import { useSession } from "../../context/session" +import { useSpeechToTextModels } from "../../context/speech-to-text-models" import { parseModelString } from "../../../../src/shared/provider-model" import { ModelSelectorBase } from "../shared/ModelSelector" import { ThinkingSelectorBase } from "../shared/ThinkingSelector" import SettingsRow from "./SettingsRow" import { DEFAULT_SPEECH_TO_TEXT_MODEL } from "../../../../src/speech-to-text/models" import { hasSpeechToTextAccess, selectedSpeechToTextModel } from "../speech-to-text/availability" -import { SPEECH_TO_TEXT_MODEL_OPTIONS } from "../speech-to-text/model-selector" +import { speechToTextModelOptions } from "../speech-to-text/model-selector" import { AUTOCOMPLETE_SELECTOR_MODELS, getAutocompleteSelection } from "./autocomplete-model-selector" const ModelsTab: Component = () => { @@ -21,6 +22,7 @@ const ModelsTab: Component = () => { const language = useLanguage() const provider = useProvider() const session = useSession() + const speechModels = useSpeechToTextModels() const autocompleteProvider = () => { const v = settings()["autocomplete.provider"] @@ -42,8 +44,9 @@ const ModelsTab: Component = () => { } const subagentModel = createMemo(() => parseModelString(config().subagent_model ?? undefined)) - const speechModel = createMemo(() => selectedSpeechToTextModel(config())) - const speechOption = createMemo(() => SPEECH_TO_TEXT_MODEL_OPTIONS.find((item) => item.value === speechModel())) + const speechModel = createMemo(() => selectedSpeechToTextModel(config(), speechModels.models())) + const speechOptions = createMemo(() => speechToTextModelOptions(speechModels.models())) + const speechOption = createMemo(() => speechOptions().find((item) => item.value === speechModel())) const kiloReady = createMemo(() => hasSpeechToTextAccess(config(), provider.authStates())) const variantKey = createMemo(() => config().subagent_model ?? undefined) const subagentVariants = createMemo(() => Object.keys(provider.findModel(subagentModel())?.variants ?? {})) @@ -190,7 +193,7 @@ const ModelsTab: Component = () => { inactive={kiloReady()} >