feat: draw every device as the system it runs, on desktop and mobile web - #3166
Merged
bobleer merged 3 commits intoSep 21, 2026
Merged
Conversation
bobleer
force-pushed
the
lwb/device-system-marks-and-mobile-devices
branch
from
September 21, 2026 02:39
51ad577 to
755a784
Compare
The device overview knew which system each device reported and drew one generic monitor for all of them: in the footer trigger, in the attached group, in the carousel and in the connect list. Each of those places now draws the system that device reported - the Apple mark for macOS, the Windows flag, Tux, the HarmonyOS mark, and the server silhouette for a headless host - and keeps the monitor only for a device whose system cannot be placed. - The marks and their system resolution move to src/shared, so the desktop shell and mobile web draw one device the same way. Each surface keeps its own sizes, colours and placement. - This machine's own system and kind now come from its account directory row. The device info command answers with identity only, so the local source was always empty and the local device fell back to the neutral mark. - A mark states its own optical correction, measured from the mass of its own drawing: the Apple's leaf is thin above a heavy body, so its mass sits about 9% below the centre of its box and the mark read as low beside a line of text. - The footer trigger's mark is placed on that line's optical centre instead of its line box, which is split by the font's ascent and descent rather than by the glyphs drawn in it. A phone stays a phone and a chat app keeps its brand, because neither is a system this client can draw. Co-authored-by: bitfun-ai <318544290+bitfun-ai@users.noreply.github.com>
The devices page drew one monitor for every device, and the compact sidebar guessed a device's shape from its own name, so a Linux desktop and a headless host each read as whatever they happened to be called. Both now draw the mark the desktop shell draws, from the same shared table, with this surface's own sizes and colours: the devices page keeps its 20px leading slot and the sidebar its 22px. - RelayDeviceInfo now declares device_kind, which the Relay already sends. It stays optional, so an older Relay or client keeps the neutral mark. - A headless host draws the server silhouette whatever it runs; a device that reports no system this client can place keeps the monitor, and a phone keeps the phone. - The devices page moves "edit name" from a block under every row to an icon button on the row's own line. A row is a button and cannot hold another one, so the action sits beside it rather than inside it. - The model and system line ellipsizes, and moves to its own line when it does not fit beside the name, instead of squeezing the name at phone widths. Co-authored-by: bitfun-ai <318544290+bitfun-ai@users.noreply.github.com>
Lifecycle, dirty, unpublished commits, locked and missing read as state, not as another run of muted text beside the branch name: each becomes a StatusPill with the tone its state deserves, and the session count gets its own class. The project header aligns the group count on the workspace name's baseline, and an unused actions rule is dropped with it. Co-authored-by: bitfun-ai <318544290+bitfun-ai@users.noreply.github.com>
bobleer
force-pushed
the
lwb/device-system-marks-and-mobile-devices
branch
from
September 21, 2026 02:55
755a784 to
280729a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Every surface that names a device now draws the system that device reported, instead of one generic monitor, and mobile web draws the same marks as the desktop shell.
Fixes # (none - no issue filed)
Type and Areas
Type: Feature / UI/UX
Areas: web UI, mobile web, shared contracts (presentation data)
Motivation / Impact
The device overview already knew which system every device reported, and drew the same monitor for all of them: in the footer trigger, the attached row, the carousel and the connect list. Mobile web did the same in its devices page, and its compact sidebar guessed a device's shape from its own name, so
lwb_serveronly read as a server because it is called "server".What changes:
src/shared/device-system, so the desktop shell and mobile web draw one device the same way while keeping their own sizes, colours and placement (desktop icon tokens, mobile 20/22px).remote_connect_get_device_infoanswers with identity only, so the previous local source was always empty and the local device silently fell back to the neutral mark.StatusPills with the tone each state deserves.Compatibility:
device_kindis declared as optional on the mobile web directory row, so an older Relay or client that does not send it keeps the neutral mark. No persisted shape, command, or wire contract changes.Verification
web UI:
pnpm --dir src/web-ui run test:run src/app/components/NavPanel src/app/components/RemoteConnectDialog src/infrastructure/config/components/WorktreeSettingsPage.test.tsx- 50 files, 351 tests passpnpm run check:web- exit 0 (Appearance contract, theme visual governance, type-check)mobile web:
pnpm --dir src/mobile-web run type-check- exit 0pnpm run build:mobile-web- exit 0pnpm --dir src/mobile-web run test:account-login- 17 tests passpnpm --dir src/mobile-web run test:ui-components- 15 tests passpnpm --dir src/mobile-web run test:account-browser- 17 tests pass (real Chrome, simulated Relay)repository:
pnpm run check:repo-hygiene- exit 0pnpm run check:core-boundaries- exit 0Mark geometry and alignment were measured in a real browser rather than eyeballed: each mark's ink box is centred in its own view box, and after the optical correction every mark's mass centre sits within 0.07px of the text's ink centre at the trigger's size (the Apple alone carries a correction, as requested).
Remote scenarios: the marks come from facts the Relay already carries per device, so they are unchanged on remote workspaces, remote control and peer device mode;
remote_connect_get_device_infoisControllerLocaland stays so. Mobile web remains read-only over the same Relay directory.Reviewer Notes
src/shared/device-system/deviceSystemMarks.tsis the shared mark table plus the os-to-system resolver;src/web-ui/.../deviceSystemMarks.tskeeps only this shell's artwork-to-mark map and re-exports the shared table.THIRD_PARTY_NOTICES.md).opticalShiftper mark is a measured value, documented where it is defined; marks whose mass is already centred carry 0 and render no inline style at all.RemoteConnectDialog.contract.test.tsasserted the footer foreground token on themessage-appblock. One row of peers now shares one colour, so the token moved to the row that owns it: the contract moved with it and now covers every device kind instead of the chat brand alone. The chat mark still carries its own unframed contract.Checklist