2a3d780347
Adds `fn doctor` read-only diagnostic command with subcommands artefacts, services, sync, uses-functions, unused, and --json flag for agents. Each subcommand wraps a registry function in functions/infra/. New functions: - artefact_doctor, services_status, pc_locations_drift, audit_uses_functions, find_unused_functions (Go diagnostics) - backup_sqlite_db, rotate_backups, wait_for_http, wait_for_port, port_kill, tail_journal, pre_commit_hook_install (bash utilities) - notify_telegram (Go HTTP) - backup_all pipeline (tag launcher) Plus prior session leftovers (scan_secrets_in_dirty, append_diary_entry, git utilities, http_session_cookie_middleware, compile/full-git pipelines). Fixes pc_locations_drift filepath.Join bug with absolute dir_path. Documents fn doctor in CLAUDE.md, .claude/rules/fn_doctor.md (rule 23), docs/architecture.md, CHANGELOG.md (2026-05-07), and diary entry. First fn doctor uses-functions run found drift in 7/12 apps (deuda para sincronizar app.md con imports reales). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
2.7 KiB
Bash
84 lines
2.7 KiB
Bash
#!/usr/bin/env bash
|
|
# resolve_cpp_app_dir — Resuelve nombre y directorio absoluto de una app C++ del registry.
|
|
# Sin arg: deduce desde CWD si esta dentro de cpp/apps/<X>/ o projects/*/apps/<X>/.
|
|
# Con arg: usa el nombre directamente y busca en ambas ubicaciones.
|
|
# Salida: "<app_name>\t<absolute_dir_path>" en stdout (TAB separado), exit 0.
|
|
# Error: lista apps disponibles en stderr + exit 1.
|
|
|
|
resolve_cpp_app_dir() {
|
|
local app_arg="${1:-}"
|
|
local root="${FN_REGISTRY_ROOT:-/home/lucas/fn_registry}"
|
|
|
|
# --- Deducir desde CWD si no hay argumento ---
|
|
if [ -z "$app_arg" ]; then
|
|
local cwd
|
|
cwd="$(pwd)"
|
|
case "$cwd" in
|
|
"$root"/cpp/apps/*/|"$root"/cpp/apps/*)
|
|
# Extraer primer segmento tras cpp/apps/
|
|
local rel="${cwd#"$root/cpp/apps/"}"
|
|
app_arg="${rel%%/*}"
|
|
;;
|
|
"$root"/projects/*/apps/*/|"$root"/projects/*/apps/*)
|
|
# Extraer primer segmento tras la ultima /apps/
|
|
local rel="${cwd#"$root/projects/"}"
|
|
rel="${rel#*/apps/}"
|
|
app_arg="${rel%%/*}"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# --- Aun vacio: listar y abortar ---
|
|
if [ -z "$app_arg" ]; then
|
|
echo "ERROR: no se pudo deducir la app desde el directorio actual." >&2
|
|
echo "" >&2
|
|
echo "Apps disponibles:" >&2
|
|
{
|
|
ls "$root/cpp/apps/" 2>/dev/null | sed 's/^/ cpp\/apps\//'
|
|
for proj in "$root"/projects/*/apps/; do
|
|
ls "$proj" 2>/dev/null | sed "s|^| $(echo "$proj" | sed "s|$root/||")|"
|
|
done
|
|
} >&2
|
|
echo "" >&2
|
|
echo "Uso: resolve_cpp_app_dir <app_name>" >&2
|
|
return 1
|
|
fi
|
|
|
|
# --- Buscar directorio real ---
|
|
local app_dir=""
|
|
|
|
# Primero: cpp/apps/<X>
|
|
if [ -d "$root/cpp/apps/$app_arg" ]; then
|
|
app_dir="$root/cpp/apps/$app_arg"
|
|
fi
|
|
|
|
# Segundo: projects/*/apps/<X> (primer match)
|
|
if [ -z "$app_dir" ]; then
|
|
for cand in "$root"/projects/*/apps/"$app_arg"; do
|
|
if [ -d "$cand" ]; then
|
|
app_dir="$cand"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -z "$app_dir" ]; then
|
|
echo "ERROR: no se encuentra app '$app_arg' en cpp/apps/ ni en projects/*/apps/" >&2
|
|
echo "" >&2
|
|
echo "Apps disponibles:" >&2
|
|
{
|
|
ls "$root/cpp/apps/" 2>/dev/null | sed 's/^/ cpp\/apps\//'
|
|
for proj in "$root"/projects/*/apps/; do
|
|
ls "$proj" 2>/dev/null | sed "s|^| $(echo "$proj" | sed "s|$root/||")|"
|
|
done
|
|
} >&2
|
|
return 1
|
|
fi
|
|
|
|
printf '%s\t%s\n' "$app_arg" "$app_dir"
|
|
}
|
|
|
|
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|
resolve_cpp_app_dir "$@"
|
|
fi
|