feat: install.sh — deux sections DÉPÔT/GLOBAL avec bascule TAB

- TAB bascule entre section DÉPÔT (skills repo) et GLOBAL (installés)
- Section active affichée en premier avec header violet ╔══╗
- Section inactive grisée avec catégories repliées en-dessous
- x remplace TAB pour plier/déplier les catégories
- Skills globaux en type g: (navigables + preview)
- ESC dans le menu agents quitte proprement le script
- F1 affiche l'aide dans le panneau preview à droite (v pour revenir)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 06:22:19 +02:00
parent bd1ddd8193
commit d131eeec5d
+104 -49
View File
@@ -189,7 +189,8 @@ select_agents() {
--delimiter='\t' \
--with-nth=2.. \
--prompt="Agents > " \
--header="$(echo -e "${GRV_GRAY}TAB=sélectionner/désélectionner ENTER=valider${RESET}")") || true
--bind="esc:abort" \
--header="$(echo -e "${GRV_GRAY}TAB=sélectionner/désélectionner ENTER=valider ESC=quitter${RESET}")") || { echo; err "Annulé."; exit 0; }
DETECTED_AGENTS=()
while IFS=$'\t' read -r agent_name _; do
@@ -416,11 +417,14 @@ run_menu() {
done
local space_script="/tmp/skills_space_$$.sh"
local fold_script="/tmp/skills_fold_$$.sh"
local tab_script="/tmp/skills_tab_$$.sh"
local list_script="/tmp/skills_list_$$.sh"
local fns_file="/tmp/skills_fns_$$.sh"
local preview_script="/tmp/skills_preview_$$.sh"
local copy_script="/tmp/skills_copy_$$.sh"
local mode_file="/tmp/skills_mode_$$.txt"
echo "repo" > "$mode_file"
# Exporter fonctions et données dans un fichier source partagé
{
@@ -430,6 +434,7 @@ run_menu() {
echo "STATE_FILE='$STATE_FILE'"
echo "REPO_DIR='$REPO_DIR'"
echo "COLLAPSED_FILE='$COLLAPSED_FILE'"
echo "MODE_FILE='$mode_file'"
echo "SKILLS_LIST=($(printf '"%s" ' "${SKILLS_LIST[@]}"))"
echo "DETECTED_AGENTS=($(printf '"%s" ' "${DETECTED_AGENTS[@]}"))"
} > "$fns_file"
@@ -457,8 +462,8 @@ SPACE_EOF
sed -i "s|FNSFILE|$fns_file|" "$space_script"
chmod +x "$space_script"
# Script TAB : plier/déplier une catégorie
cat > "$tab_script" << 'TAB_EOF'
# Script X : plier/déplier une catégorie (anciennement TAB)
cat > "$fold_script" << 'FOLD_EOF'
#!/usr/bin/env bash
source "FNSFILE"
td="$1"; type="${td%%:*}"; value="${td#*:}"
@@ -476,56 +481,100 @@ if grep -qx "$cat_name" "$COLLAPSED_FILE" 2>/dev/null; then
else
echo "$cat_name" >> "$COLLAPSED_FILE"
fi
FOLD_EOF
sed -i "s|FNSFILE|$fns_file|" "$fold_script"
chmod +x "$fold_script"
# Script TAB : basculer entre section DÉPÔT et section GLOBAL
cat > "$tab_script" << 'TAB_EOF'
#!/usr/bin/env bash
source "FNSFILE"
mode=$(cat "$MODE_FILE" 2>/dev/null || echo "repo")
[[ "$mode" == "repo" ]] && echo "global" > "$MODE_FILE" || echo "repo" > "$MODE_FILE"
TAB_EOF
sed -i "s|FNSFILE|$fns_file|" "$tab_script"
chmod +x "$tab_script"
# Script LIST : générateur d'arbre pour fzf --reload
# Script LIST : deux sections (DÉPÔT / GLOBAL) avec bascule via MODE_FILE
cat > "$list_script" << 'LIST_EOF'
#!/usr/bin/env bash
source "FNSFILE"
declare -A cat_map
declare -a cat_order
for i in "${!SKILLS_LIST[@]}"; do
cat="${SKILLS_LIST[$i]%%|*}"
[[ -z "${cat_map[$cat]+x}" ]] && { cat_order+=("$cat"); cat_map[$cat]=""; }
cat_map[$cat]+=" $i"
done
for cat in "${cat_order[@]}"; do
indices=(${cat_map[$cat]})
collapsed=0
grep -qx "$cat" "$COLLAPSED_FILE" 2>/dev/null && collapsed=1
format_category_header "$cat" "${#indices[@]}" "$collapsed"
[[ "$collapsed" == "1" ]] && continue
for idx in "${indices[@]}"; do
format_skill_line "${SKILLS_LIST[$idx]}" "$idx"
done
done
# Footer : skills déjà installés globalement
mode=$(cat "$MODE_FILE" 2>/dev/null || echo "repo")
declare -A agent_dir_map
agent_dir_map[claude-code]="$HOME/.claude"
agent_dir_map[gemini-cli]="$HOME/.gemini"
agent_dir_map[codex]="$HOME/.codex"
agent_dir_map[hermes]="$HOME/.hermes"
footer_lines=()
for agent in "${DETECTED_AGENTS[@]}"; do
base="${agent_dir_map[$agent]:-}"
[[ -z "$base" ]] && continue
while IFS= read -r skill_md; do
rel="${skill_md#${base}/skills/}"
cat_name="${rel%%/*}"; rest="${rel#*/}"; skill_name="${rest%%/*}"
ver=$(grep "^version:" "$skill_md" 2>/dev/null | head -1 | awk '{print $2}')
footer_lines+=("d:${agent}|${cat_name}|${skill_name}\t ${GRV_GRAY}${cat_name}/${skill_name} [${agent}] v${ver}${RESET}")
done < <(find "${base}/skills" -name "SKILL.md" 2>/dev/null | sort)
done
if [[ ${#footer_lines[@]} -gt 0 ]]; then
printf "d:-\t%s\n" "$(echo -e "${GRV_PURPLE}──── Skills installés globalement ────${RESET}")"
for line in "${footer_lines[@]}"; do
printf '%s\n' "$line"
gen_repo_section() {
local active="$1"
if [[ "$active" == "1" ]]; then
printf "d:section-repo\t${GRV_PURPLE}╔══ 📦 DÉPÔT — Skills disponibles ══╗${RESET}\n"
else
printf "d:section-repo\t${GRV_GRAY}── 📦 DÉPÔT — Skills disponibles ── (TAB pour basculer)${RESET}\n"
fi
declare -A cat_map
declare -a cat_order
for i in "${!SKILLS_LIST[@]}"; do
cat="${SKILLS_LIST[$i]%%|*}"
[[ -z "${cat_map[$cat]+x}" ]] && { cat_order+=("$cat"); cat_map[$cat]=""; }
cat_map[$cat]+=" $i"
done
for cat in "${cat_order[@]}"; do
indices=(${cat_map[$cat]})
if [[ "$active" == "0" ]]; then
format_category_header "$cat" "${#indices[@]}" "1"
else
collapsed=0
grep -qx "$cat" "$COLLAPSED_FILE" 2>/dev/null && collapsed=1
format_category_header "$cat" "${#indices[@]}" "$collapsed"
[[ "$collapsed" == "1" ]] && continue
for idx in "${indices[@]}"; do
format_skill_line "${SKILLS_LIST[$idx]}" "$idx"
done
fi
done
}
gen_global_section() {
local active="$1"
if [[ "$active" == "1" ]]; then
printf "d:section-global\t${GRV_PURPLE}╔══ 💾 GLOBAL — Skills installés ══╗${RESET}\n"
else
printf "d:section-global\t${GRV_GRAY}── 💾 GLOBAL — Skills installés ── (TAB pour basculer)${RESET}\n"
fi
local -a global_lines=()
for agent in "${DETECTED_AGENTS[@]}"; do
base="${agent_dir_map[$agent]:-}"
[[ -z "$base" ]] && continue
while IFS= read -r skill_md; do
rel="${skill_md#${base}/skills/}"
cat_name="${rel%%/*}"; rest="${rel#*/}"; skill_name="${rest%%/*}"
ver=$(grep "^version:" "$skill_md" 2>/dev/null | head -1 | awk '{print $2}')
global_lines+=("g:${agent}|${cat_name}|${skill_name}\t ${GRV_GRAY}${cat_name}/${skill_name}${RESET} ${GRV_GRAY}[${agent}]${RESET} ${GRV_GRAY}v${ver:-?}${RESET}")
done < <(find "${base}/skills" -name "SKILL.md" 2>/dev/null | sort)
done
if [[ ${#global_lines[@]} -eq 0 ]]; then
printf "d:-\t${GRV_GRAY} (aucun skill installé globalement)${RESET}\n"
else
for line in "${global_lines[@]}"; do
printf '%s\n' "$line"
done
fi
}
sep() { printf "d:sep\t${GRV_GRAY}────────────────────────────────────────────────────────${RESET}\n"; }
if [[ "$mode" == "repo" ]]; then
gen_repo_section 1
sep
gen_global_section 0
else
gen_global_section 1
sep
gen_repo_section 0
fi
LIST_EOF
sed -i "s|FNSFILE|$fns_file|" "$list_script"
@@ -556,7 +605,7 @@ elif [[ "$type" == "h" ]]; then
IFS='|' read -r _ skill agent _ _ _ desc tags <<< "$entry"
echo " • ${skill} [${agent}] ${desc} ${tags}"
done
elif [[ "$type" == "d" && "$value" != "-" ]]; then
elif [[ "$type" == "g" || ( "$type" == "d" && "$value" != "-" && "$value" != "section-repo" && "$value" != "section-global" && "$value" != "sep" ) ]]; then
IFS='|' read -r agent cat_name skill_name <<< "$value"
case "$agent" in
claude-code) base="$HOME/.claude" ;;
@@ -629,14 +678,19 @@ $(echo -e "${GRV_BLUE}ACTIONS (SPACE pour cycler)${RESET}")
$(echo -e "${GRV_BLUE}RACCOURCIS CLAVIER${RESET}")
$(echo -e "${GRV_GREEN}SPACE${RESET}") Changer l'action du skill sélectionné
$(echo -e "${GRV_GREEN}TAB${RESET}") Plier / déplier la catégorie
$(echo -e "${GRV_GREEN}v${RESET}") Afficher / masquer le contenu du skill (preview)
$(echo -e "${GRV_GREEN}x${RESET}") Plier / déplier la catégorie
$(echo -e "${GRV_GREEN}TAB${RESET}") Basculer entre section DÉPÔT et section GLOBAL
$(echo -e "${GRV_GREEN}v${RESET}") Afficher / masquer le contenu du skill (preview) — ferme aussi cette aide
$(echo -e "${GRV_GREEN}c${RESET}") Copier la liste affichée dans le presse-papier
$(echo -e "${GRV_GREEN}F1${RESET}") Afficher / fermer cette aide
$(echo -e "${GRV_GREEN}F1${RESET}") Ouvrir cette aide dans le panneau preview (v pour revenir au skill)
$(echo -e "${GRV_BLUE}DEUX SECTIONS${RESET}")
$(echo -e "${GRV_PURPLE}╔══ 📦 DÉPÔT ══╗${RESET}") Section active — skills du dépôt (installables)
$(echo -e "${GRV_GRAY}── 💾 GLOBAL ──${RESET}") Section inactive — skills déjà installés
$(echo -e "${GRV_BLUE}ARBRE DES CATÉGORIES${RESET}")
$(echo -e "${GRV_BLUE}▼${RESET} dev/") Catégorie dépliée — TAB pour replier
$(echo -e "${GRV_YELLOW}▶${RESET} infra/") Catégorie repliée — TAB pour déplier
$(echo -e "${GRV_BLUE}▼${RESET} dev/") Catégorie dépliée — x pour replier
$(echo -e "${GRV_YELLOW}▶${RESET} infra/") Catégorie repliée — x pour déplier
$(echo -e "${GRV_GRAY}Les catégories avec >3 skills sont repliées par défaut.${RESET}")
$(echo -e "${GRV_BLUE}VARIABLES D'ENVIRONNEMENT${RESET}")
@@ -651,7 +705,7 @@ $(echo -e "${GRV_GRAY}Dépôt : https://gitea.maison43.duckdns.org/gilles/mes_sk
HELP_EOF
local legend
legend=$(echo -e "${GRV_GRAY}État: ${GRV_GREEN}${GRV_YELLOW}${GRV_AQUA}+ Action: ${GRV_GREEN}●L ${GRV_BLUE}●G ${GRV_GRAY}○ SPACE=action TAB=plier v=voir c=copier F1=aide ENTER=ok ESC=quitter${RESET}")
legend=$(echo -e "${GRV_GRAY}État: ${GRV_GREEN}${GRV_YELLOW}${GRV_AQUA}+ Action: ${GRV_GREEN}●L ${GRV_BLUE}●G ${GRV_GRAY}○ SPACE=action x=plier TAB=sections v=voir c=copier F1=aide ENTER=ok ESC=quitter${RESET}")
fzf \
--ansi \
@@ -663,13 +717,14 @@ HELP_EOF
--preview="bash $preview_script {1}" \
--preview-window="right:50%:wrap:hidden" \
--bind="space:execute-silent(bash $space_script {1})+reload(bash $list_script)+pos({n})" \
--bind="tab:execute-silent(bash $tab_script {1})+reload(bash $list_script)" \
--bind="v:toggle-preview" \
--bind="x:execute-silent(bash $fold_script {1})+reload(bash $list_script)+pos({n})" \
--bind="tab:execute-silent(bash $tab_script)+reload(bash $list_script)+first" \
--bind="v:change-preview(bash $preview_script {1})+toggle-preview" \
--bind="f1:change-preview(cat $help_file)+show-preview" \
--bind="c:execute-silent(bash $copy_script)" \
--bind="f1:execute(less -R $help_file)" \
< <(bash "$list_script") > /dev/null || true
rm -f "$space_script" "$tab_script" "$list_script" "$fns_file" "$preview_script" "$copy_script" "$help_file"
rm -f "$space_script" "$fold_script" "$tab_script" "$list_script" "$fns_file" "$preview_script" "$copy_script" "$help_file" "$mode_file"
}
# ── Installation ──────────────────────────────────────────────────