chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
---
|
||||
name: refresh_app_hub
|
||||
kind: pipeline
|
||||
lang: bash
|
||||
domain: pipelines
|
||||
version: "1.1.0"
|
||||
purity: impure
|
||||
signature: "refresh_app_hub([--hub-dir <path>] [--size <px>] [--no-restart] [--style <s>]) -> void"
|
||||
description: "Pipeline orquestador que regenera los iconos PNG y el manifest TSV del App Hub desde registry.db y reinicia el proceso app_hub_launcher en Windows. Cubre el ciclo completo: export icons → export manifest → taskkill → relaunch. Default style=white_duotone (duotone Phosphor blanco sobre bg accent). Override con --style fill_white | adaptive_duotone."
|
||||
tags: [hub, launcher, icons, manifest, cpp, windows, wsl, cpp-windows, deploy]
|
||||
uses_functions:
|
||||
- export_hub_icons_py_infra
|
||||
- export_hub_manifest_py_infra
|
||||
- is_cpp_app_running_windows_bash_infra
|
||||
- launch_cpp_app_windows_bash_infra
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: []
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "bash/functions/pipelines/refresh_app_hub.sh"
|
||||
params:
|
||||
- name: "--hub-dir"
|
||||
desc: "Directorio local_files del hub en Windows (accesible desde WSL). Default: /mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files. Los PNGs se escriben en <hub-dir>/icons/ y el manifest en <hub-dir>/hub_manifest.tsv."
|
||||
- name: "--size"
|
||||
desc: "Lado en pixels de cada PNG de icono. Default 64. Pasar 128 para pantallas HiDPI."
|
||||
- name: "--no-restart"
|
||||
desc: "Si está presente, solo regenera icons + manifest sin tocar el proceso del hub (pasos 3 y 4 se marcan como skipped). Útil para actualizar los archivos mientras el hub está cerrado manualmente."
|
||||
output: "Imprime resumen de 4 pasos (icons exported, manifest rows, hub killed/skipped, hub launched) y finaliza con 'OK: app_hub refreshed'. Exit 1 si falla cualquier paso, con mensaje indicando cuál."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
# Caso habitual: regenerar todo y reiniciar el hub
|
||||
./fn run refresh_app_hub
|
||||
|
||||
# Solo regenerar iconos y manifest, sin tocar el proceso
|
||||
./fn run refresh_app_hub --no-restart
|
||||
|
||||
# Iconos a 128px para pantalla HiDPI o hub-dir personalizado
|
||||
./fn run refresh_app_hub --size 128
|
||||
./fn run refresh_app_hub --hub-dir /mnt/d/MiDesktop/apps/app_hub_launcher/local_files
|
||||
|
||||
# Combinado
|
||||
./fn run refresh_app_hub --size 128 --hub-dir /mnt/d/MiDesktop/apps/app_hub_launcher/local_files
|
||||
```
|
||||
|
||||
Salida esperada:
|
||||
|
||||
```
|
||||
[1/4] Exporting PNG icons (size=64px) → /mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files/icons ...
|
||||
[1/4] PNG icons exported: 12
|
||||
[2/4] Exporting manifest → .../hub_manifest.tsv ...
|
||||
[2/4] Manifest exported: 12 rows
|
||||
[3/4] Hub running → killing app_hub_launcher.exe ...
|
||||
[3/4] Hub running → killed
|
||||
[4/4] Launching app_hub_launcher ...
|
||||
[4/4] Hub launched
|
||||
OK: app_hub refreshed
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Ejecutar este pipeline después de:
|
||||
- Cambiar el bloque `icon:` (`phosphor`, `accent`) en cualquier `app.md` C++.
|
||||
- Modificar la `description` de una app C++ (se refleja en el manifest TSV).
|
||||
- Añadir una app nueva con `lang: cpp` y `framework: imgui` al registry.
|
||||
- Cambiar el `name` de una app imgui (el PNG y la fila TSV usan el `name`).
|
||||
|
||||
En todos esos casos el hub cachea los archivos al arrancar, así que el reinicio es obligatorio para ver los cambios.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Cache al arrancar**: `app_hub_launcher` carga `local_files/icons/*.png` y `local_files/hub_manifest.tsv` una sola vez al inicio. Sin el reinicio los cambios no se ven aunque los archivos estén actualizados. Usar `--no-restart` solo si el hub está cerrado o si quieres preparar los archivos antes de lanzarlo a mano.
|
||||
- **Paths Windows requieren WSL `/mnt/c/`**: el `--hub-dir` debe ser una ruta accesible desde WSL2. Las rutas `C:\...` nativas no funcionan en Bash — convertirlas con `wslpath -u 'C:\...'` antes de pasar el flag.
|
||||
- **`taskkill` solo funciona en WSL con acceso a Windows tools**: si `tasklist.exe` y `taskkill.exe` no están en `$PATH` (instalación WSL sin interop habilitado), el paso 3 fallará. Verificar con `command -v tasklist.exe`.
|
||||
- **`powershell.exe` necesario para el lanzamiento**: `launch_cpp_app_windows` usa `Start-Process` de PowerShell. Si PowerShell no está en `$PATH`, el paso 4 fallará.
|
||||
- **`export_hub_icons` requiere Phosphor SVGs**: los SVGs deben existir en `sources/phosphor-core/assets/fill/`. Si no están clonados, las apps sin SVG se omiten (skip) sin abortar; el count final puede ser menor al esperado. Clonar con: `git clone https://github.com/phosphor-icons/core.git sources/phosphor-core`.
|
||||
- **Idempotente**: lanzable N veces. Si el hub no está corriendo, el paso 3 se salta y el paso 4 lo lanza igualmente. Si ya está corriendo, lo mata y lo relanza.
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env bash
|
||||
# refresh_app_hub — Pipeline: regenera icons + manifest del App Hub y reinicia el proceso
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
|
||||
source "$SCRIPT_DIR/../infra/is_cpp_app_running_windows.sh"
|
||||
source "$SCRIPT_DIR/../infra/launch_cpp_app_windows.sh"
|
||||
|
||||
PYTHON="${REGISTRY_ROOT}/python/.venv/bin/python3"
|
||||
HUB_APP="app_hub_launcher"
|
||||
|
||||
refresh_app_hub() {
|
||||
local hub_dir="/mnt/c/Users/lucas/Desktop/apps/app_hub_launcher/local_files"
|
||||
local size=64
|
||||
local no_restart=0
|
||||
local style="white_duotone"
|
||||
|
||||
# Parsear flags
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--hub-dir)
|
||||
hub_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--size)
|
||||
size="$2"
|
||||
shift 2
|
||||
;;
|
||||
--no-restart)
|
||||
no_restart=1
|
||||
shift
|
||||
;;
|
||||
--style)
|
||||
style="$2"
|
||||
shift 2
|
||||
;;
|
||||
-*)
|
||||
echo "refresh_app_hub: flag desconocido: $1" >&2
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
echo "refresh_app_hub: argumento inesperado: $1" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local icons_dir="${hub_dir}/icons"
|
||||
local manifest_path="${hub_dir}/hub_manifest.tsv"
|
||||
|
||||
# Paso 1: exportar PNGs de iconos
|
||||
echo "[1/4] Exporting PNG icons (size=${size}px) → ${icons_dir} ..."
|
||||
local icons_json
|
||||
icons_json=$(
|
||||
PYTHONPATH="${REGISTRY_ROOT}/python/functions" \
|
||||
FN_REGISTRY_ROOT="${REGISTRY_ROOT}" \
|
||||
"$PYTHON" \
|
||||
"${REGISTRY_ROOT}/python/functions/infra/export_hub_icons.py" \
|
||||
"$icons_dir" \
|
||||
--size "$size" \
|
||||
--registry-root "$REGISTRY_ROOT" \
|
||||
--style "$style"
|
||||
) || {
|
||||
echo "ERROR [1/4]: export_hub_icons falló" >&2
|
||||
return 1
|
||||
}
|
||||
local icon_count
|
||||
icon_count=$(echo "$icons_json" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['count'])" 2>/dev/null || echo "?")
|
||||
echo "[1/4] PNG icons exported: ${icon_count}"
|
||||
|
||||
# Paso 2: exportar TSV manifest
|
||||
echo "[2/4] Exporting manifest → ${manifest_path} ..."
|
||||
local manifest_json
|
||||
manifest_json=$(
|
||||
PYTHONPATH="${REGISTRY_ROOT}/python/functions" \
|
||||
FN_REGISTRY_ROOT="${REGISTRY_ROOT}" \
|
||||
"$PYTHON" \
|
||||
"${REGISTRY_ROOT}/python/functions/infra/export_hub_manifest.py" \
|
||||
"$manifest_path" \
|
||||
--registry-root "$REGISTRY_ROOT"
|
||||
) || {
|
||||
echo "ERROR [2/4]: export_hub_manifest falló" >&2
|
||||
return 1
|
||||
}
|
||||
local manifest_count
|
||||
manifest_count=$(echo "$manifest_json" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['count'])" 2>/dev/null || echo "?")
|
||||
echo "[2/4] Manifest exported: ${manifest_count} rows"
|
||||
|
||||
# Si --no-restart, terminar aqui
|
||||
if [[ $no_restart -eq 1 ]]; then
|
||||
echo "[3/4] Kill skipped (--no-restart)"
|
||||
echo "[4/4] Launch skipped (--no-restart)"
|
||||
echo "OK: app_hub refreshed (no-restart)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Paso 3: matar el hub si está corriendo
|
||||
local running=0
|
||||
if is_cpp_app_running_windows "$HUB_APP" >/dev/null 2>&1; then
|
||||
running=1
|
||||
fi
|
||||
|
||||
if [[ $running -eq 1 ]]; then
|
||||
echo "[3/4] Hub running → killing ${HUB_APP}.exe ..."
|
||||
taskkill.exe /IM "${HUB_APP}.exe" /F >/dev/null 2>&1 || {
|
||||
echo "ERROR [3/4]: taskkill falló para ${HUB_APP}.exe" >&2
|
||||
return 1
|
||||
}
|
||||
# Pequeña pausa para que Windows libere el handle antes del relanzamiento
|
||||
sleep 1
|
||||
echo "[3/4] Hub running → killed"
|
||||
else
|
||||
echo "[3/4] Hub not running → skip kill"
|
||||
fi
|
||||
|
||||
# Paso 4: relanzar el hub
|
||||
echo "[4/4] Launching ${HUB_APP} ..."
|
||||
if ! launch_cpp_app_windows "$HUB_APP"; then
|
||||
echo "ERROR [4/4]: launch_cpp_app_windows falló para '${HUB_APP}'" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "[4/4] Hub launched"
|
||||
|
||||
echo "OK: app_hub refreshed"
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente (fn run lo invoca como script)
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
refresh_app_hub "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user