Summary
Mobile browsers are not reliable long-lived clients. Backgrounding Chrome/Samsung Internet can freeze or discard the page, suspend timers, and drop WebSocket connections. agent-frontend should therefore be designed around recoverable sessions, not around keeping one connection alive forever.
This is important because the same class of problem already appears when using OMP directly from Termux: after background/resume, resize, or reconnect, the UI may redraw from the wrong place, scroll back to the top, or otherwise lose the user's viewing state. A browser frontend gives us better control over UI state than a terminal TUI, but only if reconnect is treated as a normal lifecycle event.
Design principle
Do not model the browser/WebSocket as the agent session.
Wrong:
WebSocket = OMP session
WebSocket closed = session lost
Preferred:
OMP session = durable host-side state
Browser = attachable/disposable client
WebSocket = temporary transport
The goal is not "never disconnect". On mobile that is unrealistic.
The goal is:
disconnects may happen at any time, but the user should lose neither work nor UI context.
Expected behavior
When the mobile browser is backgrounded, frozen, reloaded, or its WebSocket is dropped:
- The underlying OMP/agent session keeps running on the host.
- The browser reconnects to the same session.
- Missed output/tool events are replayed or the current transcript is resynchronized.
- The previous viewing position is restored.
- Draft input is preserved where possible.
- If the user was following the latest output, the UI resumes at the tail.
- If the user was reading older output, new output must not force-scroll them away from that position.
Suggested state model
Host/bridge should own durable session state such as:
session_id
event_seq
transcript
running jobs / tool state
The client should keep lightweight view state such as:
session_id
last_received_seq
scroll_anchor
draft
follow_tail
Reconnect can then look roughly like:
connect(session_id, after=last_received_seq)
↓
replay missed events / resync transcript
↓
restore scroll anchor
For scroll restoration, prefer a message-based anchor over a raw pixel offset, e.g. message_id + local offset. Pixel-only restoration becomes fragile when streamed content changes height.
Mobile-specific requirements
- Treat
visibilitychange, page freeze/discard, reload, network transition, and WebSocket loss as normal conditions.
- Persist enough client state before the page becomes hidden to restore the session after process death/reload.
- Do not assume
beforeunload will run.
- Reconnect should be idempotent and safe after partial event delivery.
- Duplicate events after reconnect must not duplicate messages/tool results in the UI.
- Soft-keyboard resize should not destroy scroll position.
Why this belongs in agent-frontend
agent-terminal / ttyd remains useful as a raw terminal escape hatch, but it inherits terminal scrollback, PTY resize, and TUI redraw limitations.
agent-frontend can do better because it owns the DOM, transcript model, composer, scroll state, and reconnect behavior directly. This should be one of the main reasons to prefer the frontend on phones/tablets.
A useful product hierarchy would be:
agent-frontend → primary mobile agent UX
agent-terminal → raw shell / recovery / debugging
collab/session sharing → sharing layer
Acceptance criteria
Non-goal
Keeping a mobile browser WebSocket alive indefinitely. The frontend should remain correct even when the connection is routinely destroyed and recreated.
Summary
Mobile browsers are not reliable long-lived clients. Backgrounding Chrome/Samsung Internet can freeze or discard the page, suspend timers, and drop WebSocket connections.
agent-frontendshould therefore be designed around recoverable sessions, not around keeping one connection alive forever.This is important because the same class of problem already appears when using OMP directly from Termux: after background/resume, resize, or reconnect, the UI may redraw from the wrong place, scroll back to the top, or otherwise lose the user's viewing state. A browser frontend gives us better control over UI state than a terminal TUI, but only if reconnect is treated as a normal lifecycle event.
Design principle
Do not model the browser/WebSocket as the agent session.
The goal is not "never disconnect". On mobile that is unrealistic.
The goal is:
Expected behavior
When the mobile browser is backgrounded, frozen, reloaded, or its WebSocket is dropped:
Suggested state model
Host/bridge should own durable session state such as:
The client should keep lightweight view state such as:
Reconnect can then look roughly like:
For scroll restoration, prefer a message-based anchor over a raw pixel offset, e.g.
message_id + local offset. Pixel-only restoration becomes fragile when streamed content changes height.Mobile-specific requirements
visibilitychange, page freeze/discard, reload, network transition, and WebSocket loss as normal conditions.beforeunloadwill run.Why this belongs in
agent-frontendagent-terminal/ ttyd remains useful as a raw terminal escape hatch, but it inherits terminal scrollback, PTY resize, and TUI redraw limitations.agent-frontendcan do better because it owns the DOM, transcript model, composer, scroll state, and reconnect behavior directly. This should be one of the main reasons to prefer the frontend on phones/tablets.A useful product hierarchy would be:
Acceptance criteria
Non-goal
Keeping a mobile browser WebSocket alive indefinitely. The frontend should remain correct even when the connection is routinely destroyed and recreated.