> Note (2026-05-18): the `AV-Live-Body` directory has been archived to `_archive-AV-Live-Body/` — superseded by the new app at `/avlivebody-mac/`. See `docs/superpowers/specs/2026-05-18-avlivebody-macos-rewrite-design.md`. # launcher — AVLiveLauncher App menubar macOS (SwiftUI, SwiftPM, macOS 11+) qui démarre/arrête `sclang+scsynth`, le serveur web et `oscope-of`, log les sorties, et expose un mode picker. ## Build ```bash cd launcher ./build.sh # script standard # ou manuellement : swift build -c release .build/release/AVLiveLauncher ``` Cible : **macOS 11+**, Swift 5.7+. Package Swift, pas de Xcode project requis. ## Modules | Fichier | Rôle | |---------|------| | `AVLiveLauncherApp.swift` | `@main`, scene menubar, app lifecycle | | `MenuBarContent.swift` | UI du menu (start/stop, état des process) | | `ModePickerWindow.swift` | Fenêtre picker de mode (data-only vs full vs ...) | | `ProcessManager.swift` | Spawn / kill / monitor des process enfants | | `OSCSender.swift` | Envoi OSC (typiquement vers `:57121` sclang, `:57123` oscope) | | `LogView.swift` | UI live des logs stdout/stderr des process | | `AV-Live-Body/` | Ressources / modèles annexes (body mesh assets) | ## Conventions - Toute opération asynchrone : `Task { @MainActor in ... }` pour UI updates. - Pas de bloc `DispatchQueue.main.sync` (deadlock garanti depuis MainActor). - `ProcessManager` est `@MainActor` — interactions process via async/await, jamais `Process.waitUntilExit()` bloquant en main. - Chemins absolus vers les binaires (sclang, node, oscope-of) résolus une fois au startup et stockés ; ne pas redécouvrir à chaque démarrage. - Logs ring-buffer borné (pas de croissance illimitée dans `LogView`). ## Anti-patterns - Ne pas committer `build/` ni `.build/`. - Ne pas hardcoder un chemin utilisateur (`/Users/electron/...`) — passer par `FileManager` + chemins relatifs au repo ou bookmarks. - Ne pas mélanger `Process.terminate()` et `kill -9` sans escalade (SIGTERM → wait → SIGKILL). - Pas d'AppKit `NSApp.terminate` direct depuis un closure background — toujours hop sur MainActor. - Ne pas dépendre d'un Xcode project : le SwiftPM `Package.swift` est la source de vérité.