Add menubar-pet, the Swift menu-bar face !28

merged merged by cmc on 2026-09-04 17:26 UTC · krz/ambient-companions:feat/menubar-pet into main

cmc

Third of the menubar-pet stack.

A sibling SwiftPM package — kept out of macos-collector, which is the hardware collector, not a renderer. scripts/bundle.sh assembles a .app with LSUIElement set; SwiftPM cannot emit a bundle and an .xcodeproj would stop swift build being the whole story.

The app runs pet-life on a timer and draws it. No socket, no wire decoding — one decoder, in Rust.

Two deviations from the design, both flagged. PetKit is a library rather than everything sitting in the executable, so the contract with pet-life is testable — and it is tested, against the exact bytes pet-life's own test pins. The design said the Swift side would go untested; the Rust-to-Swift contract has drifted twice here and a pinned fixture caught it both times, so this is the part worth a test. The dead-pet case is covered specifically, since name: null is what a plain String would break on and it is exactly what the app must render.

The hook now gates both Swift packages and asserts the bundle assembles.

Verified: the real bundle launches, survives past two poll cycles, and quits cleanly. I have not visually confirmed the menu-bar rendering — that needs a human looking at the menu bar.

Closes #18