Skip to content

Commit 6d4df75

Browse files
committed
Show the running version on the landing screen
An operator has no way to tell which build is running once the terminal is open, which matters when a release changes default behaviour. The version is read from package.json and painted beside the two existing hints so it cannot drift from what shipped.
1 parent b695c4d commit 6d4df75

2 files changed

Lines changed: 21 additions & 4 deletions

File tree

src/tui-opentui/landing.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { makeOperatorQuestion, openOperatorOverlay } from "./overlays"
2020
import {
2121
LANDING_HINTS,
2222
LANDING_SUGGESTIONS,
23+
LANDING_VERSION,
2324
landingBelowContent,
2425
landingBelowRows,
2526
landingSuggestionFor,
@@ -28,6 +29,7 @@ import {
2829
wrapLanding,
2930
} from "./landing"
3031
import { LOCKUP_WORDMARK } from "./lockup"
32+
import pkg from "../../package.json" with { type: "json" }
3133
import { MARK_LARGE, MARK_MID, MARK_SMALL } from "./mark-shape"
3234
import { UI } from "./theme"
3335

@@ -151,6 +153,9 @@ describe("landing screen", () => {
151153
expect(row).toContain(hint.key)
152154
expect(row!.indexOf(hint.key)).toBeGreaterThan(0)
153155
}
156+
// The version sits with the hints, and cannot drift from package.json.
157+
expect(LANDING_VERSION).toBe(`v${pkg.version}`)
158+
expect(h.captureCharFrame()).toContain(LANDING_VERSION)
154159
const noticeRow = painted.findIndex((row) => row.includes("telemetry"))
155160
expect(noticeRow).toBeGreaterThan(bottom)
156161
for (const item of LANDING_SUGGESTIONS) {

src/tui-opentui/landing.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
type TextChunk,
3131
} from "@opentui/core"
3232
import { BoxRenderable, TextRenderable } from "@opentui/core"
33+
import pkg from "../../package.json" with { type: "json" }
3334

3435
import { MARK_LARGE, MARK_MID, MARK_SMALL, type MarkGrid } from "./mark-shape.js"
3536
import { renderMark } from "./mark-anim.js"
@@ -49,6 +50,9 @@ const MARK_GAP_ROWS = 1
4950
/** Columns of air between the mark's right edge and the hint block. */
5051
export const LANDING_HERO_GAP = 3
5152

53+
/** The running build, read from `package.json` so it cannot drift from what shipped. */
54+
export const LANDING_VERSION = `v${pkg.version}`
55+
5256
/**
5357
* The two doors off the landing screen. Every other key lives behind one of
5458
* them, so this list never grows.
@@ -62,9 +66,9 @@ export const LANDING_HINTS: readonly {
6266
]
6367

6468
/** Columns the hint block needs, its longest line deciding. */
65-
export const LANDING_HINT_WIDTH = LANDING_HINTS.reduce(
66-
(widest, hint) => Math.max(widest, hint.key.length + 1 + hint.rest.length),
67-
0,
69+
export const LANDING_HINT_WIDTH = Math.max(
70+
LANDING_HINTS.reduce((widest, hint) => Math.max(widest, hint.key.length + 1 + hint.rest.length), 0),
71+
LANDING_VERSION.length,
6872
)
6973

7074
/** Largest first: the landing takes the best-reading mark its zone can seat. */
@@ -343,6 +347,14 @@ function createHintBlock(ctx: CliRenderer): BoxRenderable {
343347
}),
344348
)
345349
})
350+
block.add(
351+
new TextRenderable(ctx, {
352+
id: "shell-landing-version",
353+
height: 1,
354+
content: LANDING_VERSION,
355+
fg: UI.textFaint,
356+
}),
357+
)
346358
return block
347359
}
348360

@@ -352,7 +364,7 @@ function createHintBlock(ctx: CliRenderer): BoxRenderable {
352364
*/
353365
export function fitLandingMark(above: LandingAbove, grid: MarkGrid | null): void {
354366
above.grid = grid
355-
const rows = grid?.rows ?? LANDING_HINTS.length
367+
const rows = grid?.rows ?? LANDING_HINTS.length + 1
356368
above.hero.height = rows
357369
above.markColumn.visible = grid !== null
358370
above.markColumn.width = grid?.cols ?? 0

0 commit comments

Comments
 (0)