From 7df8377491c914af2ea957cdb56167271799924a Mon Sep 17 00:00:00 2001 From: Johnny Amancio Date: Tue, 30 Jun 2026 11:02:35 +0200 Subject: [PATCH 1/3] feat(vscode): persist model selector expand/collapse state Save the model picker's preview-panel expand/collapse preference via the VS Code webview state API so it survives reload, hide/show, and restart. --- .../src/components/shared/ModelSelector.tsx | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx index d08274bc501..1af590fff86 100644 --- a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx @@ -30,6 +30,7 @@ import { useProvider } from "../../context/provider" import type { EnrichedModel } from "../../context/provider" import { useSession, SessionContext } from "../../context/session" import { useLanguage } from "../../context/language" +import { getVSCodeAPI } from "../../context/vscode" import type { ModelSelection } from "../../types/messages" import { isEnterKeyCommitNotIme } from "../../utils/ime-enter" import { @@ -135,6 +136,30 @@ export interface ModelSelectorBaseProps { description?: string } +// Persisted via the VS Code webview state API so the preview-panel preference +// survives reload and hide/show; defaults to expanded unless explicitly collapsed. +const EXPANDED_STATE_KEY = "modelSelectorExpanded" + +function loadExpanded(): boolean { + try { + const state = getVSCodeAPI().getState() as Record | undefined + return state?.[EXPANDED_STATE_KEY] !== false + } catch (err) { + console.warn("[Kilo New] model selector expanded load failed", err) + return true + } +} + +function saveExpanded(val: boolean) { + try { + const api = getVSCodeAPI() + const state = (api.getState() as Record | undefined) ?? {} + api.setState({ ...state, [EXPANDED_STATE_KEY]: val }) + } catch (err) { + console.warn("[Kilo New] model selector expanded save failed", err) + } +} + export const ModelSelectorBase: Component = (props) => { const { connected, models, findModel } = useProvider() const language = useLanguage() @@ -153,7 +178,9 @@ export const ModelSelectorBase: Component = (props) => { }) const [open, setOpen] = createSignal(false) - const [expanded, setExpanded] = createSignal(true) + const [expanded, setExpanded] = createSignal(loadExpanded()) + // Persist the user's expand/collapse choice so it is restored on reopen. + createEffect(() => saveExpanded(expanded())) const [search, setSearch] = createSignal("") const [debouncedSearch, setDebouncedSearch] = createSignal("") const [selectedKey, setSelectedKey] = createSignal(CLEAR_KEY) From c5aec2080fefed1893c62435ca6d4ced3f192ecd Mon Sep 17 00:00:00 2001 From: Johnny Amancio Date: Tue, 30 Jun 2026 11:14:44 +0200 Subject: [PATCH 2/3] chore(vscode): add model picker changeset --- .changeset/persist-model-picker-state.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/persist-model-picker-state.md diff --git a/.changeset/persist-model-picker-state.md b/.changeset/persist-model-picker-state.md new file mode 100644 index 00000000000..2630a94f935 --- /dev/null +++ b/.changeset/persist-model-picker-state.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Preserve the model picker preview panel expand/collapse state across reloads and restarts. From 22f9834f0cf420ccb75d7237ca861fb700622521 Mon Sep 17 00:00:00 2001 From: Johnny Amancio Date: Tue, 30 Jun 2026 11:54:04 +0200 Subject: [PATCH 3/3] fix(vscode): address model selector review feedback --- .../src/components/shared/ModelSelector.tsx | 31 +++---------------- .../webview-ui/src/context/vscode.tsx | 11 +++++++ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx index 1af590fff86..92b93b8ea30 100644 --- a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx @@ -30,7 +30,7 @@ import { useProvider } from "../../context/provider" import type { EnrichedModel } from "../../context/provider" import { useSession, SessionContext } from "../../context/session" import { useLanguage } from "../../context/language" -import { getVSCodeAPI } from "../../context/vscode" +import { useVSCode } from "../../context/vscode" import type { ModelSelection } from "../../types/messages" import { isEnterKeyCommitNotIme } from "../../utils/ime-enter" import { @@ -136,33 +136,10 @@ export interface ModelSelectorBaseProps { description?: string } -// Persisted via the VS Code webview state API so the preview-panel preference -// survives reload and hide/show; defaults to expanded unless explicitly collapsed. -const EXPANDED_STATE_KEY = "modelSelectorExpanded" - -function loadExpanded(): boolean { - try { - const state = getVSCodeAPI().getState() as Record | undefined - return state?.[EXPANDED_STATE_KEY] !== false - } catch (err) { - console.warn("[Kilo New] model selector expanded load failed", err) - return true - } -} - -function saveExpanded(val: boolean) { - try { - const api = getVSCodeAPI() - const state = (api.getState() as Record | undefined) ?? {} - api.setState({ ...state, [EXPANDED_STATE_KEY]: val }) - } catch (err) { - console.warn("[Kilo New] model selector expanded save failed", err) - } -} - export const ModelSelectorBase: Component = (props) => { const { connected, models, findModel } = useProvider() const language = useLanguage() + const vscode = useVSCode() // Session context is optional — ModelSelectorBase is also used in Settings // where SessionProvider may not be mounted. const session = useContext(SessionContext) @@ -178,9 +155,9 @@ export const ModelSelectorBase: Component = (props) => { }) const [open, setOpen] = createSignal(false) - const [expanded, setExpanded] = createSignal(loadExpanded()) + const [expanded, setExpanded] = createSignal(vscode.getModelSelectorExpanded()) // Persist the user's expand/collapse choice so it is restored on reopen. - createEffect(() => saveExpanded(expanded())) + createEffect(() => vscode.setModelSelectorExpanded(expanded())) const [search, setSearch] = createSignal("") const [debouncedSearch, setDebouncedSearch] = createSignal("") const [selectedKey, setSelectedKey] = createSignal(CLEAR_KEY) diff --git a/packages/kilo-vscode/webview-ui/src/context/vscode.tsx b/packages/kilo-vscode/webview-ui/src/context/vscode.tsx index 69d7a64ce96..a76c26c3a87 100644 --- a/packages/kilo-vscode/webview-ui/src/context/vscode.tsx +++ b/packages/kilo-vscode/webview-ui/src/context/vscode.tsx @@ -8,6 +8,7 @@ import type { VSCodeAPI, WebviewMessage, ExtensionMessage } from "../types/messa // Get the VS Code API (only available in webview context) let vscodeApi: VSCodeAPI | undefined +const EXPANDED = "modelSelectorExpanded" export function getVSCodeAPI(): VSCodeAPI { if (!vscodeApi) { @@ -33,6 +34,8 @@ interface VSCodeContextValue { onMessage: (handler: (message: ExtensionMessage) => void) => () => void getState: () => T | undefined setState: (state: T) => void + getModelSelectorExpanded: () => boolean + setModelSelectorExpanded: (value: boolean) => void } const VSCodeContext = createContext() @@ -64,6 +67,14 @@ export const VSCodeProvider: ParentComponent = (props) => { }, getState: () => api.getState() as T | undefined, setState: (state: T) => api.setState(state), + getModelSelectorExpanded: () => { + const state = api.getState() as Record | undefined + return state?.[EXPANDED] !== false + }, + setModelSelectorExpanded: (value: boolean) => { + const state = (api.getState() as Record | undefined) ?? {} + api.setState({ ...state, [EXPANDED]: value }) + }, } return {props.children}