From c9e054e013a4713bf77809d2cd975261a57b41c6 Mon Sep 17 00:00:00 2001 From: lmiranda Date: Mon, 2 Feb 2026 22:13:40 -0500 Subject: [PATCH] fix(hooks): check venv cache path before marketplace path Startup hooks in data-platform and pr-review were checking for venvs at the marketplace path (~/.claude/plugins/marketplaces/.../mcp-servers/) which gets wiped on updates. The actual venvs live in the cache directory (~/.cache/claude-mcp-venvs/) which survives updates. This caused false "MCP venv missing" errors even when venvs existed, wasting hours of debugging time. Fixed hooks now check cache path first, matching the pattern used by run.sh scripts. Also updated docs/CANONICAL-PATHS.md with the correct venv path pattern to prevent future occurrences. Lesson learned: lessons/patterns/startup-hooks-must-check-venv-cache-path-first Co-Authored-By: Claude Opus 4.5 --- docs/CANONICAL-PATHS.md | 34 +++++++++++++++++++- plugins/data-platform/hooks/startup-check.sh | 13 +++++--- plugins/pr-review/hooks/startup-check.sh | 13 +++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/docs/CANONICAL-PATHS.md b/docs/CANONICAL-PATHS.md index 2b92a7c..8507a4a 100644 --- a/docs/CANONICAL-PATHS.md +++ b/docs/CANONICAL-PATHS.md @@ -182,10 +182,42 @@ MCP servers are **shared at repository root** and configured in `.mcp.json`. | MCP configuration | `.mcp.json` | `.mcp.json` (at repo root) | | Shared MCP server | `mcp-servers/{server}/` | `mcp-servers/gitea/` | | MCP server code | `mcp-servers/{server}/mcp_server/` | `mcp-servers/gitea/mcp_server/` | -| MCP venv | `mcp-servers/{server}/.venv/` | `mcp-servers/gitea/.venv/` | +| MCP venv (local) | `mcp-servers/{server}/.venv/` | `mcp-servers/gitea/.venv/` | **Note:** Plugins do NOT have their own `mcp-servers/` directories. All MCP servers are shared at root and configured via `.mcp.json`. +### MCP Venv Paths - CRITICAL + +**Venvs live in a CACHE directory that SURVIVES marketplace updates.** + +When checking for venvs, ALWAYS check in this order: + +| Priority | Path | Survives Updates? | +|----------|------|-------------------| +| 1 (CHECK FIRST) | `~/.cache/claude-mcp-venvs/leo-claude-mktplace/{server}/.venv/` | YES | +| 2 (fallback) | `{marketplace}/mcp-servers/{server}/.venv/` | NO | + +**Why cache first?** +- Marketplace directory gets WIPED on every update/reinstall +- Cache directory SURVIVES updates +- False "venv missing" errors waste hours of debugging + +**Pattern for hooks checking venvs:** +```bash +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/{server}/.venv/bin/python" +LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/{server}/.venv/bin/python" + +if [[ -f "$CACHE_VENV" ]]; then + VENV_PATH="$CACHE_VENV" +elif [[ -f "$LOCAL_VENV" ]]; then + VENV_PATH="$LOCAL_VENV" +else + echo "venv missing" +fi +``` + +**See lesson learned:** [Startup Hooks Must Check Venv Cache Path First](https://gitea.hotserv.cloud/personal-projects/leo-claude-mktplace/wiki/lessons/patterns/startup-hooks-must-check-venv-cache-path-first) + ### Documentation Paths | Type | Location | diff --git a/plugins/data-platform/hooks/startup-check.sh b/plugins/data-platform/hooks/startup-check.sh index a0ee74c..ed861c7 100755 --- a/plugins/data-platform/hooks/startup-check.sh +++ b/plugins/data-platform/hooks/startup-check.sh @@ -5,13 +5,18 @@ PREFIX="[data-platform]" -# Check if MCP venv exists +# Check if MCP venv exists - check cache first, then local +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/data-platform/.venv/bin/python" PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}" -# MCP servers are at marketplace root, not inside plugin MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")" -VENV_PATH="$MARKETPLACE_ROOT/mcp-servers/data-platform/.venv/bin/python" +LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/data-platform/.venv/bin/python" -if [[ ! -f "$VENV_PATH" ]]; then +# Check cache first (preferred), then local +if [[ -f "$CACHE_VENV" ]]; then + VENV_PATH="$CACHE_VENV" +elif [[ -f "$LOCAL_VENV" ]]; then + VENV_PATH="$LOCAL_VENV" +else echo "$PREFIX MCP venv missing - run /initial-setup or setup.sh" exit 0 fi diff --git a/plugins/pr-review/hooks/startup-check.sh b/plugins/pr-review/hooks/startup-check.sh index c53fb16..6269e40 100755 --- a/plugins/pr-review/hooks/startup-check.sh +++ b/plugins/pr-review/hooks/startup-check.sh @@ -5,13 +5,18 @@ PREFIX="[pr-review]" -# Check if MCP venv exists +# Check if MCP venv exists - check cache first, then local +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/gitea/.venv/bin/python" PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}" -# MCP servers are at marketplace root, not inside plugin MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")" -VENV_PATH="$MARKETPLACE_ROOT/mcp-servers/gitea/.venv/bin/python" +LOCAL_VENV="$MARKETPLACE_ROOT/mcp-servers/gitea/.venv/bin/python" -if [[ ! -f "$VENV_PATH" ]]; then +# Check cache first (preferred), then local +if [[ -f "$CACHE_VENV" ]]; then + VENV_PATH="$CACHE_VENV" +elif [[ -f "$LOCAL_VENV" ]]; then + VENV_PATH="$LOCAL_VENV" +else echo "$PREFIX MCP venvs missing - run setup.sh from installed marketplace" exit 0 fi