Skip to content

[bug] Terminal output is invisible on mobile — TmuxTab stacks eight blocks in one column and the output pane is the only one that yields #370

Description

@serge-ivo

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-1the 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfrontendFrontend / UI work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions