From c8b21d1f0b532deabe0c0c0c4b6dfd72aab1ae6d Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Mon, 17 Aug 2026 10:19:13 +0200 Subject: [PATCH] fix(vscode): bound file mention directory cache --- .../tests/unit/use-file-mention.test.ts | 52 +++++++++++++++++++ .../webview-ui/src/hooks/useFileMention.ts | 12 ++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/kilo-vscode/tests/unit/use-file-mention.test.ts b/packages/kilo-vscode/tests/unit/use-file-mention.test.ts index 9b9d5ec974..f85954525c 100644 --- a/packages/kilo-vscode/tests/unit/use-file-mention.test.ts +++ b/packages/kilo-vscode/tests/unit/use-file-mention.test.ts @@ -900,6 +900,58 @@ describe("useFileMention", () => { dispose.fn?.() }) + it("bounds remembered session directories", () => { + const posted: WebviewMessage[] = [] + const handlers = new Set<(message: ExtensionMessage) => void>() + const ctx = { + postMessage: (message: WebviewMessage) => posted.push(message), + onMessage: (handler: (message: ExtensionMessage) => void) => { + handlers.add(handler) + return () => handlers.delete(handler) + }, + } + + const dispose: { fn?: () => void } = {} + const state = createRoot((root) => { + dispose.fn = root + const [session, setSession] = createSignal("session-0") + return { mention: useFileMention(ctx, session, () => false), setSession } + }) + + const reply = (request: WebviewMessage | undefined, dir: string) => { + for (const handler of handlers) { + handler({ + type: "fileSearchResult", + requestId: request?.type === "requestFileSearch" ? request.requestId : "", + dir, + paths: [], + items: [], + }) + } + } + + state.mention.onInput("@", 1) + reply(posted.at(-1), "/repo/0") + for (let index = 1; index <= 8; index++) { + state.mention.closeMention() + state.setSession(`session-${index}`) + state.mention.onInput("@", 1) + reply(posted.at(-1), `/repo/${index}`) + } + + state.mention.closeMention() + state.setSession("session-0") + state.mention.onInput("@", 1) + + expect(state.mention.mentionResults()).toEqual([ + { type: "terminal", value: "terminal", label: "Terminal", description: "Active terminal output" }, + { type: "past-chats", value: "past-chats", label: "Past chats", description: "Search previous sessions" }, + FILE_PICKER_RESULT, + ]) + + dispose.fn?.() + }) + it("preserves the highlighted file when fresh results replace cached results", () => { const posted: WebviewMessage[] = [] const handlers = new Set<(message: ExtensionMessage) => void>() diff --git a/packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts b/packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts index 80c9b01927..d0d383af01 100644 --- a/packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts +++ b/packages/kilo-vscode/webview-ui/src/hooks/useFileMention.ts @@ -199,6 +199,16 @@ export function useFileMention( } } + const writeDir = (id: string, dir: string) => { + dirs.delete(id) + dirs.set(id, dir) + while (dirs.size > FILE_SEARCH_CACHE_LIMIT) { + const oldest = dirs.keys().next().value + if (oldest === undefined) return + dirs.delete(oldest) + } + } + const replaceResults = (items: MentionResult[]) => { const index = mentionIndex() const selected = mentionResults()[index] @@ -259,7 +269,7 @@ export function useFileMention( const items = message.items ?? message.paths.map((path) => ({ path, type: "file" as const })) if (message.dir) { - dirs.set(request.scope, message.dir) + writeDir(request.scope, message.dir) workspaceDir = message.dir } if (!request.query) writeCache(message.dir, items, request.revision)