fix: bugs install.sh — cleanup destructif, clé état, tableau vide, eval npm_prefix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+87
-30
@@ -36,6 +36,7 @@ ICO_SKIP="○"
|
||||
# ── Configuration ─────────────────────────────────────────────────
|
||||
REPO_URL="https://gitea.maison43.duckdns.org/gilles/mes_skills.git"
|
||||
REPO_DIR="/tmp/mes_skills_$$"
|
||||
_CLONED_REPO_DIR=""
|
||||
STATE_FILE="/tmp/skills_state_$$"
|
||||
|
||||
SKILLS_DEBUG="${SKILLS_DEBUG:-0}"
|
||||
@@ -54,8 +55,8 @@ header() { echo -e "\n${GRV_PURPLE}╔══ $* ══╗${RESET}\n"; }
|
||||
|
||||
# ── Nettoyage automatique ─────────────────────────────────────────
|
||||
cleanup() {
|
||||
debug "Nettoyage $REPO_DIR et $STATE_FILE"
|
||||
[[ -d "$REPO_DIR" ]] && rm -rf "$REPO_DIR"
|
||||
debug "Nettoyage $_CLONED_REPO_DIR et $STATE_FILE"
|
||||
[[ -n "$_CLONED_REPO_DIR" && -d "$_CLONED_REPO_DIR" ]] && rm -rf "$_CLONED_REPO_DIR"
|
||||
[[ -f "$STATE_FILE" ]] && rm -f "$STATE_FILE"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
@@ -101,27 +102,57 @@ DETECTED_AGENTS=()
|
||||
detect_agents() {
|
||||
header "Détection des agents IA"
|
||||
|
||||
_check_agent() {
|
||||
local name="$1" primary="$2" secondary="$3"
|
||||
_add_agent() {
|
||||
local name="$1"
|
||||
if [[ -n "$SKILLS_AGENT" && "$SKILLS_AGENT" != "$name" ]]; then
|
||||
debug "Agent $name ignoré (SKILLS_AGENT=$SKILLS_AGENT)"
|
||||
return
|
||||
fi
|
||||
if eval "$primary" &>/dev/null 2>&1 || eval "$secondary" &>/dev/null 2>&1; then
|
||||
DETECTED_AGENTS+=("$name")
|
||||
ok "Agent détecté : $name"
|
||||
else
|
||||
DETECTED_AGENTS+=("$name")
|
||||
ok "Agent détecté : $name"
|
||||
}
|
||||
|
||||
_skip_agent() {
|
||||
local name="$1"
|
||||
if [[ -z "$SKILLS_AGENT" || "$SKILLS_AGENT" == "$name" ]]; then
|
||||
echo -e "${GRV_GRAY}${ICO_NA} Agent absent : $name${RESET}"
|
||||
fi
|
||||
}
|
||||
|
||||
local npm_prefix
|
||||
npm_prefix=$(npm config get prefix 2>/dev/null || echo "")
|
||||
_detect_gemini() {
|
||||
command -v gemini &>/dev/null && return 0
|
||||
local prefix
|
||||
prefix=$(npm config get prefix 2>/dev/null) || return 1
|
||||
[[ -n "$prefix" && -f "${prefix}/bin/gemini" ]]
|
||||
}
|
||||
|
||||
_check_agent "claude-code" "test -d $HOME/.claude" "command -v claude"
|
||||
_check_agent "gemini-cli" "command -v gemini" "test -f ${npm_prefix}/bin/gemini"
|
||||
_check_agent "codex" "command -v codex" "test -f $HOME/.npm-global/bin/codex"
|
||||
_check_agent "hermes" "command -v hermes" "test -f $HOME/.local/bin/hermes"
|
||||
# claude-code
|
||||
if [[ -d "$HOME/.claude" ]] || command -v claude &>/dev/null; then
|
||||
_add_agent "claude-code"
|
||||
else
|
||||
_skip_agent "claude-code"
|
||||
fi
|
||||
|
||||
# gemini-cli
|
||||
if _detect_gemini; then
|
||||
_add_agent "gemini-cli"
|
||||
else
|
||||
_skip_agent "gemini-cli"
|
||||
fi
|
||||
|
||||
# codex
|
||||
if command -v codex &>/dev/null || [[ -f "$HOME/.npm-global/bin/codex" ]]; then
|
||||
_add_agent "codex"
|
||||
else
|
||||
_skip_agent "codex"
|
||||
fi
|
||||
|
||||
# hermes
|
||||
if command -v hermes &>/dev/null || [[ -f "$HOME/.local/bin/hermes" ]]; then
|
||||
_add_agent "hermes"
|
||||
else
|
||||
_skip_agent "hermes"
|
||||
fi
|
||||
|
||||
if [[ ${#DETECTED_AGENTS[@]} -eq 0 ]]; then
|
||||
warn "Aucun agent IA détecté. L'installation continuera mais aucun skill ne sera filtré."
|
||||
@@ -138,6 +169,7 @@ clone_repo() {
|
||||
fi
|
||||
info "Clonage depuis $REPO_URL..."
|
||||
git clone --depth=1 "$REPO_URL" "$REPO_DIR" &>/dev/null
|
||||
_CLONED_REPO_DIR="$REPO_DIR"
|
||||
ok "Dépôt cloné dans $REPO_DIR"
|
||||
}
|
||||
|
||||
@@ -194,9 +226,11 @@ scan_skills() {
|
||||
|
||||
# Filtre agent
|
||||
local agent_detected=0
|
||||
for a in "${DETECTED_AGENTS[@]:-}"; do
|
||||
[[ "$a" == "$agent" ]] && agent_detected=1
|
||||
done
|
||||
if [[ ${#DETECTED_AGENTS[@]} -gt 0 ]]; then
|
||||
for a in "${DETECTED_AGENTS[@]}"; do
|
||||
[[ "$a" == "$agent" ]] && agent_detected=1
|
||||
done
|
||||
fi
|
||||
[[ "$agent_detected" -eq 0 && ${#DETECTED_AGENTS[@]} -gt 0 ]] && continue
|
||||
|
||||
# Filtre tag
|
||||
@@ -223,11 +257,21 @@ scan_skills() {
|
||||
ok "${#SKILLS_LIST[@]} skill(s) trouvé(s)"
|
||||
}
|
||||
|
||||
# ── Clé d'état normalisée ────────────────────────────────────────
|
||||
make_key() {
|
||||
# Entrée : "cat|skill|agent|..." — Sortie : clé normalisée pour STATE_FILE
|
||||
local entry="$1"
|
||||
local cat skill agent
|
||||
IFS='|' read -r cat skill agent _ <<< "$entry"
|
||||
# Normalise en remplaçant - et / par _ pour éviter les collisions
|
||||
printf '%s_%s_%s' "${cat//-/_}" "${skill//-/_}" "${agent//-/_}"
|
||||
}
|
||||
|
||||
# ── État du menu ──────────────────────────────────────────────────
|
||||
state_init() {
|
||||
: > "$STATE_FILE"
|
||||
for entry in "${SKILLS_LIST[@]}"; do
|
||||
local key="${entry//|/_}"
|
||||
local key; key=$(make_key "$entry")
|
||||
echo "${key}=local" >> "$STATE_FILE"
|
||||
done
|
||||
}
|
||||
@@ -255,7 +299,7 @@ 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 key; key=$(make_key "$entry")
|
||||
local action; action=$(state_get "$key")
|
||||
|
||||
local ico_etat color_etat
|
||||
@@ -296,23 +340,34 @@ run_menu() {
|
||||
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)
|
||||
SKILLS_FNS="$2"
|
||||
LINE_NUM="$3" # numéro de ligne fzf (1-based)
|
||||
|
||||
source "$SKILLS_FNS"
|
||||
|
||||
# Récupère l'entrée correspondante (0-based dans SKILLS_LIST)
|
||||
idx=$(( LINE_NUM - 1 ))
|
||||
entry="${SKILLS_LIST[$idx]:-}"
|
||||
[[ -z "$entry" ]] && exit 0
|
||||
|
||||
key=$(make_key "$entry")
|
||||
etat=$(echo "$entry" | cut -d'|' -f4)
|
||||
|
||||
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" ;;
|
||||
skip) [[ "$etat" == "upd" ]] && next="update" || next="local" ;;
|
||||
update) next="local" ;;
|
||||
*) next="local" ;;
|
||||
esac
|
||||
sed -i "s|^${KEY}=.*|${KEY}=${next}|" "$STATE_FILE"
|
||||
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 -f format_skill_line state_get make_key
|
||||
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'"
|
||||
@@ -336,7 +391,7 @@ LIST_EOF
|
||||
--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)" \
|
||||
--bind="tab:execute-silent($cycle_script '$STATE_FILE' '$fns_file' {n})+reload($list_script)" \
|
||||
< <(bash "$list_script") > /dev/null || true
|
||||
|
||||
rm -f "$cycle_script" "$list_script" "$fns_file"
|
||||
@@ -350,7 +405,7 @@ install_selected() {
|
||||
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 key; key=$(make_key "$entry")
|
||||
local action; action=$(state_get "$key")
|
||||
|
||||
if [[ "$action" == "skip" ]]; then
|
||||
@@ -396,12 +451,14 @@ print_summary() {
|
||||
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 key; key=$(make_key "$entry")
|
||||
local action; action=$(state_get "$key")
|
||||
[[ "$action" == "skip" ]] && continue
|
||||
|
||||
local already=0
|
||||
for s in "${shown[@]:-}"; do [[ "$s" == "${skill}|${agent}" ]] && already=1; done
|
||||
if [[ ${#shown[@]} -gt 0 ]]; then
|
||||
for s in "${shown[@]}"; do [[ "$s" == "${skill}|${agent}" ]] && already=1; done
|
||||
fi
|
||||
[[ "$already" -eq 1 ]] && continue
|
||||
shown+=("${skill}|${agent}")
|
||||
|
||||
@@ -414,7 +471,7 @@ print_summary() {
|
||||
done
|
||||
|
||||
echo -e "\n${GRV_PURPLE}╔══ Documentation agents ══╗${RESET}\n"
|
||||
for agent in "${DETECTED_AGENTS[@]:-}"; do
|
||||
for agent in "${DETECTED_AGENTS[@]}"; do
|
||||
case "$agent" in
|
||||
claude-code) echo -e " ${GRV_BLUE}Claude Code${RESET} → https://code.claude.com/docs/en/skills" ;;
|
||||
gemini-cli) echo -e " ${GRV_BLUE}Gemini CLI ${RESET} → https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/skills.md" ;;
|
||||
|
||||
Reference in New Issue
Block a user