Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/quiet-jetbrains-watchers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/cli": patch
---

Fix high CPU and runaway memory growth in the JetBrains background `kilo serve` process on macOS by no longer eagerly starting native file watchers, matching the VS Code backend.
11 changes: 10 additions & 1 deletion packages/opencode/src/kilocode/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,17 @@ export namespace KilocodeWatcher {

export class Service extends Context.Service<Service, Interface>()("@kilocode/Watcher") {}

// Embedded editor clients (VS Code, JetBrains) have their own file watching
// and git integration and do not consume the CLI's vcs.branch.updated event,
// so they must not eagerly warm the location stack — that starts a native
// @parcel/watcher subscription per instance that lives for the whole session.
// On macOS FSEvents watches the entire subtree recursively (the ignore list
// is only a userspace filter), so an always-on, consumer-less watcher on a
// churny workspace burns CPU and leaks native memory while idle. The
// standalone CLI/TUI stays eager because its sidebar branch label is the only
// consumer and no request-driven route would otherwise build the stack.
export function eager(client = Flag.KILO_CLIENT) {
return client !== "vscode"
return client !== "vscode" && client !== "jetbrains"
}

export const layer = Layer.effect(
Expand Down
4 changes: 4 additions & 0 deletions packages/opencode/test/kilocode/instance-vcs-watcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ describe("KilocodeWatcher.eager", () => {
expect(KilocodeWatcher.eager("vscode")).toBe(false)
})

test("skips eager location watchers for JetBrains", () => {
expect(KilocodeWatcher.eager("jetbrains")).toBe(false)
})

test("keeps eager location watchers for the standalone CLI", () => {
expect(KilocodeWatcher.eager("cli")).toBe(true)
expect(KilocodeWatcher.eager(undefined)).toBe(true)
Expand Down
Loading