Files
james.maesandClaude Opus 4.7 6995a1bdeb Fix duplicate "unknown" finger row + reorganize menus by concern
## Finger counting fix
Two writers were racing on CurrentStateStore.fingerCounts:
- FingerCounter.analyze writes by actual chirality (left/right/unknown)
  from VNHumanHandPoseObservation.chirality
- The CurrentStateStore event-bus subscriber ALSO wrote, but always to
  the key "unknown" regardless of which hand actually fired the event

Result: any frame with a hand showed both the correct "Left: 3 fingers"
row AND a duplicate "Unknown: 3 fingers" row in the Status panel.

Plus stale entries: a hand leaving the frame didn't clean up. The Left
entry stuck around forever.

Fix:
- CurrentStateStore is no longer a writer for finger counts from the
  bus path (the subscriber comment now flags FingerCounter as the
  authoritative writer).
- FingerCounter.analyze gets two new behaviors:
  - When hands.isEmpty → CurrentStateStore.clearFingers() wipes all
    stale per-chirality entries.
  - When at least one hand is detected → it records every observed
    chirality this cycle, then calls ageFingerEntries(currentSeen:at:)
    to drop chirality entries that weren't seen this frame and are
    older than the 1.2-second staleness window.

## Menu reorganization
Followed Mac UI conventions instead of the previous "App menu = dumping
ground" layout.

Before (everything in 3 menus):
- App: Settings, Log Stream, Status, Save Snapshot, Start Recording, Quit
- Faces: Enroll, Forget, Detection History
- Camera: Devices ▶, Refresh, Privacy Mode

After (5 menus by concern):
- VisionPOC: Settings (⌘,), Hide/Hide Others/Show All, Quit (⌘Q)
- File: Save Snapshot (⌘S), Start/Stop Recording (⇧⌘R)
- View: Status Panel (⌘I), Detection History (⇧⌘H), Log Stream (⌘L)
- Camera: <devices flat list>, Refresh List, Privacy Mode (⇧⌘P)
- Faces: Enroll Face (⌘E), Forget Face (⇧⌘E)

Notes:
- Camera devices are now a flat list at the Camera menu's root (no
  nested submenu) for easier access. The menu uses NSMenuDelegate to
  rebuild itself when opened, so devices are always fresh.
- Detection History keybinding moved from ⌘H to ⇧⌘H because ⌘H is the
  standard macOS "Hide application" shortcut.
- A small `menuItem(_:action:key:mods:target:)` helper drains the
  installMainMenu function from boilerplate so the 5 menus fit on one
  screen of code.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 17:55:01 -05:00
..