cx-wtndw acpmux: All Chats pages after the last chat, not an offset
cx-wtndw. This is part of Leo's 10-14 ask for cursor-based paging on every unbounded list that crosses the daemon/server boundary. This slice covers All Chats.
What changes
Before this change, _acpmux/chats returned an offset as nextCursor. While the reader scrolled All Chats, the list kept changing:
- a chat that moved to the top made the next page repeat a row;
- a chat that left made the next page skip one.
Now the cursor names the page's last chat: k<updatedMs hex>.<FNV-1a of the key>, at most 29 characters. The app's bridge passes at most 32, so no client changes. The next page starts right after that chat. If that chat is gone or has moved, the page starts at the first chat no newer than it was: a chat from that same millisecond may repeat, but none is skipped. A bare number is still read as an offset, so a page already in flight keeps working.
Evidence
tests/chats_deltas.rs a_page_cursor_holds_its_place_while_chats_move has 30 chats, with file times one second apart; a Claude chat's time is its file's. It takes page one, moves chat 5 to the top and removes chats 24 and 25, then checks that pages two and three are exactly the rest.
- Red at b839e7c1f743c: page two starts at chat 18, because the offset skipped chat 19.
- Green at 6357e35eeec9e:
cargo test -p acpmux --test chats_deltas --test chatspasses, 12 tests. - Both runs were on the private Linux builder.
Review follow-ups:
- A store time out of range is clamped the same way where the cursor is built and where it is looked up. Before this, a negative time could stall paging, and a huge time could push the cursor past 32 characters.
- The CLI's "more" hint prints a count again, not the cursor.
crash_ratchet.py passes.
Changelog
- Fixed: scrolling All Chats while chats change no longer repeats or skips a chat.
🤖 Generated with Claude Code