From bef47dde27e4cdf9b50e2bf27e8f10fd7f453c24 Mon Sep 17 00:00:00 2001 From: Rene Luria Date: Fri, 28 Aug 2026 15:54:07 +0200 Subject: [PATCH] docs: plan cible desktop macOS --- .../plans/2026-08-28-livrets-desktop.md | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-28-livrets-desktop.md diff --git a/docs/superpowers/plans/2026-08-28-livrets-desktop.md b/docs/superpowers/plans/2026-08-28-livrets-desktop.md new file mode 100644 index 0000000..8b835fd --- /dev/null +++ b/docs/superpowers/plans/2026-08-28-livrets-desktop.md @@ -0,0 +1,147 @@ +# 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.