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' \
|
--delimiter='\t' \
|
||||||
--with-nth=2.. \
|
--with-nth=2.. \
|
||||||
--prompt="Agents > " \
|
--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=()
|
DETECTED_AGENTS=()
|
||||||
while IFS=$'\t' read -r agent_name _; do
|
while IFS=$'\t' read -r agent_name _; do
|
||||||
@@ -416,11 +417,14 @@ run_menu() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
local space_script="/tmp/skills_space_$$.sh"
|
local space_script="/tmp/skills_space_$$.sh"
|
||||||
|
local fold_script="/tmp/skills_fold_$$.sh"
|
||||||
local tab_script="/tmp/skills_tab_$$.sh"
|
local tab_script="/tmp/skills_tab_$$.sh"
|
||||||
local list_script="/tmp/skills_list_$$.sh"
|
local list_script="/tmp/skills_list_$$.sh"
|
||||||
local fns_file="/tmp/skills_fns_$$.sh"
|
local fns_file="/tmp/skills_fns_$$.sh"
|
||||||
local preview_script="/tmp/skills_preview_$$.sh"
|
local preview_script="/tmp/skills_preview_$$.sh"
|
||||||
local copy_script="/tmp/skills_copy_$$.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é
|
# Exporter fonctions et données dans un fichier source partagé
|
||||||
{
|
{
|
||||||
@@ -430,6 +434,7 @@ run_menu() {
|
|||||||
echo "STATE_FILE='$STATE_FILE'"
|
echo "STATE_FILE='$STATE_FILE'"
|
||||||
echo "REPO_DIR='$REPO_DIR'"
|
echo "REPO_DIR='$REPO_DIR'"
|
||||||
echo "COLLAPSED_FILE='$COLLAPSED_FILE'"
|
echo "COLLAPSED_FILE='$COLLAPSED_FILE'"
|
||||||
|
echo "MODE_FILE='$mode_file'"
|
||||||
echo "SKILLS_LIST=($(printf '"%s" ' "${SKILLS_LIST[@]}"))"
|
echo "SKILLS_LIST=($(printf '"%s" ' "${SKILLS_LIST[@]}"))"
|
||||||
echo "DETECTED_AGENTS=($(printf '"%s" ' "${DETECTED_AGENTS[@]}"))"
|
echo "DETECTED_AGENTS=($(printf '"%s" ' "${DETECTED_AGENTS[@]}"))"
|
||||||
} > "$fns_file"
|
} > "$fns_file"
|
||||||
@@ -457,8 +462,8 @@ SPACE_EOF
|
|||||||
sed -i "s|FNSFILE|$fns_file|" "$space_script"
|
sed -i "s|FNSFILE|$fns_file|" "$space_script"
|
||||||
chmod +x "$space_script"
|
chmod +x "$space_script"
|
||||||
|
|
||||||
# Script TAB : plier/déplier une catégorie
|
# Script X : plier/déplier une catégorie (anciennement TAB)
|
||||||
cat > "$tab_script" << 'TAB_EOF'
|
cat > "$fold_script" << 'FOLD_EOF'
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source "FNSFILE"
|
source "FNSFILE"
|
||||||
td="$1"; type="${td%%:*}"; value="${td#*:}"
|
td="$1"; type="${td%%:*}"; value="${td#*:}"
|
||||||
@@ -476,56 +481,100 @@ if grep -qx "$cat_name" "$COLLAPSED_FILE" 2>/dev/null; then
|
|||||||
else
|
else
|
||||||
echo "$cat_name" >> "$COLLAPSED_FILE"
|
echo "$cat_name" >> "$COLLAPSED_FILE"
|
||||||
fi
|
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
|
TAB_EOF
|
||||||
sed -i "s|FNSFILE|$fns_file|" "$tab_script"
|
sed -i "s|FNSFILE|$fns_file|" "$tab_script"
|
||||||
chmod +x "$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'
|
cat > "$list_script" << 'LIST_EOF'
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source "FNSFILE"
|
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
|
declare -A agent_dir_map
|
||||||
agent_dir_map[claude-code]="$HOME/.claude"
|
agent_dir_map[claude-code]="$HOME/.claude"
|
||||||
agent_dir_map[gemini-cli]="$HOME/.gemini"
|
agent_dir_map[gemini-cli]="$HOME/.gemini"
|
||||||
agent_dir_map[codex]="$HOME/.codex"
|
agent_dir_map[codex]="$HOME/.codex"
|
||||||
agent_dir_map[hermes]="$HOME/.hermes"
|
agent_dir_map[hermes]="$HOME/.hermes"
|
||||||
|
|
||||||
footer_lines=()
|
gen_repo_section() {
|
||||||
for agent in "${DETECTED_AGENTS[@]}"; do
|
local active="$1"
|
||||||
base="${agent_dir_map[$agent]:-}"
|
if [[ "$active" == "1" ]]; then
|
||||||
[[ -z "$base" ]] && continue
|
printf "d:section-repo\t${GRV_PURPLE}╔══ 📦 DÉPÔT — Skills disponibles ══╗${RESET}\n"
|
||||||
while IFS= read -r skill_md; do
|
else
|
||||||
rel="${skill_md#${base}/skills/}"
|
printf "d:section-repo\t${GRV_GRAY}── 📦 DÉPÔT — Skills disponibles ── (TAB pour basculer)${RESET}\n"
|
||||||
cat_name="${rel%%/*}"; rest="${rel#*/}"; skill_name="${rest%%/*}"
|
fi
|
||||||
ver=$(grep "^version:" "$skill_md" 2>/dev/null | head -1 | awk '{print $2}')
|
declare -A cat_map
|
||||||
footer_lines+=("d:${agent}|${cat_name}|${skill_name}\t ${GRV_GRAY}${cat_name}/${skill_name} [${agent}] v${ver}${RESET}")
|
declare -a cat_order
|
||||||
done < <(find "${base}/skills" -name "SKILL.md" 2>/dev/null | sort)
|
for i in "${!SKILLS_LIST[@]}"; do
|
||||||
done
|
cat="${SKILLS_LIST[$i]%%|*}"
|
||||||
|
[[ -z "${cat_map[$cat]+x}" ]] && { cat_order+=("$cat"); cat_map[$cat]=""; }
|
||||||
if [[ ${#footer_lines[@]} -gt 0 ]]; then
|
cat_map[$cat]+=" $i"
|
||||||
printf "d:-\t%s\n" "$(echo -e "${GRV_PURPLE}──── Skills installés globalement ────${RESET}")"
|
|
||||||
for line in "${footer_lines[@]}"; do
|
|
||||||
printf '%s\n' "$line"
|
|
||||||
done
|
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
|
fi
|
||||||
LIST_EOF
|
LIST_EOF
|
||||||
sed -i "s|FNSFILE|$fns_file|" "$list_script"
|
sed -i "s|FNSFILE|$fns_file|" "$list_script"
|
||||||
@@ -556,7 +605,7 @@ elif [[ "$type" == "h" ]]; then
|
|||||||
IFS='|' read -r _ skill agent _ _ _ desc tags <<< "$entry"
|
IFS='|' read -r _ skill agent _ _ _ desc tags <<< "$entry"
|
||||||
echo " • ${skill} [${agent}] ${desc} ${tags}"
|
echo " • ${skill} [${agent}] ${desc} ${tags}"
|
||||||
done
|
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"
|
IFS='|' read -r agent cat_name skill_name <<< "$value"
|
||||||
case "$agent" in
|
case "$agent" in
|
||||||
claude-code) base="$HOME/.claude" ;;
|
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_BLUE}RACCOURCIS CLAVIER${RESET}")
|
||||||
$(echo -e "${GRV_GREEN}SPACE${RESET}") Changer l'action du skill sélectionné
|
$(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}x${RESET}") Plier / déplier la catégorie
|
||||||
$(echo -e "${GRV_GREEN}v${RESET}") Afficher / masquer le contenu du skill (preview)
|
$(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}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}ARBRE DES CATÉGORIES${RESET}")
|
||||||
$(echo -e "${GRV_BLUE}▼${RESET} dev/") Catégorie dépliée — TAB pour replier
|
$(echo -e "${GRV_BLUE}▼${RESET} dev/") Catégorie dépliée — x pour replier
|
||||||
$(echo -e "${GRV_YELLOW}▶${RESET} infra/") Catégorie repliée — TAB pour déplier
|
$(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_GRAY}Les catégories avec >3 skills sont repliées par défaut.${RESET}")
|
||||||
|
|
||||||
$(echo -e "${GRV_BLUE}VARIABLES D'ENVIRONNEMENT${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
|
HELP_EOF
|
||||||
|
|
||||||
local legend
|
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 \
|
fzf \
|
||||||
--ansi \
|
--ansi \
|
||||||
@@ -663,13 +717,14 @@ HELP_EOF
|
|||||||
--preview="bash $preview_script {1}" \
|
--preview="bash $preview_script {1}" \
|
||||||
--preview-window="right:50%:wrap:hidden" \
|
--preview-window="right:50%:wrap:hidden" \
|
||||||
--bind="space:execute-silent(bash $space_script {1})+reload(bash $list_script)+pos({n})" \
|
--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="x:execute-silent(bash $fold_script {1})+reload(bash $list_script)+pos({n})" \
|
||||||
--bind="v:toggle-preview" \
|
--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="c:execute-silent(bash $copy_script)" \
|
||||||
--bind="f1:execute(less -R $help_file)" \
|
|
||||||
< <(bash "$list_script") > /dev/null || true
|
< <(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 ──────────────────────────────────────────────────
|
# ── Installation ──────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user