VS Code Minimap: the canvas painter (2/4)
Part 2 of 4 of the VS Code Minimap. Land order: #25275 (setting), this PR (the painter), #25185 (the minimap), then #25280 (the placeholder looks). Stacked on #25275; review only its two commits (paint.ts and its test, +373).
Leo's words
minimap? i dont see any command for the vscode minimap
the mini map VS Code code thing ... Although I don't know if that actually, like, causes potential lag.
What this adds
webviews/src/agent-session/acpmux/chatMinimap/paint.ts draws the whole chat small into one canvas, from the transcript's existing layout (tops/heights). Nothing is measured, no text is drawn, and it never touches the DOM.
- Kinds: a prompt is a bar at the right, where its bubble sits. A reply is text-like lines at the left. A tool group is a narrower muted block.
- Bounded draws: each kind is one path and one fill, and rows on the same device pixel line merge. A draw is therefore bounded by the canvas's height, not by the number of rows.
- Scale: a short chat draws at 1/8 scale from the top, as VS Code does; a long one fits the track.
- Change check:
firstChangedRowlets the minimap skip a draw when no row moved.
The minimap that uses it lands in #25185.
Tests
Review fixes (gpt-6-astra), in the second commit. Each has a test that fails on the first commit:
- A streaming reply is never painted.
minimapKindgives a reply withrow.streamingno kind, so its place is always the minimap's placeholder and no caller repaints it per token. - Line jitter is seeded by the row's id, not its index, so rows inserted or removed above a reply leave its lines alone.
firstChangedRowcompares row ids and map kinds, so a same-shaped row swapped in, or a reply that stops streaming, repaints.streamingRowmoved here from #25185, keeping that PR under the size cap. It finds the live reply from the transcript'srowsChange: the rows before the first change are the last render's objects, so only changed rows are read, however many queued or late rows follow the reply. The same rows (a scroll frame) read nothing.
webviews/test/chat-minimap-paint.test.ts (new; it can't run on base, which has no painter):
- the row kinds and their mapping;
- the scale and the view box;
- a 20,000-row chat draws at most one rectangle per kind per device line, and fewer than 1.5Ć a 2,000-row one, always with 3 fills;
firstChangedRow.
Risk
None at runtime: nothing imports it until #25185.
Agent session: huge-blue
š¤ Generated with Claude Code