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:
+104
-49
@@ -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 ──────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user