---
name: codecontext-installer
description: >-
  Install CodeContext memory system for Claude Code. Interactively sets up hooks,
  skills, and configuration for automatic memory capture across coding sessions.
  USE WHEN: User says "install codecontext", "setup memory system", "configure codecontext",
  or wants to enable automatic learning capture.
allowed-tools: Bash, Read, Write, Edit, Glob, AskUserQuestion
argument-hint: [--global | --project | (interactive)]
---

# CodeContext Installer

This skill installs the CodeContext memory system for Claude Code sessions.

---

## Installation Overview

CodeContext captures learnings from your coding sessions and makes them searchable via semantic similarity. After installation:
- **Session Start**: Injects relevant project context
- **During Session**: Captures prompts for later extraction
- **Session End**: Extracts learnings and generates summaries

---

## Step 1: Determine Installation Mode

First, determine if the user specified a mode or needs to choose interactively.

**If `$ARGUMENTS` contains `--global`**: Use global mode
**If `$ARGUMENTS` contains `--project`**: Use project mode
**Otherwise**: Ask the user

### Ask User (if needed)

Use AskUserQuestion with these options:

```
Question: "How would you like to install CodeContext?"
Header: "Install Mode"
Options:
  1. "Global (Recommended)" - "Active for ALL projects. Hooks installed to ~/.claude/"
  2. "Project Only" - "Active only for THIS project. Hooks installed to ./.claude/"
```

---

## Step 2: Set Paths Based on Mode

### Global Mode
```
CLAUDE_DIR = ~/.claude
DATA_DIR = ~/.codecontext
USE_ABSOLUTE_PATHS = true
```

### Project Mode
```
CLAUDE_DIR = ./.claude
DATA_DIR = ./.codecontext
USE_ABSOLUTE_PATHS = false
```

---

## Step 3: Check for Existing Installation

Check if CodeContext is already installed:

```bash
# Check for existing hooks
ls -la {CLAUDE_DIR}/hooks/codecontext/ 2>/dev/null

# Check for existing marker
cat {DATA_DIR}/.codecontext_mode 2>/dev/null
```

If found, ask user:
```
Question: "CodeContext is already installed. What would you like to do?"
Header: "Existing Install"
Options:
  1. "Reinstall/Update" - "Replace existing hooks with latest version"
  2. "Cancel" - "Keep current installation"
```

---

## Step 4: Backup Existing Settings

If `{CLAUDE_DIR}/settings.json` exists:

```bash
cp {CLAUDE_DIR}/settings.json {CLAUDE_DIR}/settings.backup.$(date +%Y%m%d_%H%M%S).json
```

Report: "Created backup at {backup_path}"

---

## Step 5: Create Directory Structure

```bash
mkdir -p {CLAUDE_DIR}/hooks/codecontext
mkdir -p {CLAUDE_DIR}/skills/codecontext
mkdir -p {DATA_DIR}/projects
mkdir -p {DATA_DIR}/temp
```

---

## Step 6: Locate and Copy Hook Files

### Option A: From pip package (if installed)
```bash
# Find package location
python -c "import codecontext; print(codecontext.__file__)" 2>/dev/null
```

If found, copy from `{package_dir}/../../../hooks/` to `{CLAUDE_DIR}/hooks/codecontext/`

### Option B: From local codecontext-package directory
Check common locations:
- `./codecontext-package/hooks/`
- `../codecontext-package/hooks/`
- `~/codecontext-package/hooks/`

### Option C: Create minimal hooks inline

If no source found, create the essential hook files directly. The minimal viable hooks are:

#### user_prompt_submit.py
```python
#!/usr/bin/env python3
"""Capture user prompts for later memory extraction."""
import json
import sys
import os
from pathlib import Path
from datetime import datetime

def main():
    # Skip if this is a CodeContext subprocess
    if os.environ.get("CODECONTEXT_SUBPROCESS") == "1":
        return

    # Read event from stdin
    try:
        event = json.load(sys.stdin)
    except:
        return

    cwd = event.get("cwd", os.getcwd())
    prompt = event.get("prompt", "")

    if not prompt or len(prompt) < 20:
        return

    # Encode project path
    encoded = cwd.replace("\\", "-").replace("/", "-").replace(":", "-")

    # Store chunk
    data_dir = Path.home() / ".codecontext" / "projects" / encoded / "chunks"
    data_dir.mkdir(parents=True, exist_ok=True)

    chunk_file = data_dir / f"chunk_{datetime.now().strftime('%Y%m%d_%H%M%S_%f')}.json"
    chunk_file.write_text(json.dumps({
        "prompt": prompt,
        "timestamp": datetime.now().isoformat(),
        "cwd": cwd
    }, indent=2))

if __name__ == "__main__":
    main()
```

#### session_start.py
```python
#!/usr/bin/env python3
"""Inject project context at session start."""
import json
import sys
import os
from pathlib import Path

def main():
    if os.environ.get("CODECONTEXT_SUBPROCESS") == "1":
        return

    try:
        event = json.load(sys.stdin)
    except:
        return

    cwd = event.get("cwd", os.getcwd())
    encoded = cwd.replace("\\", "-").replace("/", "-").replace(":", "-")

    # Look for summary
    summary_file = Path.home() / ".codecontext" / "projects" / encoded / "summary.json"

    if summary_file.exists():
        try:
            summary = json.loads(summary_file.read_text())
            if summary.get("summary"):
                # Output as system reminder
                print(f"<system-reminder>\\nProject Context:\\n{summary['summary'][:2000]}\\n</system-reminder>")
        except:
            pass

if __name__ == "__main__":
    main()
```

#### session_end.py
```python
#!/usr/bin/env python3
"""Trigger memory extraction at session end."""
import os
import sys

def main():
    if os.environ.get("CODECONTEXT_SUBPROCESS") == "1":
        return
    # Memory extraction would be triggered here
    # Full implementation requires the CodeContext server
    pass

if __name__ == "__main__":
    main()
```

#### stop.py
```python
#!/usr/bin/env python3
"""Handle stop events."""
import os
import sys

def main():
    if os.environ.get("CODECONTEXT_SUBPROCESS") == "1":
        return
    pass

if __name__ == "__main__":
    main()
```

---

## Step 7: Create/Update settings.json

### Read existing settings (if any)
```bash
cat {CLAUDE_DIR}/settings.json 2>/dev/null || echo "{}"
```

### Build hook configuration

**For Global Mode** (absolute paths):
```json
{
  "hooks": {
    "UserPromptSubmit": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \"C:/Users/{USERNAME}/.claude/hooks/codecontext/user_prompt_submit.py\""
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \"C:/Users/{USERNAME}/.claude/hooks/codecontext/stop.py\""
      }]
    }],
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \"C:/Users/{USERNAME}/.claude/hooks/codecontext/session_start.py\"",
        "timeout": 300
      }]
    }],
    "SessionEnd": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \"C:/Users/{USERNAME}/.claude/hooks/codecontext/session_end.py\"",
        "timeout": 300
      }]
    }]
  }
}
```

**For Project Mode** (relative paths):
```json
{
  "hooks": {
    "UserPromptSubmit": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \".claude/hooks/codecontext/user_prompt_submit.py\""
      }]
    }],
    "Stop": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \".claude/hooks/codecontext/stop.py\""
      }]
    }],
    "SessionStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \".claude/hooks/codecontext/session_start.py\"",
        "timeout": 300
      }]
    }],
    "SessionEnd": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "python \".claude/hooks/codecontext/session_end.py\"",
        "timeout": 300
      }]
    }]
  }
}
```

### Merge with existing settings

**CRITICAL**: Preserve any existing hooks that are NOT CodeContext hooks.

1. Read existing settings
2. If `hooks` key exists, filter out entries where command contains "codecontext"
3. Add new CodeContext hooks
4. Write merged result

Use the Edit tool to surgically update settings.json, preserving other content.

---

## Step 8: Create Installation Marker

Write to `{DATA_DIR}/.codecontext_mode`:

```json
{
  "mode": "global" | "project",
  "project_path": "{current_directory}" | null,
  "installed_at": "{ISO_TIMESTAMP}",
  "version": "0.1.0",
  "installed_by": "skill"
}
```

---

## Step 9: Copy SKILL.md (Optional)

If the codecontext skill file is available, copy it:
```bash
cp {source}/skills/codecontext/SKILL.md {CLAUDE_DIR}/skills/codecontext/SKILL.md
```

---

## Step 10: Verify Installation

Run verification checks:

```bash
# Check hooks exist
ls {CLAUDE_DIR}/hooks/codecontext/*.py

# Check settings.json is valid JSON
python -c "import json; json.load(open('{CLAUDE_DIR}/settings.json'))"

# Check marker exists
cat {DATA_DIR}/.codecontext_mode
```

---

## Step 11: Report Success

Output a summary:

```
✓ CodeContext Installation Complete!

Mode: {global|project}
Hooks: {CLAUDE_DIR}/hooks/codecontext/
Data:  {DATA_DIR}/
Settings: {CLAUDE_DIR}/settings.json

What's next:
1. Start a new Claude Code session (hooks activate on new sessions)
2. Use 'codecontext query "topic"' to search memories
3. Use 'codecontext summary' to view project summary

For full functionality, also install the Python package:
  pip install codecontext
```

---

## Error Handling

### If settings.json is corrupted
```
Ask: "settings.json appears corrupted. Create a fresh one?"
Options:
  - "Yes, create new" - Backup and create fresh
  - "No, abort" - Cancel installation
```

### If hooks directory has unexpected files
```
Ask: "Found existing files in hooks directory. What should I do?"
Options:
  - "Replace all" - Remove and reinstall
  - "Merge" - Keep existing, add missing
  - "Cancel" - Abort installation
```

### If Python is not available
```
Error: Python is required for CodeContext hooks.
Please install Python 3.10+ and ensure it's in your PATH.
```

---

## Uninstall Instructions

To uninstall, the user can run:
```bash
# Remove hooks
rm -rf {CLAUDE_DIR}/hooks/codecontext

# Remove skills
rm -rf {CLAUDE_DIR}/skills/codecontext

# Remove CodeContext entries from settings.json (manual edit)

# Optionally remove data (DESTRUCTIVE)
rm -rf {DATA_DIR}
```

Or if the Python package is installed:
```bash
codecontext uninstall --global  # or --project
```

---

## Your Task

$ARGUMENTS

Execute the installation process following the steps above. Use AskUserQuestion for any decisions that need user input. Report progress at each major step.
