--- name: init_kotlin_app kind: pipeline lang: bash domain: pipelines version: "1.0.0" purity: impure signature: "init_kotlin_app(name: string, [--project

] [--desc ] [--tags ] [--package ]) -> void" description: "Scaffolder canonico de app Android Kotlin Compose con FnTheme + Roborazzi tests + e2e_checks declarados. Mirror exacto del patron init_cpp_app para el stack Kotlin." tags: [android, kotlin, compose, scaffolder, launcher] uses_functions: - ensure_repo_synced_bash_infra - gradle_run_bash_infra - gradle_assemble_debug_bash_infra - gradle_unit_test_bash_infra - gradle_screenshot_test_bash_infra - fn_theme_kt_ui - fn_tokens_kt_ui uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] params: - name: name desc: "nombre de la app en snake_case. Sera el id en registry.db y el repo dataforge/" - name: "--project" desc: "proyecto bajo projects/ donde crear la app (opcional). Si se omite va a apps//. El project.md debe existir" - name: "--desc" desc: "descripcion breve para el frontmatter app.md (default: 'App Android Kotlin Compose')" - name: "--tags" desc: "tags CSV adicionales para el frontmatter (siempre se anaden kotlin, compose, android)" - name: "--package" desc: "application id Android (default: com.fnregistry.). Ej: com.aurgi.scanner" output: "Stdout con pasos y archivos creados. Exit 0 = scaffold completo y ready para build. Exit !=0 si falla validacion (nombre invalido, destino existe, proyecto inexistente) o git init." tested: false tests: [] test_file_path: "" file_path: "bash/functions/pipelines/init_kotlin_app.sh" --- ## Ejemplo ```bash # App suelta en apps// fn run init_kotlin_app my_scanner --desc "Escaner de documentos" --package "com.aurgi.scanner" # App dentro de un proyecto fn run init_kotlin_app expense_tracker --project budget --desc "Tracker de gastos" --tags "finance,mobile" # Con package id personalizado fn run init_kotlin_app pos_terminal --package "com.aurgi.pos" --desc "Terminal de punto de venta" ``` ## Que genera ``` apps// (o projects/

/apps//) ├── settings.gradle.kts # rootProject + include(:app) + composite build ui ├── build.gradle.kts # top-level (apply false) ├── app/build.gradle.kts # Compose + Material3 + Roborazzi + tests ├── gradle.properties ├── gradlew # stub ejecutable ├── gradle/wrapper/gradle-wrapper.properties # Gradle 8.6 ├── app/ │ └── src/ │ ├── main/ │ │ ├── AndroidManifest.xml # activity con LAUNCHER intent │ │ ├── kotlin// │ │ │ └── MainActivity.kt # FnTheme + Surface + Text(" ready") │ │ └── res/values/strings.xml │ ├── test/kotlin// │ │ └── ExampleScreenshotTest.kt # Roborazzi: captura FnTheme + Surface │ └── androidTest/kotlin// │ └── MainActivityTest.kt # Compose ui-test: assertIsDisplayed(" ready") ├── app.md # frontmatter registry (lang:kt, framework:compose) ├── .gitignore └── README.md ``` ## Composite build La app apunta via `includeBuild` a `kotlin/functions/ui` del registry (FnTheme + FnTokens). El path relativo se calcula automaticamente: | Ubicacion | Path al composite | |---|---| | `apps//` | `../../kotlin/functions/ui` | | `projects/

/apps//` | `../../../../kotlin/functions/ui` | La dependencia se declara como `implementation("fn.compose:ui")` en `app/build.gradle.kts`. ## e2e_checks generados | id | cmd | timeout | |---|---|---| | `unit` | `fn run gradle_unit_test_bash_infra

` | 240s | | `screenshot` | `fn run gradle_screenshot_test_bash_infra ` | 240s | | `build` | `fn run gradle_assemble_debug_bash_infra ` | 360s | | `emu_start` | `fn run android_emulator_start_bash_infra Medium_Phone_API_35` | 240s | | `instrumented` | `fn run gradle_instrumented_test_bash_infra ` | 600s | | `emu_stop` | `fn run android_emulator_stop_bash_infra` | 30s (warning) | ## Despues de crear 1. Completar `uses_functions` en `app.md` cuando la app consuma funciones adicionales del registry. 2. Para tests Roborazzi: los snapshots se generan en `app/src/test/snapshots/images/` (gitignored). Para actualizar golden images: `./gradlew recordRoborazziDebug`. 3. Para tests instrumentados se necesita un AVD creado con `avdmanager create avd -n Medium_Phone_API_35 ...`. ## Notas - `fn_theme_kt_ui` y `fn_tokens_kt_ui` se referencian en `uses_functions` del `app.md` generado aunque todavia no esten indexados en registry.db — son los modulos del composite build. - `ensure_repo_synced_bash_infra` requiere `GITEA_URL` y `GITEA_TOKEN`. Sin ellos se hace `git init + git commit` local y se avisa al usuario. - Si `--project

` se especifica, se ejecuta `fn index` al final para registrar la nueva app.