iOS: read a paged acpmux session list whole

Merged
TE
5d ago
+208-4

Problem

With #28182, acpmux answers _acpmux/watch and _acpmux/sessions with no limit in byte-bounded pages when the whole list is past its largest reply (~14 MiB): the first rows and a string nextCursor, with the rest read by _acpmux/sessions {cursor, ...}. One daemon's list was 17 MB with tools, so older daemons refused it as message.too_large. The iPhone app reads only watched["sessions"] from one reply. On a Mac with a list that size it would see only the first page. Pull to refresh also resolves the open asks of every session missing from the list as "Answered".

What changed

  • AcpmuxConnection.wholeList(_:_:) (CmuxMobileLive) sends a list call with no limit. While a page names a nextCursor, it reads the next page with _acpmux/sessions and the same params minus enabled, then joins sessions. This is the Swift form of acpmux's Client::whole_list (#28182) and the TS SessionPager.whole() (#28272). A list that fits is one reply with no cursor, so an older daemon is read as before.
  • A cursor sent twice throws RPCError (sessions.cursor_repeated) instead of looping, and never hands back a list cut short, because the Feed reads a missing session as a gone one. A page with no rows ends the list, as in the TS pager.
  • AcpmuxHub.bind and LiveFeed.refresh read _acpmux/watch through it (AcpmuxHub.wholeList forwards to the current connection). These are the only iOS reads of the session list with no limit.
  • Left as they are: the Chats list (LiveAgentChats) already pages with limit and cursor. The _acpmux/lagged re-watch only turns the watch back on and discards the reply.

Tests

The test commit comes first; the fix follows.

  • AcpmuxWholeListTests: two pages are read whole, and the second request carries the cursor and the filter but no enabled. A list that fits is one request. A repeated cursor throws after exactly one _acpmux/sessions request. A page with no rows ends the list.
  • FeedRefreshTests.bindAndRefreshFollowTheWatchCursor: the hub's bind and a pull to refresh both see the session from the second page.

Command: swift test --filter 'AcpmuxWholeListTests|FeedRefreshTests' in cmux-next-ios/CmuxMobileKit, run on the fleet. On the base, AcpmuxWholeListTests does not compile (no wholeList) and the bind/refresh test sees only s1.

No capture: no UI change.

Observed / Not run

  • Ran: ./scripts/lint-ios-package-conventions.sh --namespace-fix (no violations) and python3 scripts/cmux-next/prepush-gate.py (no new violations).
  • Not run: no Swift compile and no test run. The host that wrote this has no Swift toolchain, so the compile and both suites are left to this PR's fleet CI. The red on the base described above is from reading the code; I did not run it.

Changelog

  • Fixed: The iPhone app shows every agent session of a Mac whose session list is too large for one message, instead of failing or showing only part of it.

Agent session: agent session

šŸ¤– Generated with Claude Code