agent pane: open a chat after the newest page of the session list (cx-2lv1k)
cx-2lv1k, Leo's paging addendum (2): one paged, cursor-based fetch for the session lists.
What changes
- Today the agent pane downloads the whole session list (
_acpmux/watch) before it opens its chat. With 1,200 sessions on a remote link that is about 800 KB before the first transcript event. - Now the pane asks
_acpmux/watchfor the newest 200 sessions, opens its chat, and reads the rest behind it with_acpmux/sessionscursors. These are the keyset pages from #20628, which neither repeat nor skip a session that moves meanwhile. - The list still ends up whole: the composer's projects, the model picker, links to old chats and automation all read every session.
- A session purged, or changed, while a later page is on its way keeps its newer state. A link to a chat on a late page reads on before calling it missing. A lagged watch rereads in pages and swaps the list in at once.
- A page that fails falls back to the whole list at once. A daemon without paging ignores
limitand answers the whole list, as before. - Chats (All Chats, History) were already cursor-paged through
AllChatsList. Recently Closed is pushed by the host and capped.
New module sessionPages.ts; direct.ts uses it at its two list reads and in the purge handler.
Evidence
webviews/test/agent-pane-session-pages.test.ts runs the real pane in Chromium against a stand-in daemon that holds 1,200 sessions of about 600 bytes each and honors limit/cursor. Later pages are held while a purge and a change race them.
| bytes the daemon sent before the chat's first events | |
|---|---|
| base | 805,740 |
| head | 134,603 (budget 160 KiB) |
- Red at a6ce23c6176d5:
Expected: <= 163840, Received: 805740. - Green at 3255c088fb9bd, run on the private builder. The test also checks the final list: every session once, the purged one gone, the changed one's newer title kept, and a late-page link opening its chat.
- Mutation check: with the purge bookkeeping removed, the test fails (1,200 sessions instead of 1,199).
tscis clean.vp fmt --checkandvp lintare clean on the changed files.- Every
agent-pane-*browser test passes except the 3 first-paint CSP tests, which need a built bundle.
Known base reds, not from this PR: bun run check formatting, ui-rules and gallery-coverage all fail on files under pages/home-channels/ (from a95f31ab8c5f4, reported). The bundle and first-paint tests check build output.
This PR needs #20628 merged first: without it, the daemon ignores limit and the pane behaves as before.
Changelog
- Changed: chats open sooner when a daemon holds many sessions; the session list loads in pages behind the open chat.
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Opens a chat after the newest page of the session list instead of after the whole list. The agent pane previously downloaded every session via _acpmux/watch before its first transcript event; now it asks for the newest 200, opens the chat, and reads the rest behind it with cursors.
- Adds
sessionPages.ts, used at both list reads and the purge handler indirect.ts; the list still ends up whole for the composer, picker, and links to old chats. - A session purged or changed while a page loads keeps its newer state; a failing page falls back to the whole list.
- With 1,200 sessions the daemon sends about 134 KB instead of 805 KB before the chat's first events.
- The merge brings in a formatting-only
vp fmtpass acrosswebviews/src/pages/home-channels/, resolving a conflict inHomeChannelsPage.tsx. - The merge also routes
cmux-tuimacOS dogfood builds and daemon tests offblacksmith-12vcpu-macos-26, the nightly build's label; a new guard test evaluates every runner route. - Depends on #20628; without it the daemon ignores
limitand the pane behaves as before.