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