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:
<div className="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):
<button onClick={() => setView("summary")} aria-pressed={view === "summary"}
className="… w-8 sm:w-auto sm:px-2 …"><Eye size={14}/>
<span className="hidden sm:inline">Co-pilot</span></button>
<button onClick={() => 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.