#!/usr/bin/env bash set -euo pipefail # ============================================================================ # Clawdbot Memory System — One-Command Installer v2.0 # https://github.com/BusyBee3333/clawdbot-memory-system # # Usage: # bash install.sh # Interactive install # bash install.sh --dry-run # Preview changes without applying # bash install.sh --uninstall # Remove memory system config # ============================================================================ VERSION="2.0.0" # --- Colors & Formatting --- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' MAGENTA='\033[0;35m' CYAN='\033[0;36m' BOLD='\033[1m' DIM='\033[2m' NC='\033[0m' # --- State --- DRY_RUN=false UNINSTALL=false CLAWDBOT_DIR="" WORKSPACE_DIR="" CONFIG_FILE="" AGENTS_FILE="" MEMORY_DIR="" PROVIDER="" API_KEY="" INSTALL_ORG_SYSTEM=false INSTALL_AUTO_SCAFFOLD=false INSTALL_GIT_BACKUP=false CHANGES_MADE=() FILES_INDEXED=0 EXISTING_MEMORY_FILES=0 # --- Parse Args --- for arg in "$@"; do case "$arg" in --dry-run) DRY_RUN=true ;; --uninstall) UNINSTALL=true ;; --help|-h) echo "Clawdbot Memory System Installer v${VERSION}" echo "" echo "Usage:" echo " bash install.sh Interactive install" echo " bash install.sh --dry-run Preview changes without applying" echo " bash install.sh --uninstall Remove memory system config" exit 0 ;; *) echo -e "${RED}Unknown option: $arg${NC}" echo "Use --help for usage information." exit 1 ;; esac done # --- Helper Functions --- info() { echo -e "${BLUE}ℹ${NC} $1"; } success() { echo -e "${GREEN}✅${NC} $1"; } warn() { echo -e "${YELLOW}⚠️${NC} $1"; } error() { echo -e "${RED}❌${NC} $1"; } step() { echo -e "\n${BOLD}${MAGENTA}$1${NC}"; } detail() { echo -e " ${DIM}$1${NC}"; } dry() { echo -e " ${CYAN}[dry-run]${NC} $1"; } jake() { echo -e " ${YELLOW}⭐ Jake's choice${NC}"; } banner() { echo "" echo -e "${BOLD}${MAGENTA}" echo " ╔══════════════════════════════════════════════╗" echo " ║ 🧠 Clawdbot Memory System v${VERSION} ║" echo " ║ Never lose context to compaction again ║" echo " ╚══════════════════════════════════════════════╝" echo -e "${NC}" } # --- Detect Clawdbot Installation --- detect_clawdbot() { step "STEP 1/9 — 🔍 Detecting Clawdbot installation..." for dir in "$HOME/.clawdbot" "$HOME/.openclaw" "$HOME/.moltbot"; do if [[ -d "$dir" ]]; then CLAWDBOT_DIR="$dir" break fi done if [[ -z "$CLAWDBOT_DIR" ]]; then error "Clawdbot installation not found!" echo "" echo " Looked in: ~/.clawdbot, ~/.openclaw, ~/.moltbot" echo " Make sure Clawdbot is installed first: https://docs.clawd.bot/getting-started" exit 1 fi success "Found Clawdbot at ${BOLD}${CLAWDBOT_DIR}${NC}" CONFIG_FILE="${CLAWDBOT_DIR}/clawdbot.json" if [[ ! -f "$CONFIG_FILE" ]]; then for name in "openclaw.json" "moltbot.json"; do if [[ -f "${CLAWDBOT_DIR}/${name}" ]]; then CONFIG_FILE="${CLAWDBOT_DIR}/${name}" break fi done fi if [[ ! -f "$CONFIG_FILE" ]]; then error "Config file not found at ${CONFIG_FILE}" echo " Run 'clawdbot doctor' first to initialize your setup." exit 1 fi success "Found config at ${BOLD}${CONFIG_FILE}${NC}" WORKSPACE_DIR=$(python3 -c " import json, os with open('${CONFIG_FILE}') as f: cfg = json.load(f) ws = cfg.get('agents', {}).get('defaults', {}).get('workspace', '') if not ws: ws = os.path.expanduser('~') + '/' + os.path.basename('${CLAWDBOT_DIR}') + '/workspace' print(os.path.expanduser(ws)) " 2>/dev/null || echo "${CLAWDBOT_DIR}/workspace") if [[ ! -d "$WORKSPACE_DIR" ]]; then warn "Workspace directory not found at ${WORKSPACE_DIR}" if $DRY_RUN; then dry "Would create workspace directory" else mkdir -p "$WORKSPACE_DIR" success "Created workspace directory" fi fi success "Workspace: ${BOLD}${WORKSPACE_DIR}${NC}" MEMORY_DIR="${WORKSPACE_DIR}/memory" AGENTS_FILE="${WORKSPACE_DIR}/AGENTS.md" } # --- Check Dependencies --- check_deps() { step "STEP 2/9 — 🔧 Checking dependencies..." if ! command -v jq &>/dev/null; then warn "jq is not installed (needed for safe JSON config patching)" if command -v brew &>/dev/null; then read -rp " Install with Homebrew? [Y/n] " yn yn=${yn:-Y} if [[ "$yn" =~ ^[Yy] ]]; then if $DRY_RUN; then dry "Would run: brew install jq" else brew install jq success "jq installed" fi else error "jq is required. Install: brew install jq" exit 1 fi else error "jq required: https://jqlang.github.io/jq/download/" exit 1 fi else success "jq found: $(jq --version)" fi if ! command -v clawdbot &>/dev/null; then if command -v openclaw &>/dev/null; then alias clawdbot=openclaw success "openclaw CLI found" elif command -v moltbot &>/dev/null; then alias clawdbot=moltbot success "moltbot CLI found" else warn "clawdbot CLI not found — index build will be skipped" fi else success "clawdbot CLI found" fi } # --- Check Existing Memory Files --- check_existing() { step "STEP 3/9 — 📂 Checking existing memory files..." if [[ -d "$MEMORY_DIR" ]]; then EXISTING_MEMORY_FILES=$(find "$MEMORY_DIR" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ') if [[ "$EXISTING_MEMORY_FILES" -gt 0 ]]; then info "Found ${BOLD}${EXISTING_MEMORY_FILES}${NC} existing memory files — they'll be preserved and indexed" echo "" echo -e " ${DIM}Existing files:${NC}" find "$MEMORY_DIR" -name "*.md" -type f 2>/dev/null | while read -r f; do echo -e " ${DIM}$(basename "$f")${NC}" done else info "Memory directory exists but is empty" fi else info "No existing memory directory — will create one" fi if [[ -f "${WORKSPACE_DIR}/MEMORY.md" ]]; then info "Found existing MEMORY.md — will be included in index" fi } # --- Core Memory System Confirmation --- confirm_core() { step "STEP 4/9 — 🧠 Core Memory System" echo "" echo -e " ${BOLD}This installs:${NC}" echo -e " ${GREEN}•${NC} Daily log system — agent writes ${CYAN}memory/YYYY-MM-DD.md${NC} each session" echo -e " capturing decisions, preferences, project progress, and blockers" echo -e " ${GREEN}•${NC} SQLite vector search index — semantic search over all memory files" echo -e " (finds context even when wording differs, <100ms)" echo -e " ${GREEN}•${NC} Hybrid search — 70% vector similarity + 30% keyword matching" echo -e " ${GREEN}•${NC} Pre-compaction auto-flush — auto-saves context BEFORE session" echo -e " compacts, so your agent never gets amnesia" echo -e " ${GREEN}•${NC} Agent instructions — tells your agent when and how to use memory" echo -e " ${GREEN}•${NC} Config patch — adds memorySearch settings without touching your" echo -e " existing config (backs up first)" echo "" echo -e " ${DIM}Cost: ~\$0.50/month (OpenAI) or free (Gemini free tier / local)${NC}" echo "" jake echo "" read -rp " Install core memory system? [Y/n] " yn yn=${yn:-Y} if [[ ! "$yn" =~ ^[Yy] ]]; then error "Core memory system is required. Exiting." exit 0 fi success "Core memory system will be installed" } # --- Choose Embedding Provider --- choose_provider() { step "STEP 5/9 — 🤖 Choose your embedding provider" echo "" echo -e " How should your agent generate search embeddings?" echo "" echo -e " ${BOLD}1)${NC} ${GREEN}OpenAI${NC} ${DIM}— fast, cheap (~\$0.02/M tokens), best quality${NC}" jake echo "" echo -e " ${BOLD}2)${NC} ${BLUE}Gemini${NC} ${DIM}— free tier available, good quality${NC}" echo "" echo -e " ${BOLD}3)${NC} ${YELLOW}Local${NC} ${DIM}— fully offline, no API key, slower first build${NC}" echo "" read -rp " Choose [1/2/3] (default: 1): " choice choice=${choice:-1} case "$choice" in 1) PROVIDER="openai" ;; 2) PROVIDER="gemini" ;; 3) PROVIDER="local" ;; *) warn "Invalid choice, defaulting to OpenAI" PROVIDER="openai" ;; esac success "Selected: ${BOLD}${PROVIDER}${NC}" if [[ "$PROVIDER" == "openai" ]]; then if [[ -n "${OPENAI_API_KEY:-}" ]]; then info "Found OPENAI_API_KEY in environment" else echo "" echo -e " ${DIM}OpenAI API key is needed for embeddings.${NC}" echo -e " ${DIM}Get one at: https://platform.openai.com/api-keys${NC}" echo -e " ${DIM}(Press Enter to skip — you can set OPENAI_API_KEY env var later)${NC}" echo "" read -rsp " OpenAI API Key: " API_KEY echo "" [[ -n "$API_KEY" ]] && success "API key provided" || warn "No key — set OPENAI_API_KEY before using memory search" fi elif [[ "$PROVIDER" == "gemini" ]]; then if [[ -n "${GEMINI_API_KEY:-}" ]]; then info "Found GEMINI_API_KEY in environment" else echo "" echo -e " ${DIM}Gemini API key is needed for embeddings.${NC}" echo -e " ${DIM}Get one at: https://aistudio.google.com/apikey${NC}" echo -e " ${DIM}(Press Enter to skip — you can set GEMINI_API_KEY env var later)${NC}" echo "" read -rsp " Gemini API Key: " API_KEY echo "" [[ -n "$API_KEY" ]] && success "API key provided" || warn "No key — set GEMINI_API_KEY before using memory search" fi fi } # --- Organization System (Optional) --- offer_org_system() { step "STEP 6/9 — 📁 Organization System (optional add-on)" echo "" echo -e " ${BOLD}This adds a project organization framework on top of memory:${NC}" echo "" echo -e " ${GREEN}📁 Project Quickstart${NC}" echo -e " When you start any new project, your agent automatically creates" echo -e " structured tracking files with consistent naming so everything" echo -e " is searchable and organized from day one." echo "" echo -e " ${GREEN}🔬 Research Intel System${NC}" echo -e " For ongoing monitoring (competitors, markets, trends). Current week's" echo -e " intel stays detailed at top, older weeks auto-compress to summaries." echo -e " Agent checks these before making strategic recommendations." echo "" echo -e " ${GREEN}📊 Project Tracking${NC}" echo -e " Standardized stages, blockers, decisions, and handoffs. Never lose" echo -e " track of where a project stands across sessions." echo "" echo -e " ${GREEN}🏷️ Tag Convention${NC}" echo -e " Consistent file naming (${CYAN}{project}-progress.md${NC}," echo -e " ${CYAN}{project}-research-intel.md${NC}) so memory search groups" echo -e " everything by project automatically." echo "" jake echo "" read -rp " Install the organization system? [Y/n] " yn yn=${yn:-Y} if [[ "$yn" =~ ^[Yy] ]]; then INSTALL_ORG_SYSTEM=true success "Organization system will be installed" else info "Skipping organization system (you can add it later by re-running the installer)" fi } # --- Auto-Scaffold for New Projects --- offer_auto_scaffold() { if ! $INSTALL_ORG_SYSTEM; then return; fi step "STEP 7/9 — 🚀 New Project Auto-Scaffold" echo "" echo -e " ${BOLD}When enabled, your agent auto-creates files for new projects.${NC}" echo "" echo -e " Example: You say ${DIM}\"Let's start a competitor analysis for Acme Corp\"${NC}" echo -e " Agent automatically creates:" echo -e " ${CYAN}memory/acme-corp-progress.md${NC} ${DIM}(project tracking)${NC}" echo -e " ${CYAN}memory/acme-corp-research-intel.md${NC} ${DIM}(intel rotation)${NC}" echo "" echo -e " Your agent will ask which templates apply before creating:" echo -e " • Progress tracker? ${DIM}(almost always yes)${NC}" echo -e " • Research intel? ${DIM}(if monitoring/research is involved)${NC}" echo -e " • Contacts tracker? ${DIM}(if other people are involved)${NC}" echo "" jake echo "" read -rp " Enable auto-scaffold for new projects? [Y/n] " yn yn=${yn:-Y} if [[ "$yn" =~ ^[Yy] ]]; then INSTALL_AUTO_SCAFFOLD=true success "Auto-scaffold enabled" else info "Skipping auto-scaffold" fi } # --- Git Backup --- offer_git_backup() { step "STEP 8/9 — 💾 Git Backup" echo "" echo -e " ${BOLD}Back up memory files to git for version history and offsite safety.${NC}" echo "" echo -e " Your agent will be instructed to run:" echo -e " ${DIM}cd ~/.clawdbot/workspace && git add -A && git commit -m \"backup\" && git push${NC}" echo -e " at the end of each session or major milestone." echo "" echo -e " ${DIM}If your workspace isn't a git repo yet, you'll need to:${NC}" echo -e " ${DIM} cd ~/.clawdbot/workspace && git init && git remote add origin ${NC}" echo "" jake echo "" read -rp " Include git backup instructions? [Y/n] " yn yn=${yn:-Y} if [[ "$yn" =~ ^[Yy] ]]; then INSTALL_GIT_BACKUP=true success "Git backup instructions will be included" else info "Skipping git backup" fi } # --- Setup Memory Directory & Templates --- setup_memory_dir() { step "STEP 9/9 — 📝 Installing..." echo "" info "Setting up memory directory and templates..." if $DRY_RUN; then [[ ! -d "$MEMORY_DIR" ]] && dry "Would create ${MEMORY_DIR}/" dry "Would copy template files" $INSTALL_ORG_SYSTEM && dry "Would copy organization templates" return fi # Create memory directory if [[ ! -d "$MEMORY_DIR" ]]; then mkdir -p "$MEMORY_DIR" success "Created ${MEMORY_DIR}/" CHANGES_MADE+=("Created memory/ directory") fi # Determine template source local script_dir script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" local templates_dir="${script_dir}/templates" local base_url="https://raw.githubusercontent.com/BusyBee3333/clawdbot-memory-system/main/templates" # If running from curl (no local templates dir), download them if [[ ! -d "$templates_dir" ]]; then templates_dir=$(mktemp -d) for tmpl in TEMPLATE-daily.md TEMPLATE-research-intel.md TEMPLATE-project-tracking.md TEMPLATE-contacts.md; do curl -sL "${base_url}/${tmpl}" -o "${templates_dir}/${tmpl}" 2>/dev/null || true done fi # Always copy daily template if [[ -f "${templates_dir}/TEMPLATE-daily.md" ]] && [[ ! -f "${MEMORY_DIR}/TEMPLATE-daily.md" ]]; then cp "${templates_dir}/TEMPLATE-daily.md" "${MEMORY_DIR}/TEMPLATE-daily.md" success "Added template: TEMPLATE-daily.md" CHANGES_MADE+=("Added TEMPLATE-daily.md") fi # Copy org system templates if selected if $INSTALL_ORG_SYSTEM; then for tmpl in TEMPLATE-research-intel.md TEMPLATE-project-tracking.md TEMPLATE-contacts.md; do if [[ -f "${templates_dir}/${tmpl}" ]] && [[ ! -f "${MEMORY_DIR}/${tmpl}" ]]; then cp "${templates_dir}/${tmpl}" "${MEMORY_DIR}/${tmpl}" success "Added template: ${tmpl}" CHANGES_MADE+=("Added ${tmpl}") fi done fi # Create today's daily log local today today=$(date +%Y-%m-%d) if [[ ! -f "${MEMORY_DIR}/${today}.md" ]]; then cat > "${MEMORY_DIR}/${today}.md" << EOF # Daily Log — ${today} ## What We Worked On - Installed Clawdbot Memory System 🧠 ## Decisions Made - Chose ${PROVIDER} for embeddings $(${INSTALL_ORG_SYSTEM} && echo "- Enabled organization system with project scaffolding" || true) $(${INSTALL_GIT_BACKUP} && echo "- Set up git backup for memory files" || true) ## Next Steps - Start using the memory system naturally — agent writes daily logs - Check memory/ directory for accumulated context over time ## Open Questions / Blockers - (none) ## Notable Context Memory system installed and indexed. Agent will now persist important context across sessions and search it automatically before answering questions. EOF success "Created today's daily log: ${today}.md" CHANGES_MADE+=("Created daily log ${today}.md") fi } # --- Patch clawdbot.json --- patch_config() { info "Patching clawdbot.json..." local existing_provider existing_provider=$(jq -r '.agents.defaults.memorySearch.provider // empty' "$CONFIG_FILE" 2>/dev/null || true) if [[ -n "$existing_provider" ]]; then info "memorySearch already configured (provider: ${existing_provider})" read -rp " Overwrite with new provider ($PROVIDER)? [y/N] " yn yn=${yn:-N} if [[ ! "$yn" =~ ^[Yy] ]]; then info "Keeping existing config" return fi fi if $DRY_RUN; then dry "Would patch clawdbot.json with memorySearch (${PROVIDER})" return fi cp "$CONFIG_FILE" "${CONFIG_FILE}.pre-memory-backup" success "Backed up config → clawdbot.json.pre-memory-backup" local memory_config case "$PROVIDER" in openai) memory_config='{"provider":"openai","model":"text-embedding-3-small","query":{"hybrid":{"enabled":true,"vectorWeight":0.7,"textWeight":0.3,"candidateMultiplier":4}}}' [[ -n "$API_KEY" ]] && memory_config=$(echo "$memory_config" | jq --arg key "$API_KEY" '. + {remote: {apiKey: $key}}') ;; gemini) memory_config='{"provider":"gemini","model":"gemini-embedding-001"}' [[ -n "$API_KEY" ]] && memory_config=$(echo "$memory_config" | jq --arg key "$API_KEY" '. + {remote: {apiKey: $key}}') ;; local) memory_config='{"provider":"local","fallback":"none"}' ;; esac local tmp_file tmp_file=$(mktemp) jq --argjson ms "$memory_config" '.agents.defaults.memorySearch = ((.agents.defaults.memorySearch // {}) * $ms)' "$CONFIG_FILE" > "$tmp_file" if jq empty "$tmp_file" 2>/dev/null; then mv "$tmp_file" "$CONFIG_FILE" success "Added memorySearch config (provider: ${PROVIDER})" CHANGES_MADE+=("Patched clawdbot.json (${PROVIDER} embeddings)") else rm -f "$tmp_file" error "Failed to patch config — restoring backup" cp "${CONFIG_FILE}.pre-memory-backup" "$CONFIG_FILE" exit 1 fi } # --- Patch AGENTS.md --- patch_agents() { info "Updating AGENTS.md..." if [[ -f "$AGENTS_FILE" ]] && grep -q "Memory System (auto-added by clawdbot-memory-system" "$AGENTS_FILE" 2>/dev/null; then info "AGENTS.md already contains memory instructions — updating" # Remove old section before re-adding python3 -c " import re with open('${AGENTS_FILE}') as f: content = f.read() content = re.sub(r'\n*## Memory System \(auto-added by clawdbot-memory-system.*?\n(?=## [^M]|\Z)', '\n', content, flags=re.DOTALL) with open('${AGENTS_FILE}', 'w') as f: f.write(content.rstrip() + '\n') " 2>/dev/null || true fi if $DRY_RUN; then dry "Would append memory + org instructions to AGENTS.md" return fi # Build the patch content local patch="" patch+=" ## Memory System (auto-added by clawdbot-memory-system installer v${VERSION}) ### Mandatory Memory Recall Before answering ANY question about prior work, decisions, dates, people, preferences, or context from previous sessions: 1. Run \`memory_search\` with a relevant query 2. Use \`memory_get\` to pull specific lines if needed 3. Check today's daily log: \`memory/YYYY-MM-DD.md\` 4. Check yesterday's log if today's is sparse 5. Only say \"I don't recall\" if memory search returns nothing ### Daily Memory Log - Write to \`memory/YYYY-MM-DD.md\` throughout the session - Log: decisions made, user preferences discovered, project progress, action items, blockers - Be specific — future-you needs exact details, not vague summaries - Include: names, URLs, version numbers, error messages, config values — anything painful to re-discover - On session start, read today + yesterday's logs to restore context ### Pre-Compaction Flush When you sense a session is getting long or receive a compaction warning: - Write ALL important unsaved context to today's daily log immediately - Include: what we were working on, where we left off, any pending decisions, partial results - This is your last chance before amnesia — be thorough, not brief" if $INSTALL_ORG_SYSTEM; then patch+=" ### Organization System — Project Files When starting any new project or workstream, create structured tracking files: **File naming convention:** \`memory/{project-slug}-{type}.md\` - \`{project-slug}\`: lowercase, hyphenated (e.g., \`acme-analysis\`, \`competitor-intel\`) - \`{type}\`: one of \`progress\`, \`research-intel\`, \`contacts\` **Templates available in memory/ directory:** - \`TEMPLATE-project-tracking.md\` — stages, blockers, decisions, next steps - \`TEMPLATE-research-intel.md\` — weekly intel rotation with auto-compression - \`TEMPLATE-contacts.md\` — people, roles, access levels" fi if $INSTALL_AUTO_SCAFFOLD; then patch+=" ### Auto-Scaffold for New Projects When the user says anything like \"start a new project\", \"let's work on X\", or \"begin tracking Y\": 1. Ask which templates apply: - Progress tracker? (almost always yes) - Research intel? (if monitoring/research is involved) - Contacts tracker? (if other people are involved) 2. Create the files using the naming convention: \`memory/{project-slug}-{type}.md\` 3. Copy from the templates in memory/ directory 4. Replace {placeholders} with actual project details 5. Add the project to today's daily log under \"What We Worked On\" 6. Confirm what was created and what each file is for" fi patch+=" ### Research Intel System For ongoing research/monitoring projects: - Store in: \`memory/{project}-research-intel.md\` - Current week's detailed intel at TOP of file - Compressed 1-3 sentence summaries of previous weeks at BOTTOM - Weekly: compress last week to summary, add new detailed intel at top - When asked about action items or strategy, check active research intel files first" if $INSTALL_GIT_BACKUP; then patch+=" ### Git Backup Habit End of each session or major milestone: \`\`\`bash cd ~/.clawdbot/workspace && git add -A && git commit -m \"session backup: \$(date +%Y-%m-%d)\" && git push \`\`\` This keeps identity, memory, and progress backed up offsite. Remind the user if they haven't backed up recently." fi if [[ -f "$AGENTS_FILE" ]]; then echo "" >> "$AGENTS_FILE" echo "$patch" >> "$AGENTS_FILE" else echo "$patch" > "$AGENTS_FILE" fi success "Updated AGENTS.md with memory instructions" $INSTALL_ORG_SYSTEM && success "Added organization system to AGENTS.md" $INSTALL_AUTO_SCAFFOLD && success "Added auto-scaffold instructions to AGENTS.md" $INSTALL_GIT_BACKUP && success "Added git backup habit to AGENTS.md" CHANGES_MADE+=("Updated AGENTS.md") } # --- Build Index --- build_index() { info "Building memory search index..." if $DRY_RUN; then dry "Would run: clawdbot memory index --verbose" return fi if ! command -v clawdbot &>/dev/null; then warn "clawdbot CLI not in PATH — skipping index build" detail "Run manually: clawdbot memory index --verbose" return fi echo -e "${DIM}" if clawdbot memory index --verbose 2>&1; then echo -e "${NC}" success "Index built successfully" else echo -e "${NC}" warn "Index build had issues — run 'clawdbot memory status --deep' to check" fi FILES_INDEXED=$(find "$MEMORY_DIR" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ') [[ -f "${WORKSPACE_DIR}/MEMORY.md" ]] && FILES_INDEXED=$((FILES_INDEXED + 1)) } # --- Review & Confirm --- review_confirm() { echo "" echo -e "${BOLD}${CYAN}" echo " ╔══════════════════════════════════════════════╗" echo " ║ 📋 Review Before Installing ║" echo " ╚══════════════════════════════════════════════╝" echo -e "${NC}" echo "" echo -e " ${BOLD}Will install:${NC}" echo "" echo -e " ${GREEN}✅${NC} Core Memory System" echo -e " ${DIM}• memory/ directory with daily log template${NC}" echo -e " ${DIM}• SQLite vector search (${PROVIDER} embeddings)${NC}" echo -e " ${DIM}• Pre-compaction auto-flush${NC}" echo -e " ${DIM}• Agent instructions in AGENTS.md${NC}" if $INSTALL_ORG_SYSTEM; then echo "" echo -e " ${GREEN}✅${NC} Organization System" echo -e " ${DIM}• Project tracking template${NC}" echo -e " ${DIM}• Research intel template${NC}" echo -e " ${DIM}• Contacts template${NC}" echo -e " ${DIM}• Tag naming convention${NC}" else echo "" echo -e " ${DIM}⏭️ Organization System (skipped)${NC}" fi if $INSTALL_AUTO_SCAFFOLD; then echo "" echo -e " ${GREEN}✅${NC} Auto-Scaffold for New Projects" fi if $INSTALL_GIT_BACKUP; then echo "" echo -e " ${GREEN}✅${NC} Git Backup Instructions" fi echo "" echo -e " ${BOLD}Config changes:${NC}" echo -e " ${DIM}• clawdbot.json → adding memorySearch config${NC}" echo -e " ${DIM}• AGENTS.md → appending memory instructions${NC}" echo -e " ${DIM}• Backup: clawdbot.json.pre-memory-backup${NC}" if [[ "$EXISTING_MEMORY_FILES" -gt 0 ]]; then echo "" echo -e " ${BOLD}Migration:${NC}" echo -e " ${DIM}• ${EXISTING_MEMORY_FILES} existing memory files will be preserved and indexed${NC}" fi echo "" read -rp " Proceed with installation? [Y/n] " yn yn=${yn:-Y} if [[ ! "$yn" =~ ^[Yy] ]]; then info "Installation cancelled" exit 0 fi } # --- Print Summary --- print_summary() { echo "" echo -e "${BOLD}${GREEN}" echo " ╔══════════════════════════════════════════════╗" echo " ║ 🎉 Installation Complete! ║" echo " ╚══════════════════════════════════════════════╝" echo -e "${NC}" if [[ ${#CHANGES_MADE[@]} -gt 0 ]]; then echo -e " ${BOLD}Changes made:${NC}" for change in "${CHANGES_MADE[@]}"; do echo -e " ${GREEN}✓${NC} ${change}" done echo "" fi if [[ "$EXISTING_MEMORY_FILES" -gt 0 ]]; then echo -e " ${BOLD}Migration:${NC}" echo -e " 📁 ${EXISTING_MEMORY_FILES} existing memory files preserved and indexed" echo "" fi echo -e " ${BOLD}Index:${NC}" echo -e " 📊 ${FILES_INDEXED} memory files indexed" echo -e " 🤖 Provider: ${PROVIDER}" echo "" echo -e " ${BOLD}${CYAN}Next steps:${NC}" echo "" echo -e " ${BOLD}1.${NC} Restart the gateway to apply config changes:" echo -e " ${DIM}clawdbot gateway restart${NC}" echo "" echo -e " ${BOLD}2.${NC} Start chatting! Your agent will now:" echo -e " • Write daily logs to ${CYAN}memory/YYYY-MM-DD.md${NC}" echo -e " • Search memories before answering about prior work" echo -e " • Flush context before compaction (no more amnesia!)" if $INSTALL_ORG_SYSTEM; then echo -e " • Create structured files when you start new projects" fi echo "" echo -e " ${BOLD}3.${NC} Test it! Ask your agent:" echo -e " ${DIM}\"What did we work on today?\"${NC}" if $INSTALL_AUTO_SCAFFOLD; then echo -e " ${DIM}\"Start a new project called competitor analysis\"${NC}" fi echo "" echo -e " ${BOLD}4.${NC} Verify anytime:" echo -e " ${DIM}clawdbot memory status --deep${NC}" echo "" if [[ -n "$API_KEY" ]]; then echo -e " ${YELLOW}⚠️ Your API key was saved to clawdbot.json.${NC}" echo -e " ${DIM} Alternatively, set as env var and remove from config.${NC}" echo "" fi echo -e " ${DIM}Your agent will NEVER forget again. ᕕ( ᐛ )ᕗ${NC}" echo "" echo -e " ${DIM}Problems? https://github.com/BusyBee3333/clawdbot-memory-system#troubleshooting${NC}" echo "" } # --- Uninstall --- do_uninstall() { banner step "🗑️ Uninstalling Clawdbot Memory System..." detect_clawdbot echo "" warn "This will:" echo " • Remove memorySearch config from clawdbot.json" echo " • Remove memory instructions from AGENTS.md" echo "" echo -e " ${BOLD}This will NOT delete your memory/ files.${NC}" echo " Your memories are safe — only the config is removed." echo "" read -rp " Continue? [y/N] " yn yn=${yn:-N} [[ ! "$yn" =~ ^[Yy] ]] && { info "Cancelled"; exit 0; } if [[ -f "$CONFIG_FILE" ]] && jq -e '.agents.defaults.memorySearch' "$CONFIG_FILE" &>/dev/null; then cp "$CONFIG_FILE" "${CONFIG_FILE}.pre-uninstall-backup" local tmp_file; tmp_file=$(mktemp) jq 'del(.agents.defaults.memorySearch)' "$CONFIG_FILE" > "$tmp_file" if jq empty "$tmp_file" 2>/dev/null; then mv "$tmp_file" "$CONFIG_FILE" success "Removed memorySearch from config" else rm -f "$tmp_file"; error "Failed to patch config" fi fi if [[ -f "$AGENTS_FILE" ]] && grep -q "Memory System (auto-added by clawdbot-memory-system" "$AGENTS_FILE" 2>/dev/null; then cp "$AGENTS_FILE" "${AGENTS_FILE}.pre-uninstall-backup" python3 -c " import re with open('${AGENTS_FILE}') as f: content = f.read() content = re.sub(r'\n*## Memory System \(auto-added by clawdbot-memory-system.*', '', content, flags=re.DOTALL) with open('${AGENTS_FILE}', 'w') as f: f.write(content.rstrip() + '\n') " 2>/dev/null || true success "Removed memory instructions from AGENTS.md" fi echo "" success "Uninstall complete" echo -e " ${DIM}Memory files preserved. Run 'clawdbot gateway restart' to apply.${NC}" exit 0 } # ============================================================================ # Main Flow # ============================================================================ [[ "$UNINSTALL" == true ]] && do_uninstall banner $DRY_RUN && echo -e " ${CYAN}${BOLD}Running in dry-run mode — no changes will be made${NC}\n" # Interactive onboarding detect_clawdbot # Step 1 check_deps # Step 2 check_existing # Step 3 confirm_core # Step 4 choose_provider # Step 5 offer_org_system # Step 6 offer_auto_scaffold # Step 7 offer_git_backup # Step 8 review_confirm # Review # Install setup_memory_dir # Step 9 (creates dirs + templates) patch_config # (patches clawdbot.json) patch_agents # (patches AGENTS.md) build_index # (builds SQLite index) # Done if $DRY_RUN; then echo "" echo -e " ${CYAN}${BOLD}Dry run complete — no changes were made.${NC}" echo -e " ${DIM}Run without --dry-run to apply.${NC}" echo "" else print_summary fi