Repository navigation
Chat view: read and reply to a live agent session from a phone, no terminal required #133
Description
Why
The phone terminal is the weakest part of flue's mobile story. Forty columns, TUI redraws, a keyboard that fights the viewport, and a key bar standing in for Esc and arrows. It works, and it is the wrong shape: an agent session is a conversation, and a conversation on a phone wants to look like one.
Half of this exists. The agent transcripts are on disk, internal/agentstore indexes all three tools, and the agent viewer (#74) already renders a transcript as messages with paging and a follow mode. What is missing is the other half: knowing which transcript a live session is writing, and a way to reply. flue does not need a vendor API for any of it, because the pty is the input channel.
Happy Coder and Claude Code's own remote control show the shape that wins on a phone: messages, a composer, approve buttons. flue can have it across every machine and every agent, with the real terminal one tap away.
Rough scope
- Link the live session to its transcript. Today the link is a guess made once, at shutdown, in
internal/session/snapshot.go. It needs to be live:InfogainsagentandagentSession, kept current by the agent hooks issue (Agent hooks: let Claude Code, Codex and Pi tell flue when a session needs you, finished, or wants a permission #132) when hooks are installed and by cwd plus newest-transcript matching otherwise. - A view toggle on the session screen: Chat | Terminal. Mobile defaults to Chat when the session has an agent, desktop defaults to Terminal. The mobile tab strip from Multiplex inside a session: splits on desktop, tabs on mobile, and a double-Ctrl scratch terminal #73 is the natural home. Remember the choice per device. The terminal is never more than one tap away, and anything the chat view cannot render says so and offers the terminal.
- Read. Reuse the viewer's paging and virtualized list. Follow needs to be faster than the viewer's 5 second poll: the daemon watches the transcript file and pushes new messages over the existing wire. Transcripts only land on completed messages, so "agent is working" comes from terminal activity and the hooks state, not from the file.
- Write. A composer at the bottom. Send writes the text and Enter into the pty through the existing input path. Uses the session state from the agent hooks issue (Agent hooks: let Claude Code, Codex and Pi tell flue when a session needs you, finished, or wants a permission #132) and Needs-you queue: fleet-wide list of sessions blocked on a prompt #110 so a message sent while the agent is running shows as queued rather than vanishing into a tool's stdin.
- Prompts as buttons. Permission prompts,
AskUserQuestion, and plan approval render as tappable options. Two sources: the permission relay in the agent hooks issue (Agent hooks: let Claude Code, Codex and Pi tell flue when a session needs you, finished, or wants a permission #132) (exact, Claude first) and, as a fallback, the options parsed off the terminal screen. When neither can render a prompt, the view shows a "needs the terminal" chip that opens it. - A few chips, not a keyboard. Interrupt (Esc), and the two or three slash commands people reach for. Everything else is the terminal.
Notes
- Same wire, same relay. Nothing here adds an HTTP surface; a phone on a relay origin gets the same view as the loopback tab.
- Thinking blocks and tool calls collapse by default the way the viewer does. Tool results are capped per message on the wire already.
- Attaching a photo from the phone (Claude and Codex accept image paths) is tempting and is not v1.
- Sequencing: needs the live agent link first, then read, then write, then prompts. Read plus write is already a better phone than the terminal; prompts as buttons is what makes it complete. Pairs with the composer (Session composer: start agent sessions from any device #112) for starting a session from the phone, and with the session card (Session card: what a session did while you were away, from facts flue already has (no model) #134) for opening one cold.
Where to look
web/src/routes/agent-viewer.tsx(paging, follow, virtualization, resume),web/src/agents/view.tsinternal/agentstore/read.go(pages),internal/agentstore/types.go(Message,Page)web/src/components/terminal.tsxandweb/src/components/key-bar.tsx(the input path and the mobile affordances this view replaces)web/src/sessions/pane-tree.tsand the Multiplex inside a session: splits on desktop, tabs on mobile, and a double-Ctrl scratch terminal #73 tab strip (where the toggle lives)internal/session/snapshot.go:215(SnapshotForShutdown, the one-shot agent guess)
Activity