diff --git a/Taskfile.yml b/Taskfile.yml index fc8cb0d..9651e95 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -14,6 +14,7 @@ vars: CLAUDE_GLOBAL_DIR: '{{.HOME}}/.claude/skills' CRUSH_DIR: '{{.HOME}}/.config/crush/skills' ANTIGRAVITY_DIR: '{{.HOME}}/.gemini/antigravity/skills' + VIBE_DIR: '{{.HOME}}/.vibe/skills' # Anything at the repo root that is NOT a skill directory. Both # Taskfile + install.sh share this exclusion regex. NON_SKILL_ENTRIES: '^(Taskfile.yml|install.sh|README.md|SKILLS_INDEX.md|.gitea|.git$)$' @@ -31,12 +32,13 @@ tasks: silent: true install: - desc: 'Wire skills into every supported harness (Claude Code, Crush, Antigravity).' + desc: 'Wire skills into every supported harness (Claude Code, Crush, Antigravity, Mistral Vibe).' cmds: - task: install:claude:global - task: install:claude:repo - task: install:crush - task: install:antigravity + - task: install:vibe install:claude:global: desc: 'Per-skill symlinks under ~/.claude/skills/ — visible in every Claude Code project on this host.' @@ -122,6 +124,26 @@ tasks: echo "linked $link → $target" done + install:vibe: + desc: 'Per-skill file symlinks under ~/.vibe/skills/.md → /SKILL.md for Mistral Vibe (flat .md layout, not a directory).' + cmds: + - mkdir -p {{.VIBE_DIR}} + - | + for skill in $(ls -1 "{{.TASKFILE_DIR}}" | grep -Ev "{{.NON_SKILL_ENTRIES}}"); do + target="{{.TASKFILE_DIR}}/${skill}/SKILL.md" + [ -f "$target" ] || continue + link="{{.VIBE_DIR}}/${skill}.md" + if [ -L "$link" ] || [ -e "$link" ]; then + current=$(readlink "$link" 2>/dev/null || true) + if [ "$current" = "$target" ]; then + continue + fi + rm -rf "$link" + fi + ln -s "$target" "$link" + echo "linked $link → $target" + done + update: desc: 'git pull the canonical checkout then re-run install.' cmds: diff --git a/install.sh b/install.sh index fb58678..8f19351 100755 --- a/install.sh +++ b/install.sh @@ -19,6 +19,7 @@ CHECKOUT_DIR="${SKILLS_CHECKOUT_DIR:-$HOME/.local/share/skills}" CLAUDE_GLOBAL_DIR="${CLAUDE_SKILLS_DIR:-$HOME/.claude/skills}" CRUSH_DIR="${CRUSH_SKILLS_DIR:-$HOME/.config/crush/skills}" ANTIGRAVITY_DIR="${ANTIGRAVITY_SKILLS_DIR:-$HOME/.gemini/antigravity/skills}" +VIBE_SKILLS_DIR="${VIBE_SKILLS_DIR:-$HOME/.vibe/skills}" log() { printf '[skills] %s\n' "$*"; } @@ -112,12 +113,35 @@ wire_claude_repo() { done < <(list_skills) } +wire_vibe() { + # Mistral Vibe reads a flat ~/.vibe/skills/.md — link the SKILL.md + # file directly (not the skill directory, as the other harnesses do). + mkdir -p "$VIBE_SKILLS_DIR" + while IFS= read -r skill; do + [ -n "$skill" ] || continue + local target="$CHECKOUT_DIR/$skill/SKILL.md" + [ -f "$target" ] || continue + local link="$VIBE_SKILLS_DIR/$skill.md" + if [ -L "$link" ] || [ -e "$link" ]; then + local current + current=$(readlink "$link" 2>/dev/null || true) + if [ "$current" = "$target" ]; then + continue + fi + rm -rf "$link" + fi + ln -s "$target" "$link" + log "linked $link → $target" + done < <(list_skills) +} + main() { ensure_checkout wire_claude_global wire_claude_repo wire_crush wire_antigravity + wire_vibe log "done — $(list_skills | wc -l | tr -d ' ') skill(s) wired at ref=$REF" }