# Livrets — cible desktop macOS — Plan d'implémentation > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Lancer l'app Livrets en natif sur macOS via `./gradlew :desktopApp:run`, sans toucher au code existant. **Architecture:** Nouveau module hôte `desktopApp` (kotlin-jvm + Compose Multiplatform desktop) qui dépend de `:sharedUI` et ouvre `App(filesDirPath = ~/.livrets)` dans une fenêtre 480×800 — miroir d'`androidApp`. **Tech Stack:** Kotlin 2.4.10, Compose Multiplatform 1.12.0 (desktop), JVM 17 bytecode (JDK 18 hôte). **Spec:** `docs/superpowers/specs/2026-08-28-livrets-desktop-design.md` ## Global Constraints - Zéro modification des modules existants (`sharedUI`, `androidApp`, `iosApp`) hormis `settings.gradle.kts` (+include) et `README.MD` (+section) - UI texte français ; pas de commentaires dans le code ; YAGNI (pas de packaging, pas d'icône) - Faisabilité déjà validée en sandbox sur cette machine (module, `:desktopApp:jar`, `:desktopApp:run` avec fenêtre visible) - Tests régression : `./gradlew :sharedUI:jvmTest` (20/20) doit rester vert --- ### Task 1: Module desktopApp + lancement + README **Files:** - Modify: `settings.gradle.kts` (+include) - Create: `desktopApp/build.gradle.kts`, `desktopApp/src/main/kotlin/com/livrets/desktop/Main.kt` - Modify: `README.MD` (+section macOS desktop) **Interfaces:** - Consumes: `App(filesDirPath: String, onThemeChanged: @Composable (isDark: Boolean) -> Unit = {})` (App.kt existant — signature inchangée) - Produces: point d'entrée desktop `com.livrets.desktop.MainKt` ; tâches `:desktopApp:run` / `:desktopApp:jar` - [ ] **Step 1: Inclure le module et créer son build file** Dans `settings.gradle.kts`, après la ligne `include(":androidApp")`, ajouter : ```kotlin include(":desktopApp") ``` Créer `desktopApp/build.gradle.kts` : ```kotlin import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlin.jvm) alias(libs.plugins.compose.compiler) alias(libs.plugins.compose.multiplatform) } java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } kotlin { compilerOptions { jvmTarget.set(JvmTarget.JVM_17) } } dependencies { implementation(project(":sharedUI")) implementation(compose.desktop.currentOs) } compose.desktop { application { mainClass = "com.livrets.desktop.MainKt" } } ``` (Les alias `kotlin-jvm`, `compose-compiler`, `compose-multiplatform` sont déjà déclarés `apply(false)` à la racine ; `compile.desktop.currentOs` se résout via le plugin compose-multiplatform, hors catalogue.) - [ ] **Step 2: Créer le point d'entrée desktop** Créer `desktopApp/src/main/kotlin/com/livrets/desktop/Main.kt` : ```kotlin package com.livrets.desktop import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Window import androidx.compose.ui.window.application import androidx.compose.ui.window.rememberWindowState import com.livrets.App fun main() = application { Window( onCloseRequest = ::exitApplication, title = "Livrets", state = rememberWindowState(width = 480.dp, height = 800.dp), ) { App(filesDirPath = storageDir()) } } private fun storageDir(): String = System.getProperty("user.home") + "/.livrets" ``` - [ ] **Step 3: Vérifier la compilation** ```bash ./gradlew :desktopApp:jar :sharedUI:jvmTest ``` Attendu : `BUILD SUCCESSFUL`, 20/20 tests. (Si erreur « Inconsistent JVM Target Compatibility » : le fichier ci-dessus est déjà corrigé — vérifier que `java {}` ET `kotlin { jvmTarget }` sont bien les deux présents.) - [ ] **Step 4: Ajouter la section desktop au README** Dans `README.MD`, après la section `### iOS`, ajouter : ```markdown ### macOS desktop Lancer l'application en fenêtre (480×800) depuis le terminal : ```bash ./gradlew :desktopApp:run ``` Les données sont stockées dans `~/.livrets/`. ``` - [ ] **Step 5: Commit** ```bash git add -A git commit -m "feat: cible desktop macOS via :desktopApp:run" ``` - [ ] **Step 6: Vérification du lancement (contrôleur ou utilisateur)** ```bash ./gradlew :desktopApp:run ``` Attendu : fenêtre « Livrets » 480×800, écran d'accueil avec les 3 réglages. Fermer la fenêtre arrête le processus. (Bloque jusqu'à fermeture — à lancer de façon interactive, pas dans la boucle de tests.) --- ## Notes d'exécution - Ne pas toucher à `sharedUI`/`androidApp`/`iosApp` — si `:desktopApp:jar` révèle une incompatibilité, rapporter BLOCKED avec la sortie exacte. - `:desktopApp:run` est interactif (fenêtre bloquante) : la vérification automatisée = `:desktopApp:jar` + processus JVM vivant pendant un run en arrière-plan ; la confirmation visuelle finale revient à l'utilisateur. - `~/.livrets` est créé à la première partie terminée (HistoryRepository.createDirectories) ; l'écran Historique affiche « Aucune partie enregistrée » avant.