#!/usr/bin/env bash # MnemoCore Integration Setup # ============================ # One-command setup for Claude Code, Gemini CLI, Aider, and universal tools. # # Usage: # ./setup.sh # Interactive, choose integrations # ./setup.sh --all # Enable all integrations # ./setup.sh --claude-code # Claude Code only # ./setup.sh --gemini # Gemini CLI only # ./setup.sh --aider # Aider only # # Prerequisites: # - Python 3.10+ with 'requests' package # - MnemoCore running (uvicorn mnemocore.api.main:app --port 8100) # - HAIM_API_KEY environment variable set set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" MNEMOCORE_DIR="$(realpath "$SCRIPT_DIR/..")" BRIDGE_PY="$SCRIPT_DIR/mnemo_bridge.py" HOOKS_DIR="$SCRIPT_DIR/claude_code/hooks" CLAUDE_SETTINGS="$HOME/.claude/settings.json" CLAUDE_MCP="$HOME/.claude/mcp.json" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # ── Helpers ──────────────────────────────────────────────────────────────── info() { echo -e "${BLUE}[INFO]${NC} $*"; } success() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } check_python() { if ! python3 -c "import requests" &>/dev/null; then warn "Python 'requests' not installed. Installing..." python3 -m pip install --quiet requests success "requests installed" fi } check_mnemocore() { info "Checking MnemoCore connectivity..." if python3 "$BRIDGE_PY" health &>/dev/null; then success "MnemoCore is online" return 0 else warn "MnemoCore is not running. Start it first with:" warn " cd $MNEMOCORE_DIR && uvicorn mnemocore.api.main:app --port 8100" return 1 fi } merge_json() { # Merge JSON object $2 into file $1 (creates if not exists) local target="$1" local fragment="$2" if [[ ! -f "$target" ]]; then echo '{}' > "$target" fi python3 - < "$mcp_tmp" if [[ ! -f "$CLAUDE_MCP" ]]; then echo '{"mcpServers": {}}' > "$CLAUDE_MCP" fi python3 - "$CLAUDE_MCP" "$mcp_tmp" <<'PYEOF' import json, sys with open(sys.argv[1]) as f: existing = json.load(f) with open(sys.argv[2]) as f: new = json.load(f) existing.setdefault("mcpServers", {}).update(new.get("mcpServers", {})) with open(sys.argv[1], "w") as f: json.dump(existing, f, indent=2) PYEOF rm -f "$mcp_tmp" success " MCP server registered in $CLAUDE_MCP" # 2. Hooks info " Installing hooks in $CLAUDE_SETTINGS..." if [[ ! -f "$CLAUDE_SETTINGS" ]]; then echo '{}' > "$CLAUDE_SETTINGS" fi python3 - "$CLAUDE_SETTINGS" "$HOOKS_DIR" <> "$clause_md" cat "$snippet" >> "$clause_md" success " Memory instructions appended to $clause_md" fi success "Claude Code integration complete" } # ── Integration: Gemini CLI ──────────────────────────────────────────────── setup_gemini() { info "Setting up Gemini CLI integration..." # Make wrapper executable chmod +x "$SCRIPT_DIR/gemini_cli/gemini_wrap.sh" # Append to GEMINI.md if it exists local gemini_md="$MNEMOCORE_DIR/GEMINI.md" local snippet="$SCRIPT_DIR/gemini_cli/GEMINI_memory_snippet.md" local marker="# MnemoCore — Persistent Cognitive Memory" if [[ -f "$gemini_md" ]] && grep -qF "$marker" "$gemini_md"; then info " GEMINI.md already contains MnemoCore instructions" elif [[ -f "$gemini_md" ]]; then echo "" >> "$gemini_md" cat "$snippet" >> "$gemini_md" success " Memory instructions appended to $gemini_md" else cp "$snippet" "$gemini_md" success " Created $gemini_md with memory instructions" fi success "Gemini CLI integration complete" info " Use: $SCRIPT_DIR/gemini_cli/gemini_wrap.sh [args] instead of 'gemini'" info " Or alias: alias gemini='$SCRIPT_DIR/gemini_cli/gemini_wrap.sh'" } # ── Integration: Aider ───────────────────────────────────────────────────── setup_aider() { info "Setting up Aider integration..." chmod +x "$SCRIPT_DIR/aider/aider_wrap.sh" # Write .env fragment for aider local aider_env="$MNEMOCORE_DIR/.aider.env" cat > "$aider_env" <