feat: install.sh — menu fzf Gruvbox et installation des skills

This commit is contained in:
2026-05-16 04:18:14 +02:00
parent f1d4755b6d
commit 3695a35232
+165
View File
@@ -222,3 +222,168 @@ scan_skills() {
ok "${#SKILLS_LIST[@]} skill(s) trouvé(s)"
}
# ── État du menu ──────────────────────────────────────────────────
state_init() {
: > "$STATE_FILE"
for entry in "${SKILLS_LIST[@]}"; do
local key="${entry//|/_}"
echo "${key}=local" >> "$STATE_FILE"
done
}
state_get() {
grep "^${1}=" "$STATE_FILE" 2>/dev/null | cut -d'=' -f2
}
state_cycle() {
local key="$1" etat="$2"
local current; current=$(state_get "$key")
local next
case "$current" in
local) next="global" ;;
global) next="skip" ;;
skip) [[ "$etat" == "upd" ]] && next="update" || next="local" ;;
update) next="local" ;;
*) next="local" ;;
esac
sed -i "s|^${key}=.*|${key}=${next}|" "$STATE_FILE"
}
# ── Formatage ligne menu ──────────────────────────────────────────
format_skill_line() {
local entry="$1"
local cat skill agent etat repo_ver local_ver
IFS='|' read -r cat skill agent etat repo_ver local_ver <<< "$entry"
local key="${cat}_${skill}_${agent}"
local action; action=$(state_get "$key")
local ico_etat color_etat
case "$etat" in
ok) ico_etat="$ICO_OK"; color_etat="$GRV_GREEN" ;;
upd) ico_etat="$ICO_UPD"; color_etat="$GRV_YELLOW" ;;
new) ico_etat="$ICO_NEW"; color_etat="$GRV_AQUA" ;;
*) ico_etat="$ICO_NA"; color_etat="$GRV_GRAY" ;;
esac
local ico_action color_action
case "$action" in
local) ico_action="$ICO_LOCAL"; color_action="$GRV_GREEN" ;;
global) ico_action="$ICO_GLOBAL"; color_action="$GRV_BLUE" ;;
skip) ico_action="$ICO_SKIP"; color_action="$GRV_GRAY" ;;
update) ico_action="$ICO_UPD"; color_action="$GRV_YELLOW" ;;
*) ico_action="$ICO_SKIP"; color_action="$GRV_GRAY" ;;
esac
local ver_info=""
[[ "$etat" == "upd" ]] && ver_info=" (${local_ver}${repo_ver})"
[[ "$etat" == "new" ]] && ver_info=" (v${repo_ver})"
printf "${color_etat}%s${RESET} %-35s ${GRV_GRAY}[%s]${RESET} ${color_action}%s${RESET}%s\n" \
"$ico_etat" "${cat}/${skill}" "$agent" "$ico_action" "$ver_info"
}
# ── Menu fzf principal ────────────────────────────────────────────
run_menu() {
header "Sélection des skills"
state_init
local cycle_script="/tmp/skills_cycle_$$.sh"
local list_script="/tmp/skills_list_$$.sh"
local fns_file="/tmp/skills_fns_$$.sh"
# Script de cycle d'état (appelé par fzf via execute-silent)
cat > "$cycle_script" << 'CYCLE_EOF'
#!/usr/bin/env bash
STATE_FILE="$1"
KEY="$2"
ETAT="$3"
current=$(grep "^${KEY}=" "$STATE_FILE" 2>/dev/null | cut -d'=' -f2)
case "$current" in
local) next="global" ;;
global) next="skip" ;;
skip) [[ "$ETAT" == "upd" ]] && next="update" || next="local" ;;
update) next="local" ;;
*) next="local" ;;
esac
sed -i "s|^${KEY}=.*|${KEY}=${next}|" "$STATE_FILE"
CYCLE_EOF
chmod +x "$cycle_script"
# Exporter fonctions et variables dans un fichier source
{
declare -f format_skill_line state_get
declare -p GRV_GREEN GRV_YELLOW GRV_AQUA GRV_GRAY GRV_BLUE RESET \
ICO_OK ICO_UPD ICO_NEW ICO_NA ICO_LOCAL ICO_GLOBAL ICO_SKIP
echo "STATE_FILE='$STATE_FILE'"
echo "SKILLS_LIST=($(printf '"%s" ' "${SKILLS_LIST[@]}"))"
} > "$fns_file"
# Script générateur de liste pour fzf --reload
cat > "$list_script" << LIST_EOF
#!/usr/bin/env bash
source "$fns_file"
for entry in "\${SKILLS_LIST[@]}"; do
format_skill_line "\$entry"
done
LIST_EOF
chmod +x "$list_script"
local legend
legend=$(echo -e "${GRV_GRAY}État: ${GRV_GREEN}✓ installé ${GRV_YELLOW}↑ MAJ ${GRV_AQUA}+ nouveau Action: ${GRV_GREEN}●L local ${GRV_BLUE}●G global ${GRV_GRAY}○ ignorer TAB=changer ENTER=confirmer ESC=quitter${RESET}")
fzf \
--ansi \
--prompt="Skills > " \
--header="$legend" \
--bind="tab:execute-silent($cycle_script '$STATE_FILE' \$(echo {} | awk '{print \$2}' | tr '/' '_' | sed 's/-/_/g')_\$(echo {} | awk '{print \$3}' | tr -d '[]') \$(echo {} | awk '{print \$4}'))+reload($list_script)" \
< <(bash "$list_script") > /dev/null || true
rm -f "$cycle_script" "$list_script" "$fns_file"
}
# ── Installation ──────────────────────────────────────────────────
install_selected() {
header "Installation"
local count_install=0 count_update=0 count_skip=0
for entry in "${SKILLS_LIST[@]}"; do
local cat skill agent etat repo_ver local_ver
IFS='|' read -r cat skill agent etat repo_ver local_ver <<< "$entry"
local key="${cat}_${skill}_${agent}"
local action; action=$(state_get "$key")
if [[ "$action" == "skip" ]]; then
(( count_skip++ )) || true
continue
fi
local scope="$action"
[[ "$action" == "update" ]] && scope="local"
local src="${REPO_DIR}/skills/${cat}/${skill}/${agent}.md"
local dest; dest=$(get_dest_path "$cat" "$skill" "$agent" "$scope")
debug "Copie $src$dest"
if [[ "$SKILLS_DRY_RUN" == "1" ]]; then
info "[DRY-RUN] cp $src$dest"
else
mkdir -p "$(dirname "$dest")"
cp "$src" "$dest"
fi
if [[ "$action" == "update" ]]; then
ok "Mis à jour : ${cat}/${skill} [${agent}] ${local_ver}${repo_ver}"
(( count_update++ )) || true
else
ok "Installé : ${cat}/${skill} [${agent}] → ${scope}"
(( count_install++ )) || true
fi
done
echo -e "\n${GRV_PURPLE}╔══ Bilan ══╗${RESET}"
echo -e " ${GRV_GREEN}${ICO_OK} $count_install installé(s)${RESET}"
echo -e " ${GRV_YELLOW}${ICO_UPD} $count_update mis à jour${RESET}"
echo -e " ${GRV_GRAY}${ICO_SKIP} $count_skip ignoré(s)${RESET}"
}