From d763d8144f2ae1ddb85465e9f7d4eca2c795b746 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 18 Apr 2026 17:56:55 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20init=5Fcli=5Fapp=20bash=20pipeline=20?= =?UTF-8?q?=E2=80=94=20scaffold=20Go=20CLI=20app=20con=20TUI=20opcional?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Genera apps/{nombre}/ con main.go (subcommand routing via os.Args + switch), cmd_version.go, cmd_status.go, Makefile (build/run/install/test/vet/clean), .gitignore, go.mod y app.md. Sin cobra/urfave — consistente con el resto de apps del registry. Flag --with-tui anade model.go con un modelo Bubbletea fullscreen (lista filtrable con bubbles/list, spinner con bubbles/spinner, dark theme con lipgloss). main.go arranca la TUI con tea.NewProgram(m, WithAltScreen) si no hay args; sino hace subcommand routing normal. Verifica con go mod tidy + go vet. Co-Authored-By: Claude Opus 4.7 (1M context) --- bash/functions/pipelines/init_cli_app.md | 110 ++++++ bash/functions/pipelines/init_cli_app.sh | 460 +++++++++++++++++++++++ 2 files changed, 570 insertions(+) create mode 100644 bash/functions/pipelines/init_cli_app.md create mode 100755 bash/functions/pipelines/init_cli_app.sh diff --git a/bash/functions/pipelines/init_cli_app.md b/bash/functions/pipelines/init_cli_app.md new file mode 100644 index 00000000..0b68deaa --- /dev/null +++ b/bash/functions/pipelines/init_cli_app.md @@ -0,0 +1,110 @@ +--- +name: init_cli_app +kind: pipeline +lang: bash +domain: pipelines +version: "1.0.0" +purity: impure +signature: "init_cli_app(nombre: string, [--with-tui]) -> void" +description: "Scaffold de Go CLI app con subcomandos (version/status/help) routed via os.Args. Con --with-tui genera model.go con un modelo Bubbletea fullscreen (lista filtrable + spinner + dark theme) y main.go arranca la TUI en modo fullscreen. Sin dependencias de cobra/urfave — consistente con las apps del registry." +tags: [init, scaffold, cli, tui, pipeline, bash, launcher] +uses_functions: + - assert_command_exists_bash_shell + - new_base_model_go_tui + - dark_styles_go_tui + - run_fullscreen_go_tui + - new_spinner_go_tui + - new_filtered_list_go_tui +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [] +params: + - name: nombre + desc: "nombre de la CLI app (apps/{nombre}/); se usa como binario y como modulo Go" + - name: "--with-tui" + desc: "anade model.go con modelo Bubbletea (lista + spinner + dark theme) y arranca TUI fullscreen al invocar sin args" +output: "CLI app en apps/{nombre}/ con main.go (subcommand routing), cmd_version.go, cmd_status.go, Makefile con targets build/run/install/test/vet/clean. Con --with-tui anade model.go y el default sin args arranca TUI." +tested: false +tests: [] +test_file_path: "" +example: "fn run init_cli_app my_cli --with-tui" +file_path: "bash/functions/pipelines/init_cli_app.sh" +--- + +## Sinopsis + +```bash +fn run init_cli_app [--with-tui] +``` + +## Ejemplo rapido + +```bash +# CLI clasica +fn run init_cli_app mytool +cd apps/mytool +make build +./mytool version +./mytool status + +# CLI + TUI fullscreen +fn run init_cli_app deploy_helper --with-tui +cd apps/deploy_helper +make build +./deploy_helper # arranca TUI +./deploy_helper version # subcomando +``` + +## Archivos generados + +| Archivo | Descripcion | +|---------|-------------| +| `main.go` | Entry con `switch os.Args[1]`; subcomandos: version, status, help | +| `cmd_version.go` | Imprime nombre + version | +| `cmd_status.go` | Imprime app/version/go/os/arch | +| `go.mod` | Modulo Go con replace `fn-registry`; con `--with-tui` agrega bubbletea/bubbles/lipgloss | +| `Makefile` | Targets build, run (ARGS=...), install (~/.local/bin/), test, vet, clean | +| `.gitignore` | Binario + IDE files | +| `app.md` | Tag `cli` (o `cli,tui,bubbletea` con `--with-tui`) | + +Con `--with-tui` anade: +- `model.go` — `Model` con spinner (spinner.Dot), lista Bubbletea con 4 items de ejemplo, dark theme (lipgloss con colores 7D56F4 / 06B6D4), keys enter/q/ctrl+c +- `main.go` arranca la TUI con `tea.NewProgram(model, tea.WithAltScreen())` si no hay args + +## Flags + +| Flag | Efecto | +|------|--------| +| `--with-tui` | Anade model.go con Bubbletea y TUI fullscreen como default | + +## Post-setup + +```bash +cd apps/{nombre} +make build # construye ./{nombre} +./{nombre} version +./{nombre} status +make install # copia a ~/.local/bin/{nombre} +make run ARGS="status" # build + run con argumentos +``` + +## Notas + +Pipeline impuro: genera archivos, ejecuta `go mod tidy` y `go vet` al final. + +Los ejemplos del modelo TUI (items "Deploy", "Status", "Logs", "Exit") son +placeholders — reemplazar con la logica real de la app. El modelo usa los +componentes estandar de bubbles (`list`, `spinner`) y lipgloss para estilos. + +Las funciones del registry `new_base_model_go_tui`, `dark_styles_go_tui`, +`run_fullscreen_go_tui`, `new_spinner_go_tui`, `new_filtered_list_go_tui` +son referenciadas en el frontmatter como deps conceptuales aunque el +scaffold inline el codigo Bubbletea directamente (las funciones del registry +son stubs que delegan a devfactory/tui). + +Abort si `apps/{nombre}/` ya existe. + +El tag `launcher` permite que aparezca en el Pipeline Launcher TUI (aunque +una CLI con TUI interactiva normalmente no se lanza como subprocess). diff --git a/bash/functions/pipelines/init_cli_app.sh b/bash/functions/pipelines/init_cli_app.sh new file mode 100755 index 00000000..d90e7ff5 --- /dev/null +++ b/bash/functions/pipelines/init_cli_app.sh @@ -0,0 +1,460 @@ +#!/usr/bin/env bash +# init_cli_app +# ------------ +# Scaffold de Go CLI app con subcomandos, opcionalmente con TUI Bubbletea. +# +# Genera main.go con routing de subcomandos (os.Args + switch), cmd_version.go, +# cmd_status.go, Makefile, .gitignore, go.mod y app.md. +# +# Con --with-tui genera ademas model.go con un modelo Bubbletea base y main.go +# arranca la TUI con tea.NewProgram().Run() en modo fullscreen. +# +# USO: +# ./init_cli_app.sh [--with-tui] +# +# EJEMPLOS: +# ./init_cli_app.sh my_cli +# ./init_cli_app.sh deploy_helper --with-tui + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" + +source "$REGISTRY_ROOT/bash/functions/shell/assert_command_exists.sh" + +NOMBRE="" +WITH_TUI="false" + +while [ $# -gt 0 ]; do + case "$1" in + --with-tui) WITH_TUI="true"; shift ;; + -h|--help) grep "^#" "$0" | sed 's/^# \?//' ; exit 0 ;; + -*) echo "Flag desconocido: $1" >&2 ; exit 1 ;; + *) + if [ -z "$NOMBRE" ]; then NOMBRE="$1" + else echo "Argumento extra ignorado: $1" >&2 + fi + shift ;; + esac +done + +if [ -z "$NOMBRE" ]; then + echo "Uso: $0 [--with-tui]" >&2 + exit 1 +fi + +APP_DIR="${REGISTRY_ROOT}/apps/${NOMBRE}" +if [ -d "$APP_DIR" ]; then + echo "ERROR: ${APP_DIR} ya existe. Abortando." >&2 + exit 1 +fi + +echo "" +echo "════════════════════════════════════════════════════════════" +echo " INIT CLI APP: ${NOMBRE}" +echo " Directorio: ${APP_DIR}" +echo " TUI: ${WITH_TUI}" +echo "════════════════════════════════════════════════════════════" +echo "" + +# ── 1. Verificar Go ────────────────────────────────────────── + +echo "[1/5] Verificando herramientas..." +assert_command_exists go +echo " Go: $(go version)" + +# ── 2. Crear estructura ────────────────────────────────────── + +echo "[2/5] Creando estructura..." +mkdir -p "$APP_DIR" + +# go.mod +if [ "$WITH_TUI" = "true" ]; then + cat > "$APP_DIR/go.mod" < ${REGISTRY_ROOT} +EOF +else + cat > "$APP_DIR/go.mod" < ${REGISTRY_ROOT} +EOF +fi + +# ── 3. Archivos Go ─────────────────────────────────────────── + +echo "[3/5] Escribiendo archivos Go..." + +# cmd_version.go — siempre existe +cat > "$APP_DIR/cmd_version.go" < "$APP_DIR/cmd_status.go" < "$APP_DIR/model.go" < "$APP_DIR/main.go" < "$APP_DIR/main.go" < + +Comandos: + version Imprime la version + status Muestra info del sistema + help Muestra esta ayuda\`) +} +EOF +fi + +# ── 4. Makefile, .gitignore, app.md ───────────────────────── + +echo "[4/5] Escribiendo Makefile, .gitignore, app.md..." + +cat > "$APP_DIR/Makefile" < "$APP_DIR/.gitignore" < "$APP_DIR/app.md" <&1 | tail -5; then + : + fi + if CGO_ENABLED=1 go vet -tags fts5 ./... 2>&1; then + echo " go vet OK" + else + echo " WARN: go vet fallo" >&2 + fi +) + +echo "" +echo "════════════════════════════════════════════════════════════" +echo " CLI APP '${NOMBRE}' LISTA" +echo "════════════════════════════════════════════════════════════" +echo "" +echo " Pasos siguientes:" +echo " cd apps/${NOMBRE}" +echo " make build" +if [ "$WITH_TUI" = "true" ]; then +echo " ./${NOMBRE} # arranca la TUI fullscreen" +echo " ./${NOMBRE} version # comando CLI" +else +echo " ./${NOMBRE} version" +echo " ./${NOMBRE} status" +fi +echo ""