[FEATURE] Make the markdown-table → Header:-value list fallback configurable

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Jul 31, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)
Prior art: this was requested in #68839 (2026-06-16, enhancement / area:tui / area:a11y), which the stale bot auto-closed as NOT_PLANNED on 2026-07-28 without a human reply, inviting a new issue if still relevant. Filing fresh per that invitation, with a reproducible characterization of when the fallback fires.

Problem Statement

Markdown tables in Claude's output silently stop being tables when the terminal is narrow: each row degrades into a stack of bold Header: labels with its value beneath. I run a ~100-column terminal by choice and lose tables that render fine at ~140 columns, even though the same data is perfectly legible at 100.

This is not a matter of the terminal being too narrow for a table of that shape. A four-column table whose cells are short stays tabular down to about 28 columns; the same four-column table with longer cells gives up at 100. So the trigger is the content, not the geometry, which makes it unpredictable from where I sit — it turns on how verbose the model happened to be in one cell.

There is currently no setting, environment variable, or flag that affects this. The only lever available is to influence the model's output — instructing it via CLAUDE.md to use fewer columns and shorter cells — which is a probabilistic prompt-level workaround for a deterministic rendering decision.

There is precedent for a setting that changes table rendering: per the v2.1.200 changelog, screen-reader mode makes nested tables read as Header: value. lines. So table layout is already something a setting can influence — just not for the narrow-terminal case.

Proposed Solution

Make the table → Header:-stack fallback configurable. In order of preference:

  1. A settings.json key to opt out of the fallback — e.g. "markdownTableFallback": "never" | "auto" (default auto = today's behavior). I would rather have a table with cramped, heavily wrapped columns than a stack of labels.
  2. Or a tolerance knob: let me raise how much vertical space a single row may occupy before the whole table degrades, since that is what appears to trigger it.
  3. An environment variable equivalent would be fine, and is arguably a better fit for something this niche.

Either shape is enough. I am not asking for column-width control, border styles, or horizontal scrolling.

Alternative Solutions

Tried, and does not help:

  • /tui fullscreen — problem statement was written with this setting active
  • Widening the terminal — works, but that is the thing I am trying to avoid.
  • Instructing the model in CLAUDE.md to keep cells short and columns few. The only workaround that does anything, and unreliable by nature.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

  1. In fullscreen TUI at ~120 columns, get Claude to emit this table (asking for a comparison of three approaches across three attributes produces something equivalent):

````markdown
| Approach | Pros | Cons | Notes |
| --- | --- | --- | --- |
| Polling | Trivial to implement and debug locally, needs no inbound network path, and fails in obvious ways | Burns request quota on every idle cycle and adds latency equal to half the poll interval | Fine below roughly ten clients, past that the wasted calls start to dominate the bill |
| Webhook | Near-instant delivery with no cost while idle, and the sender retries on our behalf in most cases | Requires a publicly reachable URL plus signature verification, so it is awkward behind NAT | Needs a replay path for the window where our endpoint was down or returning errors |
| Queue | Survives restarts, absorbs bursts through back-pressure, and decouples producer from consumer | Another component to deploy, monitor, and reason about when messages go missing | Best above roughly ten clients, or whenever delivery must outlive a process crash |

````

  1. It renders as a bordered table.
  2. Drag the window narrower to ~100 columns. The table reflows live and, at ~100, stops being a table — each row becomes a stack of bold Header: labels with its value.
  3. Drag back out to ~120. It becomes a bordered table again.
  4. With the proposed setting, step 3 would keep the bordered table at 100 columns, with cells wrapping to more lines inside their own columns.

Additional Context

Layout is re-evaluated live and in both directions. In fullscreen TUI the table flips between bordered and Header:-stack rendering as the window is dragged, with no re-prompting, and flips back on widening. The flip width depends on cell length: a short-celled table of the same shape holds its borders down to roughly 28 columns.

Correction to #68839. That issue described the table/list choice as "sampled once at render time and never re-evaluated," inferred from a trick where shrinking the font, letting a table render, then zooming back in leaves the table intact. Live resizing contradicts that: the layout re-decides continuously and reversibly as the width changes. One hypothesis for the persistence they saw is a difference between the classic renderer and fullscreen TUI — I have only tested fullscreen TUI, so I can't confirm it. Either way, the decision is width- and content-reactive, which makes this a configurable-threshold request rather than a rendering-architecture change.

Accessibility angle (from #68839, still valid). Large-font and zoom users get fewer character columns, so they hit this fallback constantly. The users who most need legible output are the ones pushed into the degraded layout. #68839 carried the area:a11y label for this reason.

Environment. Claude Code 2.1.220, fullscreen TUI, Linux (NixOS), kitty 0.47.0, TERM=xterm-kitty.

View original on GitHub ↗