Files
livrets/docs/superpowers/plans/2026-08-28-livrets-desktop.md

5.0 KiB
Raw Permalink Blame History

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 :

include(":desktopApp")

Créer desktopApp/build.gradle.kts :

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 :

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
./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 :

### 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)
./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.