Restore custom: false on the plan follow-up question — the "Type your own answer" row was redundant because the main prompt already routes typed text as a question reply. Auto-submit single-question single-select option picks in the VS Code QuestionDock so the button behaves like the TUI instead of silently waiting for a second Submit click.
* fix: persist custom provider model and variant deletions
The CLI config.update endpoint deep-merges its payload with existing
global config, so removing a model or reasoning variant from a custom
provider in the UI had no effect on disk. Save payloads now emit null
sentinels for removed IDs, and the Provider schema accepts nullable
record values so stripNulls can delete them during the merge.
Closes#9186
* chore: update kilo-vscode visual regression baselines
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* fix(vscode,ui): keep user scroll position while session is busy
Virtua's measurement-driven resize events race ahead of the debounced
user-scroll detection in createAutoScroll, snapping the viewport back
to the bottom while the user is mid-gesture. The QuestionDock's focus
call on mount also triggers the browser's focus-into-view behavior,
which yanks the view down whenever the user has scrolled up.
Fixes#9198
* fix(ui): guard recentlyInteracted against initial lastInteraction=0
Ensure Agent Manager pushes worktree session state before generic sessionCreated messages and reconciles local tabs against worktree ownership so forked, continued, and newly-created worktree sessions do not appear in Local. Fixes#8983.
Clicking 'revert file' in the Agent Manager review panel silently did
nothing when the repo had no remote and no tracking branch. The diff
view worked because it defensively searched for a local candidate
branch, but the revert path ran merge-base against the placeholder HEAD
and turned into a no-op for committed feature changes.
Lock in that a session with an open suggestion reports as idle (so reopening VS Code or switching worktrees does not show it stuck/running), that accepting flips it back to busy without an idle flash, and that a dismissed suggestion leaves it idle for the run loop to resume cleanly.
Move worktree-scoped gitdir construction, ACP guard logic, and diff
caching directly into the core snapshot service, eliminating the
separate kilocode/snapshot module. This reduces indirection and keeps
all snapshot concerns co-located in a single file.
* chore: untrack generated .kilo and .kilocode lockfiles
`kilo serve` regenerates `.kilo/package-lock.json` and `.kilocode/package-lock.json` (plus `node_modules/`) on every run -- see `Config.install` in `packages/opencode/src/config/config.ts:1406` -- but they were accidentally committed in the upstream alignment merge `7fb55e45f1`, so every run dirtied the working tree. Untrack them and add explicit root `.gitignore` rules so they stay ignored even if the per-directory `.gitignore` the CLI writes is removed. `.kilo/run-script` stays tracked -- it's a project dev helper, not a generated artifact.
* chore: rely on generated config dir ignores
The CLI already writes .gitignore files inside .kilo and .kilocode before installing config dependencies. Keep the PR focused on untracking the accidentally committed lockfiles instead of duplicating those generated ignore rules at the repo root.
If deriveAndSyncStatus hangs, the per-session promise chain would never
drain and map entries would accumulate. Wrap the derive with a 3s timeout
so stuck work fails fast, is logged, and the existing cleanup runs.
The suggest tool blocks on a promise that only resolves when the user accepts or dismisses a suggestion. While blocked, the runner stayed in Running state and the session status remained busy — if the suggestion was never answered (e.g. VS Code was closed), the session was stuck forever and follow-up prompts appeared queued.
Mark the session idle while awaiting the user's response; the loop will set it back to busy when the suggestion resolves and processing continues.
Fixes#9150
The fill() helper that repairs pages starting with an assistant turn
kept only the user-turn suffix of each older page, so earlier messages
fetched mid-stitch were dropped while the pagination cursor still
advanced past them. That made the top of the virtualized history land
after the real first message.
Keep the full older page when stitching partial turns so fill()
terminates naturally once a user message reaches the top, and add a
regression test covering multi-page fills.
* fix(vscode): keep queued messages pinned at the bottom
Queued follow-up user messages were being rendered inline inside the
conversation history, so tool output for an earlier turn could appear
under a later queued message. Render queued turns in a separate stack
beneath the virtualized history and group assistant messages by
parentID so late-arriving tool output stays attached to its turn.
* chore: update kilo-vscode visual regression baselines
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
The question tool's custom answer option showed the user's input twice — once as a preview description inside the option button, and again in the input field below. Hide the preview while the input form is open so only the live input is visible.
The prior spacing fix (#9025) relied on flex `gap` on `.message-list-content`,
but #8911 introduced virtua's `Virtualizer` which positions items absolutely
based on measured box size — so `gap` no longer applies between turns. The
missing spacing was most visible when the last assistant part was a sub-agent's
expanded task tool (two bordered boxes with 0px between them). Bake the 12px
into each turn's own padding so virtua measures it as part of the item height.
compaction.reserved only applies when a model declares a separate
input limit. For models with just a single context window, the reserve
is derived from the output cap instead.
Replaces the vague 'usableWindow' language with the real formula
(context_window - ~20K reserve), documents the /compact slash command
and task-header button, adds env-var overrides, and lists the correct
default values.