diff --git a/CLAUDE.md b/CLAUDE.md index 0caf1e3..81527a4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -73,10 +73,11 @@ Instructions pour Claude Code sur ce projet. Lis ce fichier en début de session - Renommer le repo Gitea `coach-ios` → `coach-mobile` - Upgrade macOS 26 sur Mac mini pour reprendre les builds iOS - Play Console validation (~3-5j, $25 one-shot) pour upload Android -- **watchOS live workout compagnon** (chantier ACTIF depuis 2026-05-24) — plan - technique complet dans `docs/watchos-live-workout-plan.md`. Handoff pour - Claude Code Mac dans `HANDOFF-WATCHOS.md` (à lire en 1er si tu reprends ce - chantier). +- **watchOS live workout compagnon** — Phases 1-3 RÉALISÉES (2026-05-25, sur + `main`) : target `CoachWatch` + 4 fichiers Swift watchOS + plugin Capacitor + `CoachLiveBridge`. Builds verts (watchsimulator + App embed), UI validée sur + sim. **Reste : test device + TestFlight.** Détails et deltas watchOS 26 dans + `docs/watchos-live-workout-plan.md` (section "Avancement réel"). - Push workouts vers Apple Watch (HKWorkoutPlan) / Polar (Training Targets API) / Garmin — backlog 2026-05-12 ## ⚠️ Limites connues sync diff --git a/docs/watchos-live-workout-plan.md b/docs/watchos-live-workout-plan.md index af26794..626a5a6 100644 --- a/docs/watchos-live-workout-plan.md +++ b/docs/watchos-live-workout-plan.md @@ -1,6 +1,6 @@ # Chantier watchOS — Live Workout sur iPhone -**Statut** : plan validé, prêt à exécuter sur Mac mini avec Xcode. +**Statut** : Phases 1-3 RÉALISÉES (Mac, 2026-05-25, voir "Avancement réel" en bas). Reste : test device + TestFlight. **Owner exécution** : Claude Code lancé sur le Mac (cd `~/coach-ios && claude`). **Origine** : memory `project_coach_watchos_live.md` + session Linux 2026-05-24. @@ -442,3 +442,45 @@ setInterval(() => { Le Claude Mac doit lire ces 4 pages dans sa session pour valider les signatures avant de les utiliser. + +## Avancement réel (Mac, 2026-05-25) + +Env réel : **Xcode 26.5 / SDK watchOS 26.5** (pas watchOS 11). Signatures +vérifiées directement dans les `.swiftinterface` / headers du SDK installé +(la doc Apple ne se rend pas via WebFetch). + +### Fait (Phases 1-3) — sur `main` + +- **Phase 1** (commit `5d60a40`) : target `CoachWatch` créée **par script + `xcodeproj`** (pas le wizard — gem CocoaPods `xcodeproj` installée en + user-level), bundle `ch.hypnotruck.coach.watchkitapp`, embed "Embed Watch + Content" + dépendance App→CoachWatch, schemes partagés App + CoachWatch. + Entitlement HealthKit + Info.plist FR + `WKBackgroundModes=workout-processing`. +- **Phase 2** : `ConnectivityManager` (`5864cfc`), `WorkoutManager` (`c6f5a7f` + + fix `167c1e4`), UI + entry point (`5185298`). +- **Phase 3** (commit `b2e9836`) : plugin `CoachLiveBridgePlugin` (jsName + `CoachLiveBridge`) enregistré dans `MainViewController.capacitorDidLoad()`. +- **Fix** (`1cd96de`) : `WKCompanionAppBundleIdentifier=ch.hypnotruck.coach` + (sans ça l'app watch refuse de s'installer — détecté au smoke test simctl). + +Validé : build watchsimulator + build App (embed) iphonesimulator, **0 warning** ; +app watch installée + lancée sur sim Apple Watch Series 11 (watchOS 26.5), +UI picker rendue. + +### Deltas vs le pseudocode du plan (corrigés) + +1. `ConnectivityManager` **n'est pas** `@MainActor` (le plan le disait) : les + callbacks `WCSessionDelegate` arrivent hors-main → délégué normal + hop main. +2. `WorkoutManager` **est** `@MainActor` (donc Sendable) avec délégués HealthKit + `nonisolated` qui hoppent via `Task { @MainActor }` — sinon warnings/erreurs + concurrency Swift 6 (capture de self non-Sendable). +3. Enregistrement plugin Capacitor 8 = `bridge?.registerPluginInstance(...)` + dans `capacitorDidLoad()` (PAS la macro `CAP_PLUGIN`), CAPBridgedPlugin. + +### Reste à faire + +- **Test device** (FC réelle, WatchConnectivity → /live) : nécessite l'Apple + Watch physique + signing (impossible en simulateur, pas de FC réelle). +- **Cross-check** : la page `/live` déployée doit utiliser `registerPlugin('CoachLiveBridge')` + et lire `heartRate / activeEnergyKcal / distanceMeters / elapsedSec / ts`. +- TestFlight interne.