feat(desktop): show the running build on the sidebar footer - #3430
feat(desktop): show the running build on the sidebar footer#3430Joob1n wants to merge 2 commits into
Conversation
`PR-BUILD-HYGIENE-0` put a build stamp on the About page so a dev build could be told apart from a release. It works, and it is two clicks and a scroll away — so the question it answers gets asked where it cannot answer it. This session hit exactly that: a locally built app was mistaken for the installed release, and a merged change looked like it had not landed. The rail footer already had the shape for it. `.maka-sidebar-footer-row` is a flex row whose settings item is `flex: 1`, so a sibling lands flush right — the slot the update button uses today. Order is settings, stamp, update button. The button is an action and keeps the edge, where a control is reached for; the stamp is a label, and putting it outside the button would move it every time an update arrived or was installed. A dev build never renders that button at all — `app-update-service` short-circuits to `not-available` when `!isPackaged` — so on a dev build the stamp sits at the edge on its own, and on a release it yields without changing its relation to Settings. `v0.1.11` on a release, `v0.1.11 · 4d223d0` on a dev build. The commit is present only when unpackaged, since `build-info.ts` reads `.git/HEAD` and returns null once there is no repository to read — which is exactly the case where a version number alone cannot separate two builds. Seven hex characters is what `git log --oneline` prints and how a commit is quoted in review. Collapsed, the rail is 48px and the stamp is hidden rather than clipped or allowed to widen it. The About page still carries it, and a collapsed rail is a deliberate request for less. Read once at mount through `window.maka.app.info()`: neither value can change without the process restarting. A failed read renders nothing — an orientation label that shows an error where a version belongs is worse than one that is absent, and the About page reports that failure where a user went looking for it. Tests cover both build shapes, the pre-resolution empty state, and the order against the update button — verified to fail when the stamp is moved past it. Claude-Session: https://claude.ai/code/session_014ajaRxC4jydavY9nYUFj5J Generated-by: Claude Code (Claude Opus 5)
44c0741 to
96f1bc8
Compare
|
@Astro-Han , could you merge this pr? |
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for putting the build identity where developers actually look, and for reusing the existing app:info path rather than introducing another main-process authority. The expanded/collapsed behavior and the release-versus-development formatting are clear, and the live test check is green.
I’m leaving one non-blocking P2 follow-up below.
The only correctness gap I found is specific to the development workflow: a normal Git worktree has a .git file containing a gitdir pointer, rather than a .git directory. The existing build-info resolver therefore returns commit: null in that checkout, so this footer falls back to the version alone and still cannot distinguish that locally built tree from a packaged release. The clean fix is to extend the existing main-process build-info authority to follow worktree metadata and cover that case with a focused resolver test; the renderer should remain a pure consumer of app:info rather than growing a second Git reader.
As a small P3 polish item, at the supported 180px expanded width a packaged build with an update reminder can slightly truncate the Settings label. The icon, action, and accessible name remain available, so this is not a merge blocker; making the stamp the shrinkable/ellipsis item while preserving its full title would keep both pieces readable.
AI-assisted review disclosure: OpenAI Codex coordinated the exact-head review. I independently verified the current head, base, CI and review state, traced the app:info/build-info data flow against current main, reproduced the Git-worktree behavior, and checked the sidebar geometry. The recommendation above is my reviewed judgment; no unverified AI output is being presented as a finding.
| .info() | ||
| .then((info) => { | ||
| if (cancelled) return; | ||
| setStamp({ version: info.appVersion, commit: info.buildCommit }); |
There was a problem hiding this comment.
[P2] Thanks for wiring the footer to the existing app:info result. One development-path gap remains: when Maka is run from a normal Git worktree, .git is a file containing a gitdir pointer, so the current main-process build-info resolver returns commit: null. This makes the new stamp render only v<version> and fails to distinguish the locally built tree from a packaged release—the exact problem this change is meant to solve for contributors. Could we extend the existing build-info authority to follow worktree metadata and add a focused resolver test, while keeping the renderer as a pure app:info consumer rather than adding a second Git reader here?
Two findings from @Astro-Han's review of the sidebar build stamp. **P2 — a worktree's `.git` is a file, and the resolver only read directories.** `resolveCommit` opened `<root>/.git/HEAD`. In a linked worktree `.git` is a file holding `gitdir: <path>` into `<main>/.git/worktrees/<name>`, so the read found nothing and the stamp fell back to the version alone — in exactly the checkout where it matters most, since a worktree's HEAD is the one that differs from the tree a developer thinks they are running. Fixed in the main-process `build-info` authority as asked; the renderer stays a pure consumer of `app:info`. A relative `gitdir:` resolves against the checkout, which is how Git writes it for a worktree created inside the repo. Verified against a real worktree in this checkout rather than fixtures alone: the repository root reports `96f1bc8` and the worktree reports `5d9a5b0`, each matching `git rev-parse` — two different commits, which is the distinction the stamp exists to make. The resolver had no test file at all. It has one now: ordinary clone, worktree by absolute and by relative pointer, detached HEAD, packed refs, and the two unreadable cases, where absence stays a supported answer rather than throwing out of `app:info`. **P3 — the Settings label could clip at the 180px minimum.** The stamp was `flex: none` and the settings row `flex: 1`, so with an update button present the label lost the argument. The stamp is now the shrinkable item — it ellipsises and keeps its full value in `title`, while the label a user reads and the row they aim at stay intact. Claude-Session: https://claude.ai/code/session_014ajaRxC4jydavY9nYUFj5J Generated-by: Claude Code (Claude Opus 5)
|
Both addressed in P2 — the worktree case reproduces, and the fix is in
The main process now follows the pointer, resolving a relative Verified on the same real worktree afterwards: repository root reports The resolver had no test file. It has one now covering ordinary clone, worktree by absolute and relative pointer, detached HEAD, packed refs, and the two unreadable cases — where absence stays a supported answer rather than throwing out of P3 — the stamp yields, the label does not. It was Gates: build, lint, format:check, typecheck. Suites: desktop 1030 (1023 before, +7 from the new resolver test), ui 187. |
Summary
PR-BUILD-HYGIENE-0put a build stamp on the About page so a dev build could be told apart from a release. It works, and it is two clicks and a scroll away — so the question it answers gets asked where it cannot answer it.I hit exactly that while working in this repo: a locally built app was mistaken for the installed release, and a change that had merged looked like it had not landed. The version was on screen the whole time, one page away.
The rail footer already had the shape for it.
.maka-sidebar-footer-rowis a flex row whose settings item isflex: 1, so a sibling lands flush right — the slot the update button uses.Order is settings, stamp, update button. The button is an action and keeps the edge, where a control is reached for; the stamp is a label, and outside the button it would move every time an update arrived or was installed. A dev build never renders that button —
app-update-service.tsshort-circuits tonot-availablewhen!isPackaged— so on a dev build the stamp sits at the edge on its own, and on a release it yields without changing its relation to Settings.The commit appears only on a dev build:
build-info.tsreads.git/HEADand returns null once packaged, which is exactly the case where a version number alone cannot separate two builds. Seven hex characters is whatgit log --onelineprints and how a commit is quoted in review.Read once at mount through
window.maka.app.info()— neither value can change without the process restarting. A failed read renders nothing: an orientation label showing an error where a version belongs is worse than one that is absent, and the About page reports that failure where a user went looking for it.Verification
Ran
npm run devand read the footer on a dev build:A release renders
v0.1.11alone, sincebuild-info.tshas no.gitto read once packaged.Tests cover both build shapes, the pre-resolution empty state, and the order against the update button. The order assertion was checked in both directions — moving the stamp past the button fails that test and only that test — so it pins the layout rather than describing it.
Gates run:
build,lint,format:check,typecheck,kniponapps/desktopandpackages/ui,astryx:surface-inventory,astryx:theme --check. Suites:@maka/ui187 (183 before this change),@maka/desktop1023. Storybook builds and all 145 stories render.Not run: Windows and Linux packaging; this is renderer-only and platform-independent, but the rail is only exercised on macOS here.
Review focus
The collapsed rail. The stamp is hidden below 48px rather than clipped or allowed to widen the rail — and
readSessionListCollapsed()returnstruewhen nothing is stored, so a first run has the rail collapsed and the stamp does not appear until it is expanded.I do not think a truncated version string earns 48px, and the About page still carries it. But this is the judgement most worth a second opinion: if the rail's default state matters more than its width, the fallback is a shorter form (
0.1.11— no prefix, no commit) at a smaller size rather than nothing at all.AI use
Select exactly one:
Tool(s) and scope: Claude Code — traced the existing build-info plumbing, made the change, wrote the tests, and ran the verification above.
Generated-byis on the commit. Reviewed and submitted by the contributor of record.Checklist
Does this PR entail a change in behavior?