Repository navigation
perf: cut the mobile app's data usage - #338
Open
honzasladek wants to merge 12 commits into
Open
honzasladek wants to merge 12 commits into
honzasladek wants to merge 12 commits into
Conversation
A full /v1/state runs to hundreds of KB and remote clients refetch it on every state change; JSON compresses about 7x. Compression is per route so downloads and the WebSocket upgrade keep their raw bodies. The transport client accepts gzip except over the local Unix socket. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The phone subscribed to the PTY output of every terminal, also on the dashboard and in the background, while it shows at most one. The transport gains a stream filter that survives reconnects; the mobile app starts with nothing streamed and streams the selected terminal only. Connection liveness now counts any inbound frame instead of terminal output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A session refetches the whole /v1/state on every state_changed. Clients can now set a minimum interval between fetches (changes inside it are coalesced), defer fetches entirely (an app in the background) and skip the settings fetch. The default keeps the old behaviour. The client also counts received payload bytes by kind. The state is fetched with transparent decompression off and decoded by hand, so its count is the size on the wire. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The phone fetches the workspace state at most once a second, not at all in the background (also while the Android connection service keeps the session open) and no longer fetches settings it never used. Settings gains a Data section with what the connection has downloaded, by kind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Git status already reaches clients as its own git_status_changed push, which the desktop and mobile clients patch into their copy of the state. The extra state_version bump made every client refetch the whole state on each git change. The web client now applies git_status_changed too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server pushes system_stats_changed every 2 s to every client. A client that shows no host metrics can now send set_system_stats with enabled: false; the mobile app does. Clients keeping the default never send the message, so older servers are unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clients that stream only some terminals (the mobile app streams the one on screen) could no longer see bells and OSC 9/777 notifications of the rest. The daemon now stamps both edges on the terminal and sends them in StateResponse.terminal_attention. The mobile app raises a terminal's unseen flag when its stamp moved between two states, so it never compares the server's clock with its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # crates/okena-app-core/src/remote_snapshot.rs # crates/okena-cli/src/resolve.rs # crates/okena-core/src/api.rs # crates/okena-daemon-core/src/command_loop.rs # crates/okena-mobile-ffi/src/client/manager.rs # crates/okena-transport/src/client/connection.rs # crates/okena-transport/src/client/state.rs # crates/okena-workspace/src/remote_apply.rs # crates/okena-workspace/src/state.rs
The server hands out a fresh stream id per Subscribe. When a terminal was subscribed, unsubscribed and subscribed again before the first reply arrived, that reply installed the dropped id and input sent on it was lost until the second reply. The session now counts outstanding Subscribes per terminal and applies only the reply to the latest one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Git changes no longer trigger a state refetch, so a /v1/state response that was in flight when git_status_changed arrived could overwrite the newer git status until the next git change. The web client now keeps the last pushed map and applies it over every state response of the connection. Also document why the phone's dashboard git counts can lag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- mobile: resume state fetches on every return to active; iOS can go background → inactive → active, which left the deferral on and froze the workspace state. - mobile-ffi: do not raise attention stamps for streamed terminals; their bells arrive in the output and were already marked seen. - web: a state response newer than the last git push keeps the status of projects the push does not list (added since). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The connection dot keyed on 3/10 s, but with one streamed terminal and no host metrics a quiet connection only receives the pong to the 15 s ping, so a healthy connection cycled to red. Thresholds are now 20/45 s. - A bell seen on screen right before switching away came back as unseen from the next state's stamp. The holder now records bells and notifications from its own output since the last state, and the stamp skips those, replacing the check of the current stream set. - iOS `inactive` (Control Center, alerts, Face ID) counts as foreground, so the terminal no longer resubscribes with a fresh snapshot. - Document that off-screen bells need a daemon that sends the stamps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous change made iOS `inactive` count as foreground so the terminal keeps streaming under Control Center or Face ID, but the same check marks the terminal on screen seen. A bell or a finished agent during Notification Center or the app switcher was acknowledged unseen. Streaming now stops only in the background; seen still needs `active`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mobile app used a lot of cellular data. It subscribed to the PTY output of every terminal (also on the dashboard and in the background, where the Android connection service keeps the session open), and refetched the whole
/v1/statesnapshot uncompressed on everystate_changed. A workspace with ~200 projects has a snapshot of ~235 KB.Mobile (works against current servers)
RemoteClient::set_streamed_terminals) that survives reconnects. The app starts with nothing streamed and streams the selected terminal; none on the dashboard, in the background or after polling stops. A terminal that streams again gets a fresh snapshot.StateSyncPolicy: a minimum interval between fetches (the app uses 1 s; changes inside it become one fetch, the first change after a quiet window fetches at once), deferral while the app is in the background (one fetch on return), and no settings fetch, which the app never used. The desktop keeps the default policy.Server (needs a desktop release)
/v1/state,/v1/actions, usage, Claude session/transcript), per route so downloads and the WebSocket upgrade keep raw bodies. Not used over the local Unix socket. The snapshot above goes to ~32 KB.state_version. It already has its owngit_status_changedpush, which the desktop and mobile clients patch into their state; the bump made every client refetch the whole snapshot on each git change. The web client now appliesgit_status_changedas well.set_system_stats: a client can opt out of the 2 ssystem_stats_changedpush. The app does. Clients keeping the default never send it, so older servers are unaffected.terminal_attentioninStateResponse: the last bell / OSC 9/777 notification time per terminal. Since the app no longer streams most terminals, it raises a terminal's unseen flag when its stamp moved between two states (no clock comparison; the first state is the baseline).Compatibility
set_system_statswith aninvalid messageerror, which the app only logs; no attention stamps, so bells of terminals off screen are not flagged until the server is updated.Known trade-off
The output-based "running" dot for terminals that are not on screen is gone on mobile. Agent status covers agents; plain shells running a build no longer show as running.
Test plan
cargo testfor core, terminal, daemon-core, remote-server, transport, mobile-ffi, workspace, app-core, clitsc -b🤖 Generated with Claude Code