feat(mobile): terminal-first — delete chat stacks, terminals as sessions, agent launch from home
The terminal-first pivot lands: both mobile chat surfaces are deleted, terminals become the session rows, and the home widget launches terminal agents. Stacked on #6356 (native composer) → #6342 (terminal screen); merges main, so it carries #6340's per-user relay resolution (every dial resolves relay2 for flagged users) and the #6341 terminal.list rename.
Deleted (~3k LOC, mobile-side only — host-service chat/ACP routers untouched)
- ACP chat stack (
chat/acp/[sessionId], 25 files) and the dead legacy Mastra stack (chat/[sessionId], 16 files), their routes and layout entries. lib/trpc/host-chat-types.ts(the lossy hand-typed facade) +lib/trpc/host-client.ts(4 fps polling transport) — both documented INTERIM debts.- Mobile ACP client binding,
SessionRowchat UI + fork stub +ClaudeLogohardcode,useHostAcpSessions, the unusedtab-barnative module.
Replaced with
- Home rows = live terminals (
terminal.list, host-wide per host) left-joined with agent bindings (terminalAgents.list) — agent mark + status when an agent is attached, plain shell rows otherwise. Tapping opens the terminal screen. - NewChatWidget launches terminal agents. Existing workspaces:
terminalAgents.findActive→terminal.sendinto a live agent terminal, elseagents.run. New workspaces:workspaces.createwith the agent sugar. Voice dictation and target chips unchanged; the model picker is replaced by an agent picker (see below). - Finish-review handoff launches/reuses a terminal agent the same way.
Fix found during E2E
The first re-plumb called terminalAgents.getOrCreate bare — which spawns a plain shell and waits for an agent that nothing launched (10s timeout, terminal disposed). The launch responsibility belongs to agents.run; the hook now uses findActive→send / agents.run, matching desktop semantics.
Workspace = tabbed terminal shell (final cut on this branch)
WorkspaceScreenis the terminal now: tab strip (agent mark + name, attention dots, long-press to close) + one liveTerminalWebViewkeyed by the active tab + the glassTerminalComposer. The session-list screen is deleted; home rows land directly on a tab viaworkspace/[id]?tab=, andterminal/[terminalId]redirects there for old links.- The tab strip's
+opens a native action sheet of the host'ssettings.agentConfigspresets (launched viaagents.runwith an empty prompt — host-side refine relaxed for terminal agents) plus a plain Shell (terminal.createSession). new-chat/routes renamednew-session/; the model picker became an agent picker over the target host's configs. The persisted preference is thepresetId(portable across hosts), not the per-host row UUID.settings/presets: read-only per-host listing of agent presets; editing stays on desktop.- Compact header: workspace name (pressable → bottom action sheet) + top-right glass Review pill with +/− changeset stats.
Verified E2E on iOS 26.5 simulator against prod
- Home renders terminal-first; tapping a session row lands on the tabbed shell with the live claude stream.
- Composer: type → send → claude responded on-screen; composer rides above the keyboard.
+sheet listed the host's real presets (Claude, Amp, Codex, Gemini, Copilot) + Shell; Shell launched in the workspace's worktree and became the active tab; tab switch re-attached the claude stream; long-press → Close killed the session and the strip updated.- Agent picker showed the target host's configs with marks and the persisted selection checked.
- Repo typecheck and lint clean.
Dogfooding polish batch (day 2)
- Home is a flat workspace list — nested session rows folded into an overlapping agent-mark stack per row; desktop
WorkspaceIconsemantics in the leading slot (brailleAsciiSpinnerwhile working beats the PR icon, corner ping overlays for permission/failed,FolderGit2when idle); PR icon routes to the in-app Changes screen. - Desktop's notification model, whole —
review(green, unseen Stop) derived against a persisted host-clock monotonic seen map, cleared by viewing the tab;failedjoins the set; rollups useSTATUS_PRIORITY; dot colors matchStatusIndicator, with theanimate-pinghalo ported to reanimated. - Perf: in-page terminal switching — one WebView per shell; tab switches send a
switchmessage (generation-counter guarded) instead of remounting, keeping the 400KB xterm parse and TLS pool warm. Also a guard dropping NaN-corrupted SGR mouse reports that leaked asaN;NaNM…input spam. - Sheets — new-session preset menu is a native formSheet (ActionSheetIOS renders as a centered dialog on iOS 26); workspace sheet is Cursor's layout (centered name, circular edit/pin/share, Info list with project logo, Delete at bottom). Pin is a device-local
pinnedAtmap floating pins to the top of home. - iOS 26 header/tabs — no glass-in-glass Review pill (icon-only
Stack.Toolbar.Buttonnow), title width fits the floating bar items, tab strip is square chips with a+that opens the sheet; tabs hold creation order instead of re-sorting by activity mid-session. - Fixes from the fresh-session gym test — quick keys were dead (glass Host's oversized invisible frame swallowed chip taps;
z-10fix, verified with add|xxdbyte probe), home composer always launches a new session (thefindActivereuse path contradicted the "New agent in …" label), and workspace share links go through one env-based helper (/workspaces/<id>kept canonical — web side tracked in SUPER-1846). - Agent brand marks ship as PNGs rendered from desktop's preset-icons catalog (all 15 presets, composer/tabs/picker/settings);
@gorhom/bottom-sheetremoved (last consumer was dead chat-era code).
Notes for review
chat_sessionsElectric collection consumers are gone from mobile; the cloud rows remain (desktop still writes them) — coordinate final removal with #6328.- Snapshot previews on home rows and push notifications on agent transitions are the next items in the plan, not in this PR.
- Composer input stays expo-ui SwiftUI for now; a fully-native spike is ticketed as SUPER-1849.
Summary by cubic
Makes mobile terminal-first: deletes chat stacks, turns Workspace into a tabbed terminal shell, and launches agents from Home or a New session sheet. Share links now use an env-based helper, with EXPO_PUBLIC_WEB_URL defaulting to https://app.superset.sh.
- Workspace: tabbed terminal shell with one live WebView and in-page tab switching; “+” launches host
settings.agentConfigsor a plain shell; compact header with an icon-only Review button; stable tab order; drops NaN-corrupted wheel reports. - Home: flat workspace list with stacked agent marks and pinging attention dots; defaults to the most recently active project; native cell highlight and context‑menu lift; PR icon opens in‑app Changes; device‑local pins float to the top.
- New session and agents:
new-chat/*→new-session/*; model picker → Agent picker; selectedagentIdpersists across hosts; read‑only presets atsettings/presets; agent brand marks bundled viaexpo-asset; Home composer always runs a fresh agent viaagents.runand returns to the shell with the new tab active. - Host access: overlays
_whoownstunnel probes onv2_hosts.is_online; routes all host calls through the per‑user relay URL (typed clients inlib/host-service/client). - Removals: delete ACP and legacy chat stacks, the mobile
@superset/host-clientbinding and chat types, the chat‑era model selector,@superset/tab-bar, and@gorhom/bottom-sheet. - Links: share links use
workspaceShareUrlonEXPO_PUBLIC_WEB_URL;/workspaces/<id>stays canonical; the legacy terminal redirect route is removed.
Migration
- Update links from
/new-chat/*to/new-session/*; deep links should target/workspace/[id]?tab=<terminalId>. - Remove usages of deleted packages and routes:
@superset/host-client,@superset/tab-bar,@gorhom/bottom-sheet. - Install/pin deps: add
react-native-webview,@xterm/xterm,@xterm/addon-fit,expo-asset, and pinexpo-fontto56.0.5.
Summary by CodeRabbit
-
New Features
- Added live terminal tabs with session switching, creation, closing, connection status, retry controls, input, and quick keys.
- Added agent selection when starting a new session, with persisted preferences.
- Added workspace actions for renaming, sharing, copying IDs, and deleting eligible workspaces.
- Added read-only agent presets in Settings.
- Added terminal deep-link routing and improved workspace session indicators.
-
Updates
- Workspace views now prioritize terminal sessions instead of chat threads.