fix(hooks): remove all venv auto-repair code that deleted .venv directories

BREAKING: Removes automatic venv management that was causing session failures

Changes:
- Delete scripts/venv-repair.sh (was deleting and recreating venvs)
- Remove auto-repair code from projman/hooks/startup-check.sh
- Remove venv-repair call from scripts/post-update.sh
- Remove rm -rf .venv instructions from docs/UPDATING.md and CONFIGURATION.md
- Update docs/CANONICAL-PATHS.md to remove venv-repair.sh reference

Additionally:
- Add Pre-Change Protocol to CLAUDE.md (mandatory dependency check before edits)
- Add Pre-Change Protocol enforcement to claude-config-maintainer plugin
- Add Development Context section to CLAUDE.md clarifying which plugins are
  used in this project vs only being developed
- Reorganize commands table to separate relevant vs non-relevant commands

The venv auto-repair was the root cause of repeated MCP server failures,
requiring manual setup.sh runs after every session start.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 11:33:25 -05:00
parent e1d7ec46ae
commit 9550a85f4d
11 changed files with 241 additions and 228 deletions

View File

@@ -6,9 +6,10 @@
#
# This script:
# 1. Clears Claude plugin cache (forces fresh .mcp.json reads)
# 2. Restores MCP venv symlinks (instant if cache exists)
# 3. Creates venvs in external cache if missing (first run only)
# 4. Shows recent changelog updates
# 2. Shows recent changelog updates
#
# NOTE: This script does NOT touch .venv directories.
# If venvs are missing, run ./scripts/setup.sh manually.
#
set -euo pipefail
@@ -22,13 +23,11 @@ REPO_ROOT="$(dirname "$SCRIPT_DIR")"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
check_changelog() {
if [[ -f "$REPO_ROOT/CHANGELOG.md" ]]; then
@@ -52,35 +51,21 @@ main() {
# Clear Claude plugin cache to force fresh .mcp.json reads
# This cache holds versioned copies that become stale after updates
# NOTE: This does NOT touch .venv directories
if [[ -d "$CLAUDE_PLUGIN_CACHE" ]]; then
log_info "Clearing Claude plugin cache..."
rm -rf "$CLAUDE_PLUGIN_CACHE"
log_success "Plugin cache cleared"
fi
# Run venv-repair.sh to restore symlinks to external cache
# This is instant if cache exists, or does full setup on first run
if [[ -x "$SCRIPT_DIR/venv-repair.sh" ]]; then
log_info "Restoring MCP venv symlinks..."
if "$SCRIPT_DIR/venv-repair.sh"; then
log_success "MCP venvs ready"
else
log_error "MCP venv setup failed"
log_warn "Run: $SCRIPT_DIR/setup-venvs.sh for full setup"
exit 1
fi
else
log_error "venv-repair.sh not found at $SCRIPT_DIR"
exit 1
fi
check_changelog
echo ""
log_success "Post-update complete!"
echo ""
echo "IMPORTANT: Restart Claude Code for changes to take effect."
echo "MCP servers will work immediately on next session start."
echo ""
echo "If MCP servers are not working, run: ./scripts/setup.sh"
}
main "$@"

View File

@@ -1,169 +0,0 @@
#!/usr/bin/env bash
#
# venv-repair.sh - Fast MCP venv auto-repair for SessionStart hooks
#
# This script is designed to run at session start. It:
# 1. Checks if venvs exist in external cache (~/.cache/claude-mcp-venvs/)
# 2. Creates symlinks from marketplace to cache (instant operation)
# 3. Only runs pip install if cache is missing (first install)
#
# Output format: All messages prefixed with [mcp-venv] for hook display
#
# Usage:
# ./scripts/venv-repair.sh # Auto-repair (default)
# ./scripts/venv-repair.sh --silent # Silent mode (no output unless error)
#
set -euo pipefail
# ============================================================================
# Configuration
# ============================================================================
PREFIX="[mcp-venv]"
VENV_CACHE_DIR="${HOME}/.cache/claude-mcp-venvs/leo-claude-mktplace"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
# MCP servers
MCP_SERVERS=(gitea netbox data-platform viz-platform contract-validator)
# Parse args
SILENT=false
[[ "${1:-}" == "--silent" ]] && SILENT=true
log() {
[[ "$SILENT" == true ]] && return
echo "$PREFIX $1"
}
log_error() {
echo "$PREFIX ERROR: $1" >&2
}
# ============================================================================
# Check if all venvs exist in cache
# ============================================================================
cache_complete() {
for server in "${MCP_SERVERS[@]}"; do
local venv_python="$VENV_CACHE_DIR/$server/.venv/bin/python"
[[ ! -f "$venv_python" ]] && return 1
done
return 0
}
# ============================================================================
# Create symlinks from marketplace to cache
# ============================================================================
create_symlink() {
local server_name="$1"
local server_path="$REPO_ROOT/mcp-servers/$server_name"
local venv_cache="$VENV_CACHE_DIR/$server_name/.venv"
local venv_link="$server_path/.venv"
# Skip if server doesn't exist
[[ ! -d "$server_path" ]] && return 0
# Skip if cache doesn't exist
[[ ! -d "$venv_cache" ]] && return 1
# Already correct symlink?
if [[ -L "$venv_link" ]]; then
local target
target=$(readlink "$venv_link")
[[ "$target" == "$venv_cache" ]] && return 0
rm "$venv_link"
elif [[ -d "$venv_link" ]]; then
# Old venv directory exists - back it up or remove
rm -rf "$venv_link"
fi
# Create symlink
ln -s "$venv_cache" "$venv_link"
return 0
}
create_all_symlinks() {
local created=0
for server in "${MCP_SERVERS[@]}"; do
if create_symlink "$server"; then
((created++)) || true
fi
done
[[ $created -gt 0 ]] && log "Restored $created venv symlinks"
}
# ============================================================================
# Full setup (only if cache missing)
# ============================================================================
setup_server() {
local server_name="$1"
local server_path="$REPO_ROOT/mcp-servers/$server_name"
local venv_path="$VENV_CACHE_DIR/$server_name/.venv"
[[ ! -d "$server_path" ]] && return 0
mkdir -p "$VENV_CACHE_DIR/$server_name"
# Create venv
if [[ ! -d "$venv_path" ]]; then
python3 -m venv "$venv_path"
fi
# Install dependencies
# shellcheck disable=SC1091
source "$venv_path/bin/activate"
pip install -q --upgrade pip
if [[ -f "$server_path/requirements.txt" ]]; then
pip install -q -r "$server_path/requirements.txt"
fi
if [[ -f "$server_path/pyproject.toml" ]]; then
pip install -q -e "$server_path"
fi
deactivate
# Save hash for future quick checks
local hash_file="$VENV_CACHE_DIR/$server_name/.requirements_hash"
{
if [[ -f "$server_path/requirements.txt" ]]; then
cat "$server_path/requirements.txt"
fi
if [[ -f "$server_path/pyproject.toml" ]]; then
cat "$server_path/pyproject.toml"
fi
echo "" # Ensure non-empty input for sha256sum
} | sha256sum | cut -d' ' -f1 > "$hash_file"
}
full_setup() {
log "First run - setting up MCP venvs (this only happens once)..."
for server in "${MCP_SERVERS[@]}"; do
log " Setting up $server..."
setup_server "$server"
done
log "Setup complete. Future sessions will be instant."
}
# ============================================================================
# Main
# ============================================================================
main() {
# Fast path: cache exists, just ensure symlinks
if cache_complete; then
create_all_symlinks
exit 0
fi
# Slow path: need to create venvs (first install)
full_setup
create_all_symlinks
}
main "$@"