feat(client): version build-stamp on title screen (#147) #156
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/147-version-display"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this does
Shows
v<version>as a quiet bottom-right cabinet-stamp on the title/landing screen, both viewports. The version is the single source of truth frompackage.json, injected at build time, so the on-screen stamp bumps automatically on release — no second place to keep in sync.Closes #147.
How
vite.config.tsreadspackage.jsonat build time anddefines__APP_VERSION__.src/version.ts(new) is the single seam:declare const __APP_VERSION__(type-checks) →export const APP_VERSION(vite substitutes the literal into the bundle).render.tsdrawTitledrawsv${APP_VERSION}bottom-right.main.tsexposeswindow.__appVersionunder?navtestfor the injection test (the on-screen stamp is what ships).Treatment (Herald spec, #147 comment)
Bottom-right keyart floor, both platforms ·
v1.0.0alone · small, dim, low-opacity monospace. The whole canvas sits inside the body'senv(safe-area-inset-*)padding (index.html), soCANVAS_H − 14is already clear of the iPhone home-indicator; in portrait the stamp (≈886 of 900) lands well below the stacked SOLO/VERSUS buttons (VERSUS bottom ≈602). No fit collision either viewport.Placement/treatment verified by render-capture (throwaway spec, screenshots to
/tmp/cap-147-{landscape,portrait}.pngfor Herald) — canvas text isn't DOM-queryable, so the pixels are eyeballed, not asserted.⚠️ Flagged design calls (want reviewer/Herald veto)
1. Font: I used
FONT_HUD(VT323), not Press Start 2P. Herald's comment says "Press Start 2P (matching the UI chrome)" — but in the codebase the small-text chrome (key-hint line, tagline, HUD) is actually VT323 (FONT_HUD); Press Start 2P isFONT_BIG, the wordmark/button font. Herald's intent ("matching the UI chrome", "small dim footnote") points to VT323, and Press Start 2P at footnote size (~12–16px) is a chunky pixel font that reads poorly for an unobtrusive stamp. So I followed the intent (VT323 — literally the HUD-chrome font, sibling to the key-hint line directly above it) over the literal font name. Decision tree: VT323 is right for a quiet readable footnote; Press Start 2P would be right if the stamp were meant to read as a branded element competing with the wordmark — which contradicts "unobtrusive". Herald: the render is in/tmp— one-line change if you want the literal Press Start 2P instead.2. Bumped
client/package.json0.0.1 → 1.0.0. The manifest was never bumped at the v1.0.0 release cut (no release workflow — the release was cut manually). For the stamp to showv1.0.0(the operator's actual ask) the source-of-truth must read 1.0.0, so I aligned the manifest with the already-released tag. AC#2 ("bumps automatically on release") is now a forward contract: whoever cuts the next release bumpspackage.jsonand the stamp follows. Possible follow-up: a release step / CI check that assertspackage.json.versionmatches the tag, so this gap can't recur — happy to file if wanted.What this does NOT do
package.json↔ tag in lockstep (flagged above as an optional follow-up).Verification
npx tsc --noEmitclean.defineat a garbage literal reds both rows (value-mismatch + not-semver); reverted via precise re-edit.🤖 Generated with Claude Code
✅ APPROVED — version build-stamp (#147)
Reviewed at head
9d2c726(on current mainf0b2496). Small and clean — single source of truth, mutation-proven wire, stamp renders.Injection wire — verified independently, mutation-proven
The chain is tidy: package.json
version→ vitedefine(__APP_VERSION__) →src/version.ts(APP_VERSION) → render.ts stamp +window.__appVersion(navtest-gated, for the test). package.json is the single source so the stamp bumps automatically on release — no second place to sync. I reproduced the mutation: point the vitedefineat a garbage value → both wire tests red (the value mismatch + the semver-shape check that catches the "unreplaced token / undefined" silent-break). The tests honestly scope themselves to the wire, not the pixels — exactly right, since canvas text isn't DOM-queryable.The stamp renders
Captured the title screen myself (renders fine); the stamp is dim-by-design (0.45 alpha — "present for those who look"), so I cross-referenced the dim-pixel position via the purpose-made crop after independently mutation-proving the injection. It shows "v1.0.0" in the bottom-right keyart floor, light-blue (
TEXT), VT323 — the cabinet-stamp treatment. The draw code confirms position (CANVAS_W−14, CANVAS_H−14) and the no-collision reasoning (portrait stamp at ~886 well below the VERSUS button bottom ~602).The two design calls
v1.0.0rather thanv0.0.1. It also fixes a real staleness (the manifest was never bumped at the v1.0.0 release cut). Right place, right time.tsc clean, 79 passed (CI=1 — matches the body). A clean little release-hygiene PR. Closes #147. Merge-ready → Bosun (pending Herald's font ack).