From 06097439398b7c6f0510b76cef8d3bb30c144e13 Mon Sep 17 00:00:00 2001 From: Rousan Ali Date: Thu, 9 Jul 2026 13:52:03 +0530 Subject: [PATCH] fix: mx divider renders much larger, fills the terminal (3.6.1) The banner now scales to fill the terminal, using the largest cell size the width allows and growing the height to match (chunky letters), instead of strict proportional scaling that left a long label like IN REVIEWS at 1x (7 rows) and tiny on a fullscreen window. Also honor COLUMNS/LINES env vars as a size fallback for non-TTY output, so a piped run can render at an explicit size for preview. core: renderBanner scale rule. cli: divider size fallback. docs: history. version 3.6.0 to 3.6.1. --- apps/cli/src/divider.ts | 12 +++++++++--- docs/history.md | 4 ++++ npm/package.json | 2 +- packages/core/src/banner.ts | 14 ++++++++------ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/apps/cli/src/divider.ts b/apps/cli/src/divider.ts index 41d8b99..c6b08e9 100644 --- a/apps/cli/src/divider.ts +++ b/apps/cli/src/divider.ts @@ -19,15 +19,21 @@ const SHOW_CURSOR = '\x1b[?25h'; * @param text - The label to display. */ export function runDivider(text: string): void { + // Terminal size, falling back to COLUMNS/LINES env then a default — the env + // fallback lets a non-TTY (piped) run render at an explicit size for preview. + const dims = (): [number, number] => [ + process.stdout.columns || Number(process.env.COLUMNS) || 80, + process.stdout.rows || Number(process.env.LINES) || 24, + ]; const paint = (): void => { - const cols = process.stdout.columns || 80; - const rows = process.stdout.rows || 24; + const [cols, rows] = dims(); process.stdout.write(CLEAR + renderBanner(text, cols, rows)); }; // Non-interactive (piped) stdout: emit once and return, no hold. if (!process.stdout.isTTY) { - process.stdout.write(renderBanner(text, process.stdout.columns || 80, process.stdout.rows || 24) + '\n'); + const [cols, rows] = dims(); + process.stdout.write(renderBanner(text, cols, rows) + '\n'); return; } diff --git a/docs/history.md b/docs/history.md index d0269cf..46b7185 100644 --- a/docs/history.md +++ b/docs/history.md @@ -2,6 +2,10 @@ What each release brought. Reverse-chronological. Dates reflect when the corresponding tag was pushed. +## 3.6.1 — 2026-07-09 + +**`mx divider` renders much larger.** The banner now scales to fill the terminal (chunky letters at the largest cell size the width allows, height grown to match) instead of strict proportional scaling, which left a long label like `IN REVIEWS` tiny on a fullscreen window (7 rows). Also honors `COLUMNS`/`LINES` env vars as a size fallback for non-TTY (piped) output, so you can preview a size without going fullscreen. Renderer-only change in `@mx/core` (`renderBanner`) plus the CLI size fallback. + ## 3.6.0 — 2026-07-08 **`mx divider [-o]`** — fill a terminal with `` as large block letters, a visual separator for macOS Mission Control Spaces (e.g. an `IN REVIEWS` / `PR REVIEWS` window between clusters of work windows). Bare, it takes over the current terminal, draws the banner, and holds it (Ctrl-C or `q` to quit); `-o` opens a new fullscreen Terminal running the same banner (macOS). The text auto-scales to fill the terminal and re-renders on resize. diff --git a/npm/package.json b/npm/package.json index 5e29d0e..2f89cf0 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "@roulabs/mx", - "version": "3.6.0", + "version": "3.6.1", "description": "mx — run several features in parallel across shared repos using git worktrees", "type": "module", "bin": { diff --git a/packages/core/src/banner.ts b/packages/core/src/banner.ts index 97adbf7..c990479 100644 --- a/packages/core/src/banner.ts +++ b/packages/core/src/banner.ts @@ -102,16 +102,18 @@ export function renderBanner(text: string, cols: number, rows: number): string { baseRows.push(glyphs.map((g) => g[r]).join(' ')); } - // Pick a scale that fits both dimensions. A character cell is about twice as - // tall as wide, so we aim for xscale ≈ 2·yscale to keep letters looking - // square, but never exceed the width/height budget (each axis is clamped - // independently, so long text scales down instead of overflowing). + // Scale up to fill the terminal. Width is the usual constraint (a long label + // caps how wide each cell can be), so take the largest cell width that fits + // and then grow the height to match — capped at the same factor so letters + // stay chunky (roughly square in cell counts) rather than proportional-but- + // tiny. This fills far more of a large fullscreen window than strict + // proportional scaling, which is what makes the banner readable at a glance. const marginH = 2; const marginV = 2; const xMax = Math.floor((cols - marginH) / Math.max(1, baseW)); const yMax = Math.floor((rows - marginV) / GLYPH_H); - const yscale = Math.max(1, Math.min(yMax, Math.floor(xMax / 2))); - const xscale = Math.max(1, Math.min(xMax, yscale * 2)); + const xscale = Math.max(1, xMax); + const yscale = Math.max(1, Math.min(yMax, xscale)); // Scale each base row up (horizontally by xscale, vertically by yscale). const scaled: string[] = [];