#!/usr/bin/env bash # generate_capability_doc — regenera la tabla "Funciones" de una pagina capability # Preserva bloques curated (Ejemplo canonico, Fronteras, Prerequisitos, Notas, etc.) # Usage: generate_capability_doc [--registry ] [--out ] set -euo pipefail # -------------------------------------------------------------------------- # Helpers # -------------------------------------------------------------------------- die() { echo "ERROR: $*" >&2; exit 1; } warn() { echo "WARN: $*" >&2; } # -------------------------------------------------------------------------- # Parse args # -------------------------------------------------------------------------- GROUP="" REGISTRY_PATH="" OUT_PATH="" while [[ $# -gt 0 ]]; do case "$1" in --registry) shift REGISTRY_PATH="${1:-}" [[ -z "$REGISTRY_PATH" ]] && die "--registry requiere un valor" shift ;; --out) shift OUT_PATH="${1:-}" [[ -z "$OUT_PATH" ]] && die "--out requiere un valor" shift ;; -*) die "Opcion desconocida: $1" ;; *) [[ -n "$GROUP" ]] && die "Solo se acepta un . Ya se especifico: '$GROUP'" GROUP="$1" shift ;; esac done [[ -z "$GROUP" ]] && die "Uso: generate_capability_doc [--registry ] [--out ]" # -------------------------------------------------------------------------- # Resolver registry root # -------------------------------------------------------------------------- find_registry_root() { local dir dir="$(pwd)" while [[ "$dir" != "/" ]]; do if [[ -f "$dir/registry.db" ]]; then echo "$dir" return 0 fi dir="$(dirname "$dir")" done return 1 } if [[ -n "$REGISTRY_PATH" ]]; then # Si se pasa un path que termina en registry.db, tomar el directorio if [[ -f "$REGISTRY_PATH" ]]; then REGISTRY_ROOT="$(dirname "$(realpath "$REGISTRY_PATH")")" elif [[ -d "$REGISTRY_PATH" ]]; then REGISTRY_ROOT="$(realpath "$REGISTRY_PATH")" else die "registry no encontrado en: $REGISTRY_PATH" fi else REGISTRY_ROOT="$(find_registry_root)" || die "No se encontro registry.db. Ejecutar desde dentro del registry o pasar --registry." fi DB="$REGISTRY_ROOT/registry.db" [[ -f "$DB" ]] || die "registry.db no encontrado en: $DB" # -------------------------------------------------------------------------- # Resolver output path # -------------------------------------------------------------------------- if [[ -z "$OUT_PATH" ]]; then OUT_PATH="$REGISTRY_ROOT/docs/capabilities/${GROUP}.md" fi # -------------------------------------------------------------------------- # Consultar funciones del grupo # -------------------------------------------------------------------------- # JOIN custom entre functions y json_each(tags) — excepcion autorizada para sqlite3 directo. # Usamos U+001F (ASCII Unit Separator) como separador de campos para evitar conflictos # con el caracter | que aparece en signatures Python (ej. "list[int] | None"). SEP=$'\x1f' ROWS="$(sqlite3 -separator "$SEP" "$DB" \ "SELECT f.id, f.signature, f.description FROM functions f, json_each(f.tags) j WHERE j.value = '${GROUP}' ORDER BY f.id;" 2>/dev/null)" || die "Error al consultar registry.db" # Escapar | en un valor para que no rompa la tabla Markdown escape_pipe() { printf '%s' "$1" | sed 's/|/\\|/g' } # Construir tabla Markdown TABLE_HEADER="| ID | Firma | Que hace | |---|---|---|" TABLE_ROWS="" FUNC_COUNT=0 if [[ -n "$ROWS" ]]; then while IFS="$SEP" read -r id signature description; do # Limpiar espacios extra id="${id// /}" signature="$(printf '%s' "$signature" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" description="$(printf '%s' "$description" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" # Escapar pipes internos en firma y descripcion sig_esc="$(escape_pipe "$signature")" desc_esc="$(escape_pipe "$description")" TABLE_ROWS="${TABLE_ROWS}| \`${id}\` | \`${sig_esc}\` | ${desc_esc} | " FUNC_COUNT=$((FUNC_COUNT + 1)) done <<< "$ROWS" fi if [[ $FUNC_COUNT -eq 0 ]]; then warn "El grupo '${GROUP}' no tiene funciones con ese tag en registry.db." TABLE_CONTENT="_No hay funciones con tag ${GROUP}._" else TABLE_CONTENT="${TABLE_HEADER} ${TABLE_ROWS}" fi # -------------------------------------------------------------------------- # Crear o actualizar el archivo # -------------------------------------------------------------------------- mkdir -p "$(dirname "$OUT_PATH")" if [[ ! -f "$OUT_PATH" ]]; then # --- Archivo nuevo: plantilla minima --- cat > "$OUT_PATH" <