Skip to content

fix(tui): make the welcome panel responsive to terminal size (#1067) - #1069

Open
saravmajestic wants to merge 1 commit into
mainfrom
fix/AI-1067-welcome-panel-responsive
Open

fix(tui): make the welcome panel responsive to terminal size (#1067)#1069
saravmajestic wants to merge 1 commit into
mainfrom
fix/AI-1067-welcome-panel-responsive

Conversation

@saravmajestic

@saravmajestic saravmajestic commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Closes #1067.

What & why

The welcome panel (home_logo slot) rendered a fixed two-column boot box — block ALTIMATE CODE wordmark on the left (~65 cols), "What is Altimate Code" on the right — that never shrank. On a typical terminal it took ~40–50% of the screen and couldn't be reduced, which is what #1067 reports.

What this does

It now scales with terminal size, reactively (adapts live on resize), using the repo's existing breakpoint idiom (useTerminalDimensions + createMemo, as in routes/session/permission.tsx and component/upgrade-indicator.tsx). Both axes gate each step — the wordmark is wide and tall:

Variant When What shows ~height
full ≥110w & ≥44h the two-column wordmark boot box (large windows only) ~13 rows
medium in between (the common case) title + one condensed line + CTA, no wordmark ~6 rows
compact <60w or <18h a single line; the border title already carries the version ~3 rows

On an everyday laptop terminal (e.g. 106×31, 80×24) you now get medium; the full branded panel returns only when there's genuinely room for it.

Notes

  • The breakpoint decision is a pure function in welcome-panel-utils.ts (mirroring upgrade-indicator-utils.ts), so it's unit-testable without the render/sync context. 4 tests cover the thresholds and that the smaller dimension wins.
  • Scope: responsiveness only. No dismiss / collapse-once-connected behavior change — that's separable and can be a follow-up if wanted.
  • Thresholds are four named constants in welcome-panel-utils.ts, easy to tune.

Verified

tsgo --noEmit clean · 4 unit tests pass · existing home-onboarding render test still passes · oxlint 0/0 · prettier.

🤖 Generated with Claude Code


Summary by cubic

Make the TUI welcome panel responsive to terminal size so it no longer takes over small terminals. Addresses AI-1067 by switching between full, medium, and compact layouts and updating live on resize.

  • Bug Fixes
    • Implemented breakpoint logic with useTerminalDimensions + createMemo; both width and height decide the layout.
    • Added welcome-panel-utils with welcomePanelVariant and thresholds; 4 unit tests cover edge cases.
    • Updated welcome-panel.tsx to render: full (two-column, ≥110w & ≥44h), medium (no wordmark), compact (single line, <60w or <18h); no changes to CTA/dismiss behavior.

Written for commit 721fee6. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • The welcome panel now adapts its layout to the available terminal size.
    • Added full, medium, and compact layouts to improve usability in smaller terminal windows.
    • Compact layouts provide condensed information and streamlined readiness actions.
  • Tests

    • Added coverage for layout selection across terminal size thresholds and boundary conditions.

The full two-column boot box (block wordmark + description) is ~65 cols wide and
~13 rows tall, so on a typical terminal it ate ~40-50% of the screen with no way
to shrink it (#1067).

It now scales by terminal size, using the repo's breakpoint idiom
(useTerminalDimensions + createMemo, cf. routes/session/permission.tsx,
component/upgrade-indicator.tsx) — reactive, so it adapts live on resize:

- full   — the two-column wordmark box, reserved for large windows (>=110w & >=44h)
- medium — title + one condensed line, no wordmark (the common case, ~6 rows)
- compact — a single line; the border title already shows the version (<60w or <18h)

The breakpoint decision is a pure function in welcome-panel-utils.ts (mirroring
upgrade-indicator-utils.ts) so it's unit-testable without the render/sync context;
4 tests cover the thresholds and that the smaller dimension wins.

Scope: responsiveness only — no dismiss/collapse behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 552387a0-f7d7-419e-a45d-3bf463101bc0

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae6c02 and 721fee6.

📒 Files selected for processing (3)
  • packages/tui/src/component/welcome-panel-utils.ts
  • packages/tui/src/component/welcome-panel.tsx
  • packages/tui/test/component/welcome-panel-utils.test.ts

📝 Walkthrough

Walkthrough

The TUI welcome panel now selects compact, medium, or full layouts from terminal width and height. New breakpoint utilities classify dimensions, and tests cover threshold behavior. The panel renders condensed content for smaller terminals while retaining the original full layout.

Changes

Responsive Welcome Panel

Layer / File(s) Summary
Terminal-size variant classification
packages/tui/src/component/welcome-panel-utils.ts, packages/tui/test/component/welcome-panel-utils.test.ts
Breakpoint constants and welcomePanelVariant classify terminal dimensions as compact, medium, or full. Tests cover boundaries and cross-axis thresholds.
Responsive panel rendering
packages/tui/src/component/welcome-panel.tsx
WelcomePanel uses terminal dimensions to select layouts. Compact mode shows a readiness-dependent line. Medium mode shows condensed content and the connection CTA when needed. Full mode retains the wordmark, information panel, and existing CTA behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TerminalDimensions
  participant WelcomePanel
  participant welcomePanelVariant
  participant CompactLayout
  participant MediumLayout
  participant FullLayout
  TerminalDimensions->>WelcomePanel: provide width and height
  WelcomePanel->>welcomePanelVariant: classify terminal dimensions
  welcomePanelVariant-->>WelcomePanel: return panel variant
  WelcomePanel->>CompactLayout: render compact content
  WelcomePanel->>MediumLayout: render medium content
  WelcomePanel->>FullLayout: render full content
Loading

Poem

I’m a rabbit in a smaller-screen den,
Compact lines appear, then medium again.
Full panels bloom when space is wide,
Readiness stays close by each side.
Hop, hop—the welcome view can fit!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR fixes excessive space from the fixed panel, but it does not address issue #1067's separate requirement that the home_logo slot be dismissible. Implement or explicitly scope the dismiss behavior for home_logo, or split and relink the responsiveness fix so issue #1067's full requirements are covered.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: making the TUI welcome panel responsive to terminal size.
Description check ✅ Passed The description explains the issue, implementation, scope, and verification, but omits some template headings, checklist state, and screenshots.
Out of Scope Changes check ✅ Passed All code and tests are limited to terminal-size responsiveness and related layout behavior; no unrelated changes are shown.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/AI-1067-welcome-panel-responsive

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/tui/src/component/welcome-panel-utils.ts">

<violation number="1" location="packages/tui/src/component/welcome-panel-utils.ts:18">
P3: Constant naming `COMPACT_MAX_WIDTH` / `COMPACT_MAX_HEIGHT` / `MEDIUM_MAX_WIDTH` / `MEDIUM_MAX_HEIGHT` conflicts with the strict inequality in `welcomePanelVariant`. The suffix `_MAX_` conventionally implies an inclusive upper bound (so `width ≤ COMPACT_MAX_WIDTH` would be compact), but the function uses strict `<`, meaning at the exact value the variant flips to the next tier. For example, `width = COMPACT_MAX_WIDTH (60)` returns medium, not compact, and `width = MEDIUM_MAX_WIDTH (110)` returns full, not medium. Someone tuning these thresholds later could easily mis-predict behavior.

Recommend renaming to convey an exclusive boundary, e.g. `COMPACT_BELOW_WIDTH`, `COMPACT_BELOW_HEIGHT`, `MEDIUM_BELOW_WIDTH`, `MEDIUM_BELOW_HEIGHT` (mirroring the PR description's `<60w` / `<18h` / `<110w` / `<44h` language).</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

// ~40% of the screen, which is the problem #1067 is about. So `medium` (no
// wordmark, ~6 rows) is the common case; `full` only when there's real room.
/** Below these, drop to the single-line compact panel. */
export const COMPACT_MAX_WIDTH = 60

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Constant naming COMPACT_MAX_WIDTH / COMPACT_MAX_HEIGHT / MEDIUM_MAX_WIDTH / MEDIUM_MAX_HEIGHT conflicts with the strict inequality in welcomePanelVariant. The suffix _MAX_ conventionally implies an inclusive upper bound (so width ≤ COMPACT_MAX_WIDTH would be compact), but the function uses strict <, meaning at the exact value the variant flips to the next tier. For example, width = COMPACT_MAX_WIDTH (60) returns medium, not compact, and width = MEDIUM_MAX_WIDTH (110) returns full, not medium. Someone tuning these thresholds later could easily mis-predict behavior.

Recommend renaming to convey an exclusive boundary, e.g. COMPACT_BELOW_WIDTH, COMPACT_BELOW_HEIGHT, MEDIUM_BELOW_WIDTH, MEDIUM_BELOW_HEIGHT (mirroring the PR description's <60w / <18h / <110w / <44h language).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/tui/src/component/welcome-panel-utils.ts, line 18:

<comment>Constant naming `COMPACT_MAX_WIDTH` / `COMPACT_MAX_HEIGHT` / `MEDIUM_MAX_WIDTH` / `MEDIUM_MAX_HEIGHT` conflicts with the strict inequality in `welcomePanelVariant`. The suffix `_MAX_` conventionally implies an inclusive upper bound (so `width ≤ COMPACT_MAX_WIDTH` would be compact), but the function uses strict `<`, meaning at the exact value the variant flips to the next tier. For example, `width = COMPACT_MAX_WIDTH (60)` returns medium, not compact, and `width = MEDIUM_MAX_WIDTH (110)` returns full, not medium. Someone tuning these thresholds later could easily mis-predict behavior.

Recommend renaming to convey an exclusive boundary, e.g. `COMPACT_BELOW_WIDTH`, `COMPACT_BELOW_HEIGHT`, `MEDIUM_BELOW_WIDTH`, `MEDIUM_BELOW_HEIGHT` (mirroring the PR description's `<60w` / `<18h` / `<110w` / `<44h` language).</comment>

<file context>
@@ -0,0 +1,29 @@
+// ~40% of the screen, which is the problem #1067 is about. So `medium` (no
+// wordmark, ~6 rows) is the common case; `full` only when there's real room.
+/** Below these, drop to the single-line compact panel. */
+export const COMPACT_MAX_WIDTH = 60
+export const COMPACT_MAX_HEIGHT = 18
+/** At/above these, show the full two-column wordmark panel; below → medium. */
</file context>

@saravmajestic saravmajestic self-assigned this Aug 4, 2026

@sahrizvi sahrizvi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — responsiveness change works, but two things block

The direction is right and the decomposition is clean. Splitting the breakpoint decision into a pure, exported function mirroring upgrade-indicator-utils.ts is the right call, the createMemo + useTerminalDimensions wiring matches the idiom in upgrade-indicator.tsx:14 and permission.tsx:450 (genuinely reactive, no destructured props), and the full branch is a faithful move of the original markup so the large-terminal path is low-risk. Theme tokens are unchanged, there's no dead code, and the scope discipline — explicitly declining to bundle dismiss/collapse — is good.

Two blockers, both left inline:

  1. The breakpoint is computed from terminal width, but the panel never gets terminal width. In the session view with the sidebar open, full is still selected when the panel only has ~84–94 columns, and the panel swells back to ~44% of the screen — the exact bug #1067 reports. (welcome-panel.tsx:30)
  2. The tests don't prove the width threshold the change is built around. Deleting width < MEDIUM_MAX_WIDTH from the source leaves all four tests green. (welcome-panel-utils.test.ts:17)

Plus three minors inline: the compact variant's wrapMode="word" breaks its own single-line invariant, medium is ~9 rows at its lower bound rather than ~6, and the *_MAX_* constants are really minimums for the tier above.


MINOR — no render test for the component, though the repo has the harness

The pure function is tested; the part that can actually break isn't — that useTerminalDimensions is wired up, that the memo survives a resize, that each variant fits its row budget. test/feature-plugins/home-onboarding.test.tsx shows testRender takes an explicit { width, height }, so a three-case render test is cheap.

"existing home-onboarding render test still passes" is true but says nothing about this component — that test renders at 120×4 and never mounts WelcomePanel. A render test at session-like widths with the sidebar visible is also the only thing that would have caught blocker #1.

NIT — contradictory height figures inside one file

welcome-panel-utils.ts:4-5 says the full box is "~8 rows tall"; lines 13-16 say "~13 rows tall". Both are defensible (inner content vs. bordered box) but the reader can't tell which is which. Pick one framing.

NIT — structural cleanups worth folding in

  • welcome-panel.tsx:31-33compact(), medium(), full() are three memos over one memo feeding three mutually-exclusive <Show> blocks (lines 51, 60, 78). routes/session/permission.tsx and session/index.tsx:1349-1358 both use <Switch><Match when={…}> for exactly this; switching makes the exclusivity structural rather than incidental.
  • The fixed width={65} left column (line 82) is ~15 columns wider than its content — src/logo.ts is 32 + 1 gap + 17 = 50 columns, and the title line is 24. Trimming to ~52 would let full engage on a smaller terminal and would soften blocker #1.
  • "Connect your AI model to start." is duplicated verbatim at lines 54, 71 and 122 — worth one module constant. (The three descriptions are deliberately different copy, not duplication.)

Open design question, not a defect

MEDIUM_MAX_HEIGHT = 44 means the wordmark is effectively never seen on a laptop — it needs an external monitor or a full-screen tall window. That may well be intentional ("full only when there's real room"), but it's worth an explicit product decision, since it makes the branded panel dead code for most users. Note the tension with blocker #1: lowering the threshold widens the range where the sidebar case misfires, so fix that first.

Missing tests, collected

  • Compact→medium boundary at exactly (60, 18), (60, 40), (120, 18) — the entire lower boundary.
  • (109, 44) — the only case that isolates the full width gate.
  • Degenerate sizes (0, 0), (1, 1) — currently return compact, which is correct, but nothing pins it.
  • Render tests per variant, with height-budget assertions and a resize transition.
  • Session layout with the sidebar visible — where blocker #1 lives.

const ready = useReady()
const dimensions = useTerminalDimensions()

const variant = createMemo(() => welcomePanelVariant(dimensions().width, dimensions().height))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAJOR (Bug / Logic Error) — the breakpoint reads terminal width, but the panel never gets terminal width.

dimensions().width is the whole terminal. This panel is never that wide:

  • routes/home.tsx:104 wraps it in <box … paddingLeft={2} paddingRight={2}>width - 4.
  • routes/session/index.tsx:1181-1189 — same padding, and it sits in the content column of a flexDirection="row" layout whose sibling is a 42-column Sidebar (routes/session/sidebar.tsx:30), auto-shown whenever width > 120 (session/index.tsx:267-272).

The correct quantity already exists four lines from the call site and is unused here:

// session/index.tsx:274
const contentWidth = createMemo(() => dimensions().width - (sidebarVisible() ? 42 : 0) - 4)

The full branch has a hard width={65} flexShrink={0} left column (line 82), so it needs ~105 usable columns:

Terminal Sidebar Panel width Variant chosen Right-column text
110×44 (home) n/a 106 full ~33 cols — fine
130×50 (session) visible (auto, >120) 84 full ~11 cols
140×50 (session) visible 94 full ~21 cols

At 140×50 the two description paragraphs wrap to ~13 rows and the panel lands at ~22 rows — 44% of the screen, which is the complaint in #1067. Every terminal roughly 121–151 columns wide and ≥44 rows, in a session with the sidebar visible, reproduces the original bug.

Not a regression (before this change full rendered at every size), but the fix misses its stated goal in a configuration a user on a large monitor will hit.

Fix:

export function WelcomePanel(props: { availableWidth?: number } = {}) {
  const dimensions = useTerminalDimensions()
  const width = createMemo(() => props.availableWidth ?? dimensions().width - 4)
  const variant = createMemo(() => welcomePanelVariant(width(), dimensions().height))
// session/index.tsx
<WelcomePanel availableWidth={contentWidth()} />

contentWidth is already reactive to sidebarVisible(), so toggling the sidebar re-picks the variant for free.

Belt-and-braces regardless: give the full left column flexShrink={1} or a maxWidth, or a minWidth on the right column, so a mis-sized full degrades instead of collapsing to a text gutter.


test("a narrow OR short terminal drops the wordmark (medium)", () => {
expect(welcomePanelVariant(80, 24)).toBe("medium")
expect(welcomePanelVariant(MEDIUM_MAX_WIDTH - 1, 40)).toBe("medium") // narrow but tall

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAJOR (Testing) — these tests don't prove what the PR description claims they prove.

The description says "4 tests cover the thresholds and that the smaller dimension wins." Two separate problems mean they don't.

(a) The full-tier width gate is entirely unexercised. Mutation-test the pure function — delete the width gate from the medium branch:

if (width < MEDIUM_MAX_WIDTH || height < MEDIUM_MAX_HEIGHT) return "medium"
// becomes
if (height < MEDIUM_MAX_HEIGHT) return "medium"

…and all four tests still pass. The other three gates (full height, compact width, compact height) are each caught by an equivalent mutant, so this is the one real hole.

This line is the culprit: the comment says "narrow but tall", but 40 < MEDIUM_MAX_HEIGHT (44), so height forces the medium result, not width. "Tall" isn't tall enough to isolate the width axis.

(b) The compact→medium boundary is untested, and test 4 (lines 27-31) duplicates test 3. Line 12 does an "at the threshold" check for the full tier; the compact tier has none, so a <<= slip on either compact gate ships silently. And test 4's (200, 17) / (59, 200) take the same two branches as test 3's (120, 17) / (59, 40) — only the non-deciding dimension differs, and it stays on the same side of every threshold. No mutant is caught by test 4 that test 3 doesn't already catch.

Fix — repair this assertion and replace test 4 with the boundaries that are actually missing:

expect(welcomePanelVariant(MEDIUM_MAX_WIDTH - 1, MEDIUM_MAX_HEIGHT)).toBe("medium") // narrow, tall enough
expect(welcomePanelVariant(COMPACT_MAX_WIDTH, COMPACT_MAX_HEIGHT)).toBe("medium")
expect(welcomePanelVariant(COMPACT_MAX_WIDTH, 40)).toBe("medium")
expect(welcomePanelVariant(120, COMPACT_MAX_HEIGHT)).toBe("medium")
expect(welcomePanelVariant(0, 0)).toBe("compact")

{/* compact — one line; the border title already carries the version */}
<Show when={compact()}>
<box paddingLeft={2} paddingRight={2} width="100%">
<text fg={ready() ? theme.text : theme.primary} wrapMode="word" width="100%">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR (Bug) — wrapMode="word" means the "single line" invariant doesn't actually hold.

The compact string is 31 characters ("Connect your AI model to start."). Subtract 2 border + 4 panel padding + 4 home-route gutter and it wraps at roughly 40 columns; near 20 columns it can reach ~5 rows. compact is reachable at any width below 60, so the "a single line; ~3 rows" claim on line 24 is aspirational rather than enforced.

Fix — enforce it structurally:

<text fg={ready() ? theme.text : theme.primary} wrapMode="none" truncate width="100%">

Comment on lines +61 to 74
<box paddingLeft={2} paddingRight={2} paddingTop={1} paddingBottom={1} gap={0} width="100%">
<text fg={theme.text} attributes={TextAttributes.BOLD}>
Welcome to Altimate Code
</text>
<text fg={theme.text} wrapMode="word" width="100%">
It gives your AI real context — column-level lineage, SQL analysis, dbt, and live warehouse metadata — so it
reasons about your data instead of guessing.
A data-engineering harness that gives your AI real context — column-level lineage, SQL analysis, dbt, and
live warehouse metadata.
</text>
{/* CTA only until a model is connected — stale afterwards */}
<Show when={!ready()}>
<text fg={theme.primary} wrapMode="word" width="100%">
Connect your AI model to start.
</text>
</Show>
</box>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR (Design) — medium is ~9 rows at its own lower bound, not the advertised ~6.

At the smallest terminal that still selects medium (60×18, home route → 56-wide panel, 50-column text area):

Element Rows
border 2
paddingTop / paddingBottom 2
title 1
description (~130 chars at 50 cols) 3
CTA (disconnected) 1
total ~9

That's 50% of an 18-row terminal — the same ratio #1067 complains about, in a different layout. Even at minimum intrinsic size the disconnected medium panel needs 7 rows, so the "~6 rows" figure in welcome-panel-utils.ts:16 isn't reachable while the CTA is present.

Raise COMPACT_MAX_HEIGHT, drop the vertical padding here, or shorten the description so it fits one or two lines at 50 columns.

Comment on lines +17 to +22
/** Below these, drop to the single-line compact panel. */
export const COMPACT_MAX_WIDTH = 60
export const COMPACT_MAX_HEIGHT = 18
/** At/above these, show the full two-column wordmark panel; below → medium. */
export const MEDIUM_MAX_WIDTH = 110
export const MEDIUM_MAX_HEIGHT = 44

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MINOR (Code Quality / Documentation) — the *_MAX_* names are actually minimums for the tier above.

Every comparison in welcomePanelVariant is a strict <, so:

  • COMPACT_MAX_WIDTH = 60 → a 60-wide terminal is medium, not compact. 60 is the minimum width for medium.
  • MEDIUM_MAX_WIDTH = 110 → 110 is the minimum width for full.

The doc comment on line 20 ("At/above these, show the full…") already describes minimum semantics and contradicts the name on line 21. These constants are exported and consumed by the tests, so the wrong name propagates — and it's the direct cause of several "is this an off-by-one?" readings that turn out to be wrong.

Suggest MEDIUM_MIN_WIDTH / MEDIUM_MIN_HEIGHT / FULL_MIN_WIDTH / FULL_MIN_HEIGHT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

home_logo slot always visible and cannot be dismissed in TUI

2 participants