From 618025cae2c5736b1ce6f89a8855967e02a87fd3 Mon Sep 17 00:00:00 2001 From: bastien Date: Tue, 21 Apr 2026 13:47:51 +0200 Subject: [PATCH] fix(update): pass full name@marketplace to `claude plugin update` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `claude plugin update` rejects a bare plugin name when multiple marketplaces are registered — the CLI demands `name@marketplace`. update-all.sh stripped the suffix via `${_p%%@*}`, causing every marketplace plugin update to fail with "Plugin not found". Fixed by passing the unmodified spec from `claude plugin list`. Also adds install + update paths for external skills distributed through the `npx skills` CLI (vercel-labs/skills): - alchaincyf/darwin-skill - alchaincyf/find-skills These land in ~/.agents/skills/ and are now symlinked into $REPO/skills/ via link.sh using absolute paths — the previous relative `../../.agents/...` targets resolved incorrectly when the repo is cloned below $HOME (as ~/Documents/claude/), leaving dangling symlinks. Co-Authored-By: Claude --- .gitignore | 4 ++++ install-plugins.sh | 43 ++++++++++++++++++++++++++++++++++++++++++- link.sh | 21 +++++++++++++++++++++ update-all.sh | 30 +++++++++++++++++++++++++++++- 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 4995112..204086d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,10 @@ skills/unfreeze # Emil Design Engineering skill symlink — auto-created by link.sh skills/emil-design-eng +# External skills installed via `npx skills add` — auto-created by link.sh +skills/darwin-skill +skills/find-skills + # Local project config (per-machine, not shared) .claude/ diff --git a/install-plugins.sh b/install-plugins.sh index a17d98c..0b3fe58 100644 --- a/install-plugins.sh +++ b/install-plugins.sh @@ -455,6 +455,44 @@ else fi echo "" +# ============================================================ +# STEP 8.5 — EXTERNAL SKILLS (npx skills add …) +# ============================================================ +# Cross-agent skills distributed via the `skills` npm package +# (vercel-labs/skills). Installed into ~/.agents/skills/ and +# symlinked into $REPO/skills/ by link.sh using absolute paths. +echo "── Step 8.5: External skills via npx ──────────────────────" +echo "" + +NPX_SKILLS=( + "alchaincyf/darwin-skill" + "alchaincyf/find-skills" +) + +if ! command -v npx &>/dev/null; then + warn "npx not available — skipping external skills" +else + for _src in "${NPX_SKILLS[@]}"; do + _name="${_src##*/}" + _dst="$HOME/.agents/skills/$_name" + if [ -d "$_dst" ]; then + ok "$_name already installed ($_dst)" + continue + fi + info "Installing $_name via: npx -y skills add $_src" + if npx -y skills add "$_src" 2>/dev/null; then + if [ -d "$_dst" ]; then + ok "$_name installed" + else + warn "$_name installed but not at expected path $_dst" + fi + else + err "$_name install failed — run manually: npx -y skills add $_src" + fi + done +fi +echo "" + # ============================================================ # STEP 9 — SHELL CONFIG (alias + env vars) # ============================================================ @@ -526,10 +564,13 @@ echo " 🔄 ui-ux-pro-max — user scope (~400 tokens)" echo " 🔄 context7 CLI — ctx7 (npm global, standalone or MCP setup)" echo " 🔄 graphifyy — codebase knowledge graph (pipx, PreToolUse hook)" echo " 🔄 emil-design-eng — UI polish, animations, component craft (curl → symlink)" +echo " 🔄 darwin-skill — autonomous skill optimizer (npx skills, ~/.agents/skills/)" +echo " 🔄 find-skills — skill discovery helper (npx skills, ~/.agents/skills/)" echo "" echo " All plugins installed at: user scope (~/.claude/plugins/)" -echo " GStack at: ~/.claude/skills/gstack/ (symlink → submodule)" +echo " GStack skills symlinked individually into ~/.claude/skills/ (→ submodule)" echo " Emil Design Eng at: ~/.claude/skills/emil-design-eng/ (symlink → skills-external)" +echo " npx skills at: ~/.agents/skills/ (symlinked into ~/.claude/skills/)" echo "" echo " → Restart Claude Code — plugins load automatically" echo "" diff --git a/link.sh b/link.sh index 3ef7774..0171397 100644 --- a/link.sh +++ b/link.sh @@ -57,6 +57,27 @@ else echo "⚠️ emil-design-eng not found — run: make plugin" fi +# External skills installed via `npx skills add` live under +# $HOME/.agents/skills/. We symlink them into $REPO/skills/ with +# absolute paths so the link stays valid regardless of where the +# repo is cloned (relative ../../ paths broke on repos deeper than +# one level below $HOME). +NPX_EXTERNAL_SKILLS=(darwin-skill find-skills) +for _ext in "${NPX_EXTERNAL_SKILLS[@]}"; do + _target="$HOME/.agents/skills/$_ext" + _link="$REPO/skills/$_ext" + if [ ! -d "$_target" ]; then + echo "⚠️ $_ext not installed at $_target — run: make plugin" + continue + fi + if [ -L "$_link" ] && [ "$(readlink "$_link")" = "$_target" ]; then + continue + fi + rm -f "$_link" + ln -sf "$_target" "$_link" + CHANGED=$((CHANGED + 1)) +done + if [ "$CHANGED" -eq 0 ]; then echo "✅ All symlinks already up to date." else diff --git a/update-all.sh b/update-all.sh index 306c967..4c14b5d 100644 --- a/update-all.sh +++ b/update-all.sh @@ -210,6 +210,32 @@ else info "emil-design-eng not installed — skipping (run: make plugin)" fi +# ── 7.5. Update external skills (npx skills) ── +echo "" +echo "── Updating external skills (npx skills)..." +if command -v npx &>/dev/null; then + NPX_SKILLS=( + "alchaincyf/darwin-skill" + "alchaincyf/find-skills" + ) + for _src in "${NPX_SKILLS[@]}"; do + _name="${_src##*/}" + if [ ! -d "$HOME/.agents/skills/$_name" ]; then + info "$_name not installed — skipping (run: make plugin)" + continue + fi + # `skills add` is idempotent and pulls latest from the source repo, + # which is the closest thing to an update operation the CLI exposes. + if npx -y skills add "$_src" 2>/dev/null; then + ok "$_name refreshed from $_src" + else + warn "$_name refresh failed — run manually: npx -y skills add $_src" + fi + done +else + info "npx not available — skipping external skills" +fi + # ── 8. Update marketplace plugins ── echo "" echo "── Updating marketplace plugins..." @@ -220,7 +246,9 @@ if command -v claude &>/dev/null; then while IFS= read -r _p; do _name="${_p%%@*}" info "Updating $_name..." - if claude plugin update "$_name" 2>/dev/null; then + # Pass the full "name@marketplace" spec — the CLI rejects + # the bare name when several marketplaces are registered. + if claude plugin update "$_p" 2>/dev/null; then ok "$_name updated" else warn "$_name update failed"