Reported
"In the tmux coding agent, on mobile I can't see terminal output. It shows the terminal selector
and everything on one screen."
What the layout does on a phone
TmuxTab.tsx:246 is a two-column grid that degrades to a single column:
<divclassName="flex-1 min-h-0 grid grid-cols-1 lg:grid-cols-[17rem_minmax(0,1fr)]"><aside…>{/* target list */}<section…>{/* header · status · OUTPUT · command · send-keys · create-target */}Below lg, those stack, so the screen becomes eight blocks in a column:
| block | mobile height |
|---|
| 1 | aside header — "Terminal" + refresh | fixed |
| 2 | target list | auto — grows with target count |
| 3 | section header — name, attached pill, 3 icon buttons | fixed |
| 4 | status / permission line | fixed |
| 5 | <pre> output | flex-1 — the only block that yields |
| 6 | command row — input + Run | fixed |
| 7 | send-keys row | grid-cols-1 → 2 stacked full-width inputs |
| 8 | create-target row | grid-cols-1 → 3 stacked full-width inputs + button |
Rows 7 and 8 are the aggravating factor and they are aggravating because of the responsive rule.
grid-cols-1 sm:grid-cols-[…] means the compact toolbars that fit on one line at sm become
five stacked full-width inputs below it. Every one of them is fixed-height. The output pane is
the single flex-1 element in the column, so it absorbs the entire deficit and collapses to a
sliver — on the tab whose whole purpose is reading terminal output.
This repo already solved this, one directory away
agents/coder/web/src/CodingTab.tsx renders a terminal on the same phone and does not have this
problem, because it switches views instead of stacking them (:831-832):
<buttononClick={()=>setView("summary")}aria-pressed={view==="summary"}className="… w-8 sm:w-auto sm:px-2 …"><Eyesize={14}/><spanclassName="hidden sm:inline">Co-pilot</span></button><buttononClick={()=>setView("terminal")}aria-pressed={view ==="terminal"}…>Backed by one piece of state — const [view, setView] = useState<"summary" | "terminal"> (:83).
The same file also collapses its chrome on mobile rather than stacking it: the repo title truncates
to max-w-[5.75rem] sm:max-w-[11rem], the repo switcher becomes a dropdown, and Settings folds into
a session menu (sm:hidden).
So the pattern, the ARIA treatment and the icon-only-on-mobile convention all already exist in the
codebase. TmuxTab predates them or missed them.
Proposal — reuse the idiom, do not invent a new one
Add a mobile-only segmented view to TmuxTab with the same shape as CodingTab's:
- Targets — the
aside list (currently block 1–2) - Output — the
<pre>, given the full remaining height (block 3–5), the default - Controls — command, send-keys, create-target (blocks 6–8)
Above lg, keep today's two-column layout unchanged — it is fine there, and the controls belong
under the output on a wide screen.
Two details worth copying rather than re-deciding:
- Icon-only below
sm, label from sm up (w-8 sm:w-auto sm:px-2 + hidden sm:inline), so the
switch itself does not become the thing eating the viewport. aria-pressed on each button, not a role="tablist". CodingTab already made this choice and
the console's other switch of this kind (the interaction-mode control in InstanceDetail) uses a
role="radiogroup" with sr-only radios. Matching one of the two existing treatments matters more
than which; picking a third would be the actual regression.
Note for #366
This would be the fourth segmented control in the console — interaction mode (InstanceDetail,
role="radiogroup"), Co-pilot/Terminal (CodingTab, aria-pressed), the delivery-status chips
(TeamworkSection), and now this. Three of them already disagree about markup and ARIA. That is the
case for the shared primitive in #366, and this ticket should not wait for it — copy CodingTab's
version now, and let #366 collapse all four later.
Reported
What the layout does on a phone
TmuxTab.tsx:246is a two-column grid that degrades to a single column:Below
lg, those stack, so the screen becomes eight blocks in a column:asideheader — "Terminal" + refreshsectionheader — name, attached pill, 3 icon buttons<pre>outputflex-1— the only block that yieldsgrid-cols-1→ 2 stacked full-width inputsgrid-cols-1→ 3 stacked full-width inputs + buttonRows 7 and 8 are the aggravating factor and they are aggravating because of the responsive rule.
grid-cols-1 sm:grid-cols-[…]means the compact toolbars that fit on one line atsmbecomefive stacked full-width inputs below it. Every one of them is fixed-height. The output pane is
the single
flex-1element in the column, so it absorbs the entire deficit and collapses to asliver — on the tab whose whole purpose is reading terminal output.
This repo already solved this, one directory away
agents/coder/web/src/CodingTab.tsxrenders a terminal on the same phone and does not have thisproblem, because it switches views instead of stacking them (
:831-832):Backed by one piece of state —
const [view, setView] = useState<"summary" | "terminal">(:83).The same file also collapses its chrome on mobile rather than stacking it: the repo title truncates
to
max-w-[5.75rem] sm:max-w-[11rem], the repo switcher becomes a dropdown, and Settings folds intoa session menu (
sm:hidden).So the pattern, the ARIA treatment and the icon-only-on-mobile convention all already exist in the
codebase. TmuxTab predates them or missed them.
Proposal — reuse the idiom, do not invent a new one
Add a mobile-only segmented view to TmuxTab with the same shape as CodingTab's:
asidelist (currently block 1–2)<pre>, given the full remaining height (block 3–5), the defaultAbove
lg, keep today's two-column layout unchanged — it is fine there, and the controls belongunder the output on a wide screen.
Two details worth copying rather than re-deciding:
sm, label fromsmup (w-8 sm:w-auto sm:px-2+hidden sm:inline), so theswitch itself does not become the thing eating the viewport.
aria-pressedon each button, not arole="tablist". CodingTab already made this choice andthe console's other switch of this kind (the interaction-mode control in
InstanceDetail) uses arole="radiogroup"withsr-onlyradios. Matching one of the two existing treatments matters morethan which; picking a third would be the actual regression.
Note for #366
This would be the fourth segmented control in the console — interaction mode (
InstanceDetail,role="radiogroup"), Co-pilot/Terminal (CodingTab,aria-pressed), the delivery-status chips(
TeamworkSection), and now this. Three of them already disagree about markup and ARIA. That is thecase for the shared primitive in #366, and this ticket should not wait for it — copy CodingTab's
version now, and let #366 collapse all four later.