The mode switch posts didChangeScreenParameters synchronously; reconcile ran
nested before the output was registered and opened a second window/receiver,
which stayed visible after stopping. Register first, never nest reconcile,
handle the notification asynchronously. Switching sources keeps the 50 Hz mode.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Coordinator: restores live state on launch, role-based Bonjour server/browser,
node adopts commands, control keeps desired config per node and re-sends on reconnect
- Scene menu (load, save, save as, export, import), settings (role, interface, login item)
- Remote screens with status on the control; node banner
- Developer ID signing with hardened runtime and audio-input entitlement
- Retry and clear message when macOS blocks Bonjour
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- NDIReceiver: per-source receive thread, IOSurface pixel buffers, watchdog reconnect
- VideoOutput: borderless output window above menu bar, AVSampleBufferVideoRenderer,
50 Hz display mode for app lifetime, display sleep assertion
- Screen cards with drag and drop, live fps and frame loss
- Per-minute stats CSV in ~/Library/Logs/Musubi for long-run tests
- --route launch argument for scripted tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>