fix(cmux-next): New Tab keeps settled chats and machine name across workspace close/open

Closed
TE
16d ago
+266-10

Leo, 2026-10-18: "the jitter and re-reading configs that are already settled/couldn't have possibly changed when closing and opening workspaces needs to get fixed."

Opening a workspace this window hasn't shown yet mounts its New Tab page again, either cold or as an adopted spare (key={newTabGeneration}). Two things on that page started over every time:

  • The Chats list started empty and called chats.page on each mount. The rows then popped in and pushed the page down.
  • The machine chip read "This Mac" until the handshake answered, then flipped to the machine's name ("cosmic-gray").

Every agent page shares one website data store (AgentPaneView.sharedDataStore), so localStorage on that origin is effectively an app-run store. newtab/settledCache.ts keeps the All chats first page and this Mac's name there:

  • A page that mounts draws both on its first frame.
  • The list reads its first page again only when the chat index pushed a change (deviceChats) that no read on this page has taken in yet. A push counter records which push the stored page answers.
  • A cold page still gets the host's push on ready, and that push refreshes the list in place. The in-place refresh already keeps rows that haven't changed, so a refresh that finds nothing new changes nothing on screen.

The model, effort and permission chips already draw from localStorage caches (catalog.ts, chipMemory.ts, startMode.ts), so this PR leaves them alone. With agent.pageHost on (off by default), each page has its own store. That mode only gains the remount (adoption) case.

Testing

webviews/test/new-tab-settled-remount.test.tsx, committed red first (5dd5eb54), then green with the fix (851ff3e4):

  • After an unmount and remount, the list shows its rows before any reply, and the read count stays at 1. Red: no rows, and 3 reads where 2 were expected.
  • A push that arrives while no list is mounted is read once by the next list, over the rows it already shows.
  • The machine name is known before the next page's handshake.

bun test passes for the new file plus the all-chats and New Tab test files (81 pass). bun run typecheck and vp lint on the changed files are clean. I didn't run a tagged app build. I ran the full single-process bun test, but its 44 failures are cross-file pollution in areas this change doesn't touch, and my run didn't isolate a base comparison, so CI's web lane is the check for the rest.

Changelog

  • Fixed: Opening or closing a workspace no longer makes the New Tab page's Chats list and machine name blink in again.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes New Tab jitter when closing or opening a workspace: the Chats list and machine name no longer blink in on each remount.

Every agent page shares one website data store, so localStorage on that origin is an app-run store. A remounted New Tab page draws the settled All chats first page and this Mac's name on its first frame, and re-reads the first page only when the chat index pushed a change the page has not taken in yet. Only a New Tab page's handshake is remembered as this Mac's name; a remote chat's handshake names its own machine and is never stored, and only New Tab chips fall back to the cached name.

Testing

webviews/test/new-tab-settled-remount.test.tsx covers the remount, a push arriving while no list is mounted, and the cached machine name.