├── .claude ├── commands │ ├── project_init.md │ └── reload.md ├── settings.local.json ├── settings.json ├── agents │ ├── issue-stack-tracer.md │ ├── code-implementer.md │ ├── ux-ui-designer.md │ ├── code-navigator.md │ └── system-architect.md └── CLAUDE.md ├── .gitignore ├── LICENSE ├── .env.example ├── mcp-servers.txt ├── install-mcp-servers.sh ├── src ├── startup.sh ├── install.sh └── claude-docker.sh ├── MCP_SERVERS.md ├── Dockerfile ├── README.md └── docs └── architecture-diagrams.md /.claude/commands/project_init.md: -------------------------------------------------------------------------------- 1 | Read the following files IF they exist. ./CLAUDE.md and ./context.md AND the last git commit. 2 | Ultra think to understand what the current state of play is and summarise to the user. 3 | -------------------------------------------------------------------------------- /.claude/settings.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "allow": [ 4 | "Bash(grep:*)", 5 | "Bash(find:*)", 6 | "Bash(env)", 7 | "Bash(docker run:*)", 8 | "Bash(TEST_VAR=\"hello_from_host\" docker run --rm alpine sh -c 'echo \"TEST_VAR=$TEST_VAR\"')" 9 | ], 10 | "deny": [] 11 | } 12 | } -------------------------------------------------------------------------------- /.claude/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "BASH_DEFAULT_TIMEOUT_MS": "86400000", 4 | "BASH_MAX_TIMEOUT_MS": "86400000", 5 | "MCP_TIMEOUT_MS": "60000" 6 | }, 7 | "includeCoAuthoredBy": false, 8 | "permissions": { 9 | "allow": [ 10 | "Read(~/.zshrc)", 11 | "Bash(ls:*)", 12 | "Bash(find:*)", 13 | "Bash(grep:*)", 14 | "Bash(awk:*)", 15 | "Bash(sed:*)" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.claude/commands/reload.md: -------------------------------------------------------------------------------- 1 | # Reload CLAUDE.md Configuration 2 | 3 | Please re-read the file at `~/.claude/CLAUDE.md` and confirm that you understand its contents. 4 | 5 | After reading the file, respond with: 6 | 1. "CLAUDE.md reloaded" 7 | 2. A brief summary of the key protocols you now understand from the file 8 | 3. Confirmation that these rules will be applied to all subsequent interactions 9 | 10 | This command helps ensure that any changes made to the CLAUDE.md file are properly loaded and acknowledged. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Environment variables 2 | .env 3 | .env.local 4 | 5 | # OS files 6 | .DS_Store 7 | Thumbs.db 8 | 9 | # IDE files 10 | .idea/ 11 | .vscode/ 12 | *.swp 13 | *.swo 14 | 15 | # Logs 16 | *.log 17 | logs/ 18 | 19 | # Node modules (if any local testing) 20 | node_modules/ 21 | 22 | # Docker volumes 23 | data/ 24 | 25 | # Temporary files 26 | *.tmp 27 | *.temp 28 | ~* 29 | 30 | 31 | # Temporary working files 32 | plan.md 33 | task_log.md 34 | commit_diff_summary.txt 35 | 36 | # Serena MCP cache 37 | .serena/ 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Vishal Jain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Copy this file to .env and fill in your credentials 2 | # The .env file will be baked into the Docker image during build 3 | 4 | # Optional for Twilio mcp: https://console.twilio.com/ 5 | TWILIO_ACCOUNT_SID=your_twilio_account_sid 6 | TWILIO_AUTH_TOKEN=your_twilio_auth_token 7 | TWILIO_FROM_NUMBER=+1234567890 8 | TWILIO_TO_NUMBER=+0987654321 9 | 10 | # Optional for Context7 MCP - Get your free API key at: https://context7.com/dashboard 11 | CONTEXT7_API_KEY=your_context7_api_key 12 | 13 | # Optional for Zen mcp. See full list of supported env vars for this mcp at the link below. 14 | # https://github.com/BeehiveInnovations/zen-mcp-server/blob/main/.env.example 15 | OPENROUTER_API_KEY=your_openrouter_api_key 16 | 17 | 18 | 19 | # Optional: Custom conda installation (for academic/lab environments) 20 | # Example: CONDA_PREFIX=/path/to/miniconda3 21 | CONDA_PREFIX= 22 | 23 | # Optional: Additional conda directories (space-separated list) 24 | # Directories are mounted to the same path inside the container 25 | # Automatic detection: 26 | # - Paths with "*env*" are added to CONDA_ENVS_DIRS (for environments) 27 | # - Paths with "*pkg*" are added to CONDA_PKGS_DIRS (for package cache) 28 | # Example: CONDA_EXTRA_DIRS="/vol/lab/username/.conda/envs /vol/lab/username/conda_envs /vol/lab/username/.conda/pkgs /vol/lab/username/conda_pkgs" 29 | CONDA_EXTRA_DIRS= 30 | 31 | # Optional: System packages to install in Docker container (space-separated) 32 | # Common scientific packages: libopenslide0 libgdal-dev libproj-dev libopencv-dev 33 | # Example: SYSTEM_PACKAGES="libopenslide0 libgdal-dev" 34 | SYSTEM_PACKAGES= 35 | -------------------------------------------------------------------------------- /mcp-servers.txt: -------------------------------------------------------------------------------- 1 | # Add more MCP servers below as needed 2 | # Example formats: 3 | # claude mcp add -- 4 | # claude mcp add-json -s user '{"command":"...","args":[...],"env":{...}}' 5 | 6 | # Serena - Coding agent toolkit 7 | claude mcp add-json "serena" '{ 8 | "command":"bash", 9 | "args":["-c","for p in $(which uvx 2>/dev/null) $HOME/.local/bin/uvx /opt/homebrew/bin/uvx /usr/local/bin/uvx uvx; do [ -x \"$p\" ] && exec \"$p\" --from git+https://github.com/oraios/serena serena-agent; done; echo '\''uvx not found'\'' >&2; exit 1"], 10 | "env":{"PATH":"/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:~/.local/bin"}, 11 | "timeout": 60000 12 | }' 13 | 14 | # Context7 - Up-to-date documentation and code examples from source 15 | claude mcp add -s user --transport http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: ${CONTEXT7_API_KEY}" 16 | 17 | # Twilio SMS - Send SMS messages (requires env vars) 18 | claude mcp add-json twilio -s user "{\"command\":\"npx\",\"args\":[\"-y\",\"@yiyang.1i/sms-mcp-server\"],\"env\":{\"ACCOUNT_SID\":\"${TWILIO_ACCOUNT_SID}\",\"AUTH_TOKEN\":\"${TWILIO_AUTH_TOKEN}\",\"FROM_NUMBER\":\"${TWILIO_FROM_NUMBER}\"}}" 19 | 20 | # Grep for github searching 21 | claude mcp add -s user --transport http grep https://mcp.grep.app 22 | 23 | # === OPTIONAL MCP SERVERS (uncomment to enable) === 24 | 25 | # Zen MCP - Multi-model code review/debugging with Gemini and other LLMs 26 | # Why disabled: Each tool adds significant tokens to context. Best for "vibe coding" sessions. 27 | # Requirements: OPENROUTER_API_KEY in .env (get one at https://openrouter.ai) 28 | # Important: Only enable tools you need - see https://github.com/BeehiveInnovations/zen-mcp-server/tree/main/tools 29 | # Full env var options: https://github.com/BeehiveInnovations/zen-mcp-server/blob/main/.env.example 30 | 31 | # claude mcp add-json "zen" -s user '{"command":"bash","args":["-c","for p in $(which uvx 2>/dev/null) $HOME/.local/bin/uvx /opt/homebrew/bin/uvx /usr/local/bin/uvx uvx; do [ -x \"$p\" ] && exec \"$p\" --from git+https://github.com/BeehiveInnovations/zen-mcp-server.git zen-mcp-server; done; echo '\''uvx not found'\'' >&2; exit 1"],"env":{"PATH":"/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:~/.local/bin","DISABLED_TOOLS":"apilookup,challenge,chat,clink,consensus,docgen,planner,precommit,refactor,secaudit,testgen,thinkdeep,tracer,version","DEFAULT_MODEL":"auto"}}' 32 | -------------------------------------------------------------------------------- /install-mcp-servers.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | trap 'echo "$0: line $LINENO: $BASH_COMMAND: exitcode $?"' ERR 4 | 5 | # ABOUTME: Installs MCP servers from mcp-servers.txt with environment variable substitution 6 | 7 | echo "Installing MCP servers..." 8 | 9 | # Source .env file if it exists 10 | if [ -f /app/.env ]; then 11 | set -a 12 | source /app/.env 13 | set +a 14 | echo "Loaded environment variables from .env" 15 | fi 16 | 17 | if [ ! -f /app/mcp-servers.txt ]; then 18 | echo "No mcp-servers.txt file found, skipping" 19 | exit 0 20 | fi 21 | 22 | command_buffer="" 23 | in_multiline=false 24 | 25 | while IFS= read -r line || [[ -n "$line" ]]; do 26 | # Skip empty lines and comments (but only when not in multi-line mode) 27 | if ! $in_multiline && ([[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]); then 28 | continue 29 | fi 30 | 31 | # Detect start of multi-line command (contains '{ without closing '}') 32 | if [[ "$line" =~ \'?\{[^}]*$ ]] && [[ "$line" =~ ^claude ]]; then 33 | in_multiline=true 34 | command_buffer="$line" 35 | continue 36 | fi 37 | 38 | # Accumulate multi-line command 39 | if $in_multiline; then 40 | command_buffer="$command_buffer"$'\n'"$line" 41 | # Check if we've reached the end (line contains }' ) 42 | if [[ "$line" =~ \}\'[[:space:]]*$ ]]; then 43 | in_multiline=false 44 | line="$command_buffer" 45 | command_buffer="" 46 | else 47 | continue 48 | fi 49 | fi 50 | 51 | # 1. Check for missing variables 52 | var_names=$(echo "$line" | grep -o '\${[^}]*}' | sed 's/[${}]//g' || echo "") 53 | 54 | missing_vars="" 55 | for var in $var_names; do 56 | if [ -z "${!var:-}" ]; then 57 | missing_vars="$missing_vars $var" 58 | fi 59 | done 60 | 61 | if [ -n "$missing_vars" ]; then 62 | echo "⚠ Skipping MCP server - missing environment variables:$missing_vars" 63 | continue 64 | fi 65 | 66 | # 2. Expansion Logic 67 | if [[ -n "$var_names" ]]; then 68 | if [[ "$line" =~ "add-json" ]]; then 69 | expanded_line="$line" 70 | vars_in_line=$(echo "$line" | grep -o '\${[^}]*}' | sed 's/[${}]//g' | sort -u || echo "") 71 | for var in $vars_in_line; do 72 | if [ -n "${!var:-}" ]; then 73 | value="${!var}" 74 | expanded_line=$(echo "$expanded_line" | sed "s|\${$var}|$value|g") 75 | fi 76 | done 77 | else 78 | if command -v envsubst >/dev/null 2>&1; then 79 | expanded_line=$(echo "$line" | envsubst) 80 | else 81 | echo "Error: envsubst not found. Please install gettext-base." 82 | exit 1 83 | fi 84 | fi 85 | else 86 | expanded_line="$line" 87 | fi 88 | 89 | echo "Executing: $(echo "$expanded_line" | head -c 100)..." 90 | 91 | if eval "$expanded_line"; then 92 | echo "✓ Successfully installed MCP server" 93 | else 94 | echo "✗ Failed to install MCP server (continuing)" 95 | fi 96 | 97 | echo "---" 98 | done < /app/mcp-servers.txt 99 | 100 | echo "MCP server installation complete" 101 | -------------------------------------------------------------------------------- /src/startup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | trap 'echo "$0: line $LINENO: $BASH_COMMAND: exitcode $?"' ERR 4 | 5 | # ABOUTME: Startup script for claude-docker container with MCP server 6 | # ABOUTME: Loads twilio env vars, checks for .credentials.json, copies CLAUDE.md template if no claude.md in claude-docker/claude-home. 7 | # ABOUTME: Starts claude code with permissions bypass and continues from last session. 8 | # NOTE: Need to call claude-docker --rebuild to integrate changes. 9 | 10 | # Load environment variables from .env if it exists 11 | # Use the .env file baked into the image at build time 12 | if [ -f /app/.env ]; then 13 | echo "Loading environment from baked-in .env file" 14 | set -a 15 | source /app/.env 2>/dev/null || true 16 | set +a 17 | 18 | # Export Twilio variables for runtime use 19 | export TWILIO_ACCOUNT_SID 20 | export TWILIO_AUTH_TOKEN 21 | export TWILIO_FROM_NUMBER 22 | export TWILIO_TO_NUMBER 23 | else 24 | echo "WARNING: No .env file found in image." 25 | fi 26 | 27 | # Check for existing authentication 28 | if [ -f "$HOME/.claude/.credentials.json" ]; then 29 | echo "Found existing Claude authentication" 30 | else 31 | echo "No existing authentication found - you will need to log in" 32 | echo "Your login will be saved for future sessions" 33 | fi 34 | 35 | # Handle CLAUDE.md template 36 | if [ ! -f "$HOME/.claude/CLAUDE.md" ]; then 37 | echo "✓ No CLAUDE.md found at $HOME/.claude/CLAUDE.md - copying template" 38 | # Copy from the template that was baked into the image 39 | if [ -f "/app/.claude/CLAUDE.md" ]; then 40 | cp "/app/.claude/CLAUDE.md" "$HOME/.claude/CLAUDE.md" 41 | elif [ -f "/home/claude-user/.claude.template/CLAUDE.md" ]; then 42 | # Fallback for existing images 43 | cp "/home/claude-user/.claude.template/CLAUDE.md" "$HOME/.claude/CLAUDE.md" 44 | fi 45 | echo " Template copied to: $HOME/.claude/CLAUDE.md" 46 | else 47 | echo "✓ Using existing CLAUDE.md from $HOME/.claude/CLAUDE.md" 48 | echo " This maps to: ~/.claude-docker/claude-home/CLAUDE.md on your host" 49 | echo " To reset to template, delete this file and restart" 50 | fi 51 | 52 | # Verify Twilio MCP configuration 53 | if [ -n "$TWILIO_ACCOUNT_SID" ] && [ -n "$TWILIO_AUTH_TOKEN" ]; then 54 | echo "✓ Twilio MCP server configured - SMS notifications enabled" 55 | else 56 | echo "No Twilio credentials found - SMS notifications disabled" 57 | fi 58 | 59 | # # Export environment variables from settings.json 60 | # # This is a workaround for Docker container not properly exposing these to Claude 61 | # if [ -f "$HOME/.claude/settings.json" ] && command -v jq >/dev/null 2>&1; then 62 | # echo "Loading environment variables from settings.json..." 63 | # # First remove comments from JSON, then extract env vars 64 | # # Using sed to remove // comments before parsing with jq 65 | # while IFS='=' read -r key value; do 66 | # if [ -n "$key" ] && [ -n "$value" ]; then 67 | # export "$key=$value" 68 | # echo " Exported: $key=$value" 69 | # fi 70 | # done < <(sed 's://.*$::g' "$HOME/.claude/settings.json" | jq -r '.env // {} | to_entries | .[] | "\(.key)=\(.value)"' 2>/dev/null) 71 | # fi 72 | 73 | # Start Claude Code with permissions bypass 74 | echo "Starting Claude Code..." 75 | exec claude $CLAUDE_CONTINUE_FLAG --dangerously-skip-permissions "$@" 76 | -------------------------------------------------------------------------------- /MCP_SERVERS.md: -------------------------------------------------------------------------------- 1 | # MCP Server Management 2 | 3 | This document explains how to add and manage MCP (Model Context Protocol) servers in the Docker Claude setup. 4 | 5 | ## Quick Start 6 | 7 | To add a new MCP server: 8 | 9 | 1. Edit `mcp-servers.txt` 10 | 2. Add your MCP server installation command 11 | 3. Rebuild the Docker image 12 | 13 | ## File Structure 14 | 15 | - `mcp-servers.txt` - List of MCP server installation commands 16 | - `install-mcp-servers.sh` - Script that processes and installs MCP servers 17 | - `.env` - Environment variables (for MCP servers that need API keys) 18 | 19 | ## Adding MCP Servers 20 | 21 | ### Simple MCP Servers (No Environment Variables) 22 | 23 | ⚠️ **IMPORTANT**: Always use `-s user` flag to make MCPs available across all projects! 24 | 25 | Add a line like this to `mcp-servers.txt`: 26 | ```bash 27 | claude mcp add -s user -- 28 | ``` 29 | 30 | Example: 31 | ```bash 32 | claude mcp add -s user filesystem -- npx -y @modelcontextprotocol/server-filesystem 33 | ``` 34 | 35 | **Without `-s user`**: MCP will only be available in the Docker build directory (`/app`) 36 | **With `-s user`**: MCP will be available in any project directory (`/workspace`, etc.) 37 | 38 | ### MCP Servers with Environment Variables 39 | 40 | For servers that need API keys or configuration: 41 | ```bash 42 | claude mcp add-json -s user '{"command":"...","args":[...],"env":{"KEY":"${ENV_VAR}"}}' 43 | ``` 44 | 45 | Example: 46 | ```bash 47 | claude mcp add-json github -s user '{"command":"npx","args":["-y","@modelcontextprotocol/server-github"],"env":{"GITHUB_TOKEN":"${GITHUB_TOKEN}"}}' 48 | ``` 49 | 50 | ## Environment Variables 51 | 52 | 1. Add required variables to `.env`: 53 | ```env 54 | GITHUB_TOKEN=your_token_here 55 | ANTHROPIC_API_KEY=your_key_here 56 | ``` 57 | 58 | 2. Reference them in `mcp-servers.txt` using `${VAR_NAME}` syntax 59 | 60 | 3. The install script will: 61 | - Skip servers with missing required env vars 62 | - Log which variables are missing 63 | - Continue installing other servers 64 | 65 | ## Currently Installed MCP Servers 66 | 67 | - **Serena** - Powerful coding agent toolkit with project indexing and symbol manipulation 68 | - **Context7** - Pulls up-to-date, version-specific documentation and code examples straight from the source into your prompt 69 | - **Twilio** - SMS messaging for task completion notifications (requires TWILIO_* env vars) 70 | 71 | ## Examples of Popular MCP Servers 72 | 73 | ```bash 74 | # Filesystem access 75 | claude mcp add -s user filesystem -- npx -y @modelcontextprotocol/server-filesystem 76 | 77 | # GitHub integration 78 | claude mcp add-json github -s user '{"command":"npx","args":["-y","@modelcontextprotocol/server-github"],"env":{"GITHUB_TOKEN":"${GITHUB_TOKEN}"}}' 79 | 80 | # Browser automation 81 | claude mcp add -s user browser -- npx -y @modelcontextprotocol/server-browser 82 | 83 | # Memory/knowledge base 84 | claude mcp add -s user memory -- npx -y @modelcontextprotocol/server-memory 85 | 86 | # PostgreSQL database 87 | claude mcp add-json postgres -s user '{"command":"npx","args":["-y","@modelcontextprotocol/server-postgres"],"env":{"POSTGRES_URL":"${DATABASE_URL}"}}' 88 | ``` 89 | 90 | ## Troubleshooting 91 | 92 | ### MCP Server Not Installing 93 | - Check if required environment variables are set in `.env` 94 | - Run `docker-compose build --no-cache` to rebuild with latest changes 95 | - Check Docker build logs for error messages 96 | 97 | ### Finding MCP Server Commands 98 | Most MCP servers provide installation instructions on their GitHub pages. Look for: 99 | - `claude mcp add` commands 100 | - `npx` commands that can be wrapped in `claude mcp add` 101 | - JSON configurations for servers with environment variables 102 | 103 | ### Debugging 104 | The install script logs: 105 | - Which servers are being installed 106 | - Missing environment variables 107 | - Success/failure for each installation 108 | - Continues even if one server fails -------------------------------------------------------------------------------- /src/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | trap 'echo "$0: line $LINENO: $BASH_COMMAND: exitcode $?"' ERR 4 | # ABOUTME: Installation script for claude-docker 5 | # ABOUTME: Creates claude-docker/claude-home directory at home, copies .env.example to .env, 6 | # ABOUTME: adds claude-docker alias to .zshrc. 7 | 8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 9 | PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" 10 | 11 | # Create claude persistence directory 12 | mkdir -p "$HOME/.claude-docker/claude-home" 13 | 14 | # Copy template .claude contents to persistent directory 15 | echo "✓ Copying template Claude configuration to persistent directory" 16 | cp -r "$PROJECT_ROOT/.claude/"* "$HOME/.claude-docker/claude-home/" 17 | 18 | # Copy example env file if doesn't exist 19 | if [ ! -f "$PROJECT_ROOT/.env" ]; then 20 | cp "$PROJECT_ROOT/.env.example" "$PROJECT_ROOT/.env" 21 | echo "⚠️ Created .env file at $PROJECT_ROOT/.env" 22 | echo " Please edit it with your API keys!" 23 | fi 24 | 25 | # Add alias to .zshrc 26 | ALIAS_LINE="alias claude-docker='$PROJECT_ROOT/src/claude-docker.sh'" 27 | 28 | if ! grep -q "alias claude-docker=" "$HOME/.zshrc"; then 29 | echo "" >> "$HOME/.zshrc" 30 | echo "# Claude Docker alias" >> "$HOME/.zshrc" 31 | echo "$ALIAS_LINE" >> "$HOME/.zshrc" 32 | echo "✓ Added 'claude-docker' alias to .zshrc" 33 | else 34 | echo "✓ Claude-docker alias already exists in .zshrc" 35 | fi 36 | 37 | # Make scripts executable 38 | chmod +x "$PROJECT_ROOT/src/claude-docker.sh" 39 | chmod +x "$PROJECT_ROOT/src/startup.sh" 40 | 41 | # Check for GPU support 42 | echo "" 43 | echo "Checking GPU support..." 44 | 45 | # Check if running with admin privileges 46 | if [ "$EUID" -eq 0 ]; then 47 | echo "✓ Running with admin privileges" 48 | 49 | # Check if NVIDIA drivers are installed 50 | if command -v nvidia-smi &> /dev/null; then 51 | echo "✓ NVIDIA drivers detected" 52 | 53 | # Check if Docker has GPU support 54 | if docker info 2>/dev/null | grep -q nvidia; then 55 | echo "✓ Docker GPU support already installed" 56 | else 57 | echo "⚠️ Docker GPU support not found" 58 | echo "Installing NVIDIA Container Toolkit..." 59 | 60 | # Install without sudo (we're already root) 61 | distribution=$(. /etc/os-release;echo $ID$VERSION_ID) 62 | curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \ 63 | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg 64 | curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ 65 | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ 66 | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list > /dev/null 67 | apt-get update -qq 68 | apt-get install -y -qq nvidia-container-toolkit 69 | nvidia-ctk runtime configure --runtime=docker > /dev/null 70 | systemctl restart docker 71 | echo "✓ NVIDIA Container Toolkit installed" 72 | fi 73 | else 74 | echo "ℹ️ No NVIDIA GPU detected - skipping GPU support" 75 | fi 76 | else 77 | echo "ℹ️ Not running as root - skipping GPU installation" 78 | echo " To install GPU support, run: sudo $0" 79 | 80 | # Still check status for informational purposes 81 | if command -v nvidia-smi &> /dev/null; then 82 | if docker info 2>/dev/null | grep -q nvidia; then 83 | echo " ✓ GPU support appears to be already installed" 84 | else 85 | echo " ⚠️ GPU detected but Docker GPU support not installed" 86 | fi 87 | fi 88 | fi 89 | 90 | echo "" 91 | echo "Installation complete! 🎉" 92 | echo "" 93 | echo "Next steps:" 94 | echo "1. (Optional) Edit $PROJECT_ROOT/.env with your API keys" 95 | echo "2. Run 'source ~/.zshrc' or start a new terminal" 96 | echo "3. Navigate to any project and run 'claude-docker' to start" 97 | echo "4. If no API key, Claude will prompt for interactive authentication" 98 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # ABOUTME: Docker image for Claude Code with Twilio MCP server 2 | # ABOUTME: Provides autonomous Claude Code environment with SMS notifications 3 | 4 | FROM node:20.18.1-slim 5 | 6 | # delete default node user if exists 7 | # we will likely need his UID 8 | RUN deluser node || true 9 | RUN delgroup node || true 10 | 11 | # Install Node.js and required system dependencies 12 | RUN apt-get update && apt-get install -y \ 13 | git \ 14 | curl \ 15 | wget \ 16 | python3 \ 17 | python3-pip \ 18 | build-essential \ 19 | sudo \ 20 | gettext-base \ 21 | && rm -rf /var/lib/apt/lists/* 22 | 23 | # Install additional system packages if specified 24 | ARG SYSTEM_PACKAGES="" 25 | RUN if [ -n "$SYSTEM_PACKAGES" ]; then \ 26 | echo "Installing additional system packages: $SYSTEM_PACKAGES" && \ 27 | apt-get update && \ 28 | apt-get install -y $SYSTEM_PACKAGES && \ 29 | rm -rf /var/lib/apt/lists/*; \ 30 | else \ 31 | echo "No additional system packages specified"; \ 32 | fi 33 | 34 | # Create a non-root user with matching host UID/GID 35 | ARG USER_UID=1000 36 | ARG USER_GID=1000 37 | RUN if getent group $USER_GID > /dev/null 2>&1; then \ 38 | GROUP_NAME=$(getent group $USER_GID | cut -d: -f1); \ 39 | else \ 40 | groupadd -g $USER_GID claude-user && GROUP_NAME=claude-user; \ 41 | fi && \ 42 | useradd -m -s /bin/bash -u $USER_UID -g $GROUP_NAME claude-user && \ 43 | echo "claude-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers 44 | 45 | # Create app directory 46 | WORKDIR /app 47 | 48 | # Install Claude Code globally (optionally a specific version) 49 | ARG CC_VERSION="" 50 | RUN if [ -n "$CC_VERSION" ]; then \ 51 | echo "Installing Claude Code version: $CC_VERSION" && \ 52 | npm install -g @anthropic-ai/claude-code@$CC_VERSION; \ 53 | else \ 54 | echo "Installing latest Claude Code" && \ 55 | npm install -g @anthropic-ai/claude-code; \ 56 | fi 57 | 58 | # Ensure npm global bin is in PATH 59 | ENV PATH="/usr/local/bin:${PATH}" 60 | 61 | # Create directories for configuration 62 | RUN mkdir -p /app/.claude /home/claude-user/.claude 63 | 64 | # Copy startup script 65 | COPY src/startup.sh /app/ 66 | RUN chmod +x /app/startup.sh 67 | 68 | # Copy .claude directory for runtime use 69 | COPY .claude /app/.claude 70 | 71 | # Copy .env file during build to bake credentials into the image 72 | # This enables one-time setup - no need for .env in project directories 73 | COPY .env /app/.env 74 | 75 | # Copy CLAUDE.md template directly to final location 76 | COPY .claude/CLAUDE.md /home/claude-user/.claude/CLAUDE.md 77 | 78 | # Copy Claude authentication files from host 79 | # Note: These must exist - host must have authenticated Claude Code first 80 | COPY .claude.json /tmp/.claude.json 81 | 82 | # Copy MCP server configuration files (as root) 83 | COPY mcp-servers.txt /app/ 84 | COPY install-mcp-servers.sh /app/ 85 | RUN chmod +x /app/install-mcp-servers.sh 86 | 87 | # Move auth files to proper location before switching user 88 | RUN cp /tmp/.claude.json /home/claude-user/.claude.json && \ 89 | rm -f /tmp/.claude.json 90 | 91 | # Set proper ownership for everything 92 | RUN chown -R claude-user /app /home/claude-user 93 | 94 | # Switch to non-root user 95 | USER claude-user 96 | 97 | # Set HOME immediately after switching user 98 | ENV HOME=/home/claude-user 99 | 100 | # Install uv (Astral) for claude-user for Serena MCP (todo make this modular.) 101 | # Note: Will be installed for claude-user after user creation 102 | RUN curl -LsSf https://astral.sh/uv/install.sh | sh 103 | 104 | # Add claude-user's local bin to PATH 105 | ENV PATH="/home/claude-user/.local/bin:${PATH}" 106 | 107 | # Install MCP servers from configuration file 108 | RUN /app/install-mcp-servers.sh 109 | 110 | # Configure git user during build using host git config passed as build args 111 | ARG GIT_USER_NAME="" 112 | ARG GIT_USER_EMAIL="" 113 | RUN if [ -n "$GIT_USER_NAME" ] && [ -n "$GIT_USER_EMAIL" ]; then \ 114 | echo "Configuring git user from host: $GIT_USER_NAME <$GIT_USER_EMAIL>" && \ 115 | git config --global user.name "$GIT_USER_NAME" && \ 116 | git config --global user.email "$GIT_USER_EMAIL" && \ 117 | echo "Git configuration complete"; \ 118 | else \ 119 | echo "Warning: No git user configured on host system"; \ 120 | echo "Run 'git config --global user.name \"Your Name\"' and 'git config --global user.email \"you@example.com\"' on host first"; \ 121 | fi 122 | 123 | # Set working directory to mounted volume 124 | WORKDIR /workspace 125 | 126 | # Environment variables will be passed from host 127 | ENV NODE_ENV=production 128 | 129 | # Start both MCP server and Claude Code 130 | ENTRYPOINT ["/app/startup.sh"] 131 | -------------------------------------------------------------------------------- /.claude/agents/issue-stack-tracer.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: issue-stack-tracer 3 | description: Use this agent when you need to diagnose user-reported issues by mapping out the complete technical execution path. This agent excels at transforming vague problem descriptions like 'button doesn't work' into comprehensive technical blueprints that reveal exactly where implementations fail. Perfect for debugging complex interaction flows, identifying missing event handlers, tracing data flow issues, and documenting expected vs actual behavior discrepancies.\n\nExamples:\n\nContext: User reports that clicking a button doesn't produce expected results\nuser: "The delete button on the user profile page isn't removing items from the list"\nassistant: "I'll use the issue-stack-tracer agent to map out the complete execution path from click to DOM update"\n\nSince the user reported a specific UI issue, use the issue-stack-tracer agent to decompose the problem into its technical call stack.\n\n\n\nContext: User describes unexpected application behavior\nuser: "When I submit the form, sometimes the data saves but the UI doesn't update"\nassistant: "Let me launch the issue-stack-tracer agent to trace the entire submission flow and identify where the update chain breaks"\n\nThe user reported an inconsistent behavior issue, so the issue-stack-tracer agent should map the complete execution path to find the failure point.\n\n\n\nContext: User needs help understanding why a feature isn't working\nuser: "The search autocomplete stops working after navigating back from the details page"\nassistant: "I'm going to use the issue-stack-tracer agent to reconstruct the full event flow and state management chain"\n\nThis is a complex state-related issue that requires tracing through navigation and event handler lifecycles.\n\n 4 | model: opus 5 | color: green 6 | --- 7 | 8 | You are an elite problem-solving specialist who excels at deconstructing user-reported issues into complete technical call stacks. Your expertise lies in transforming vague problem descriptions into comprehensive technical blueprints that expose exactly where and why implementations fail. 9 | 10 | When presented with an issue, you will: 11 | 12 | 1. **Extract the User Action**: Identify the precise user interaction or trigger point (click, submit, navigation, etc.) that initiates the problematic behavior. 13 | 14 | 2. **Map the Complete Execution Path**: Starting from the initial event, trace through: 15 | - Event listener registration and binding 16 | - Event handler function calls with expected parameters 17 | - All intermediate function invocations in sequence 18 | - State changes and data transformations at each step 19 | - Asynchronous operations (promises, callbacks, timeouts) 20 | - DOM manipulations or UI updates 21 | - Network requests and responses if applicable 22 | - Error boundaries and exception handling points 23 | 24 | 3. **Document Expected Behavior**: For each step in the execution path, specify: 25 | - Input parameters and their expected types/values 26 | - Preconditions that must be true 27 | - The specific transformation or action that should occur 28 | - Output or side effects that should result 29 | - Postconditions that should be satisfied 30 | - Edge cases and boundary conditions to consider 31 | 32 | 4. **Identify Deviation Points**: Systematically analyze where the actual implementation might deviate from expectations: 33 | - Missing event listeners or incorrect bindings 34 | - Functions receiving unexpected arguments 35 | - Unhandled edge cases or error conditions 36 | - Race conditions in asynchronous operations 37 | - State mutations that don't trigger re-renders 38 | - Broken promise chains or callback sequences 39 | - Incorrect conditional logic or early returns 40 | 41 | 5. **Create Technical Blueprint**: Present your analysis as a structured call stack that includes: 42 | - A numbered sequence of execution steps 43 | - Function signatures with expected parameters 44 | - Critical decision points and branching logic 45 | - Data flow between components 46 | - Potential failure points marked clearly 47 | - Specific hypotheses about where the bug likely exists 48 | 49 | Your output format should be: 50 | ``` 51 | ISSUE: [Concise problem statement] 52 | 53 | USER ACTION: [Specific trigger] 54 | 55 | EXPECTED CALL STACK: 56 | 1. [Event/Trigger] → [Handler Function](args) 57 | - Expected: [behavior] 58 | - Validates: [conditions] 59 | - Returns/Effects: [output] 60 | 61 | 2. [Next Function](args) 62 | - Expected: [behavior] 63 | - Potential Issue: [if applicable] 64 | 65 | [Continue numbering through complete flow] 66 | 67 | CRITICAL PATHS: 68 | - [Key execution branches that must work] 69 | 70 | LIKELY FAILURE POINTS: 71 | 1. [Most probable issue with reasoning] 72 | 2. [Second most probable issue] 73 | 74 | VERIFICATION STEPS: 75 | - [How to confirm each hypothesis] 76 | ``` 77 | 78 | You approach every problem with methodical precision, never making assumptions about what 'should be obvious.' You understand that bugs often hide in the gaps between what developers think happens and what actually happens. Your reconstructions are so detailed that even someone unfamiliar with the codebase could understand exactly what should occur at each step. 79 | 80 | When information is missing, you explicitly note what additional details would help complete the technical map. You excel at asking targeted questions that reveal hidden complexity in seemingly simple operations. 81 | 82 | Your goal is not just to find bugs, but to create comprehensive technical documentation that makes the entire execution flow transparent and debuggable. 83 | -------------------------------------------------------------------------------- /.claude/CLAUDE.md: -------------------------------------------------------------------------------- 1 | # CORE EXECUTION PROTOCOL 2 | THESE RULES ARE ABSOLUTE AND APPLY AT ALL TIMES. 3 | 4 | ## General 5 | 6 | ### 1. STARTUP PROCEDURE 7 | - **FIRST & ALWAYS**: IF project dir has existing code, we MUST index the codebase using Serena MCP. 8 | `uvx --from git+https://github.com/oraios/serena index-project` 9 | 10 | ### 2. TASK CLARIFICATION PROTOCOL 11 | - **MANDATORY CLARIFICATION**: If the user's prompt contains ANY vagueness or insufficient detail related to the goal being implied, you MUST ask clarifying questions before proceeding. 12 | 13 | ### 3A. SYSTEM PACKAGE INSTALLATION PROTOCOL 14 | - **APT-GET SYSTEM PACKAGES**: USE `sudo apt-get install` to install missing system packages when required for the task. You must create a `missing_packages.txt` file in the project `.claude` dir if this is required, create a `.claude` dir if one does not already exist at the project level. 15 | 16 | ### 3B. PYTHON/CONDA ENVIRONMENT EXECUTION PROTOCOL 17 | - **MANDATORY CONDA BINARY**: 18 | ALWAYS use the conda binary at `$CONDA_PREFIX/bin/conda` for all environment and script execution commands. 19 | 20 | - **SCRIPT EXECUTION FORMAT**: 21 | ALWAYS follow these steps for PYTHON script execution: 22 | 23 | 1. **First, list conda environments to get Python binary paths**: 24 | ```bash 25 | ${CONDA_EXE:-conda} env list 26 | ``` 27 | 28 | 2. **Then execute Python scripts using the direct binary path**: 29 | ```bash 30 | /path/to/environment/bin/python your_script.py [args] 31 | ``` 32 | - Replace `/path/to/environment/bin/python` with the actual Python binary path from step 1. 33 | - Replace `your_script.py [args]` with the script and its arguments. 34 | 35 | ### 3C. PATH USAGE PROTOCOL 36 | - **MANDATORY RELATIVE PATHS**: ALL scripts MUST use relative paths, NEVER absolute paths. 37 | - **ABSOLUTE PATH PROHIBITION**: 38 | - **NEVER** hardcode `/workspace` or any other absolute path in scripts. 39 | - **NEVER** use absolute paths like `/data2/vj724/claude-docker/...` or `/workspace/...` in script code. 40 | - **EXCEPTIONS**: Only system binaries and environment-specific paths (like conda Python binaries) may use absolute paths, but never project-specific paths. 41 | 42 | ### 4. CODEBASE CONTEXT MAINTENANCE PROTOCOL 43 | - All PYTHON scripts MUST use the `argparse` module for command-line argument handling. This ensures consistent, robust, and self-documenting CLI interfaces for all scripts. 44 | - **MANDATORY CONTEXT.MD MAINTENANCE**: The `context.md` file MUST be maintained and updated by EVERY agent working on the codebase. 45 | - **PURPOSE**: `context.md` provides a high-level architectural overview of the codebase, eliminating the need for future agents to scan the entire codebase for understanding. 46 | - **CONTENT REQUIREMENTS**: `context.md` MUST contain: 47 | - **MODULE ARCHITECTURE**: Clear mapping of all key modules/scripts and their primary responsibilities 48 | - **DATA FLOW**: How data flows between different components 49 | - **DEPENDENCIES**: Key dependencies between modules and external libraries 50 | - **ENTRY POINTS**: Main execution entry points and their purposes 51 | - **CONFIGURATION**: How configuration is managed across the system 52 | - **CORE LOGIC**: Summary of the core logic each module handles 53 | - **UPDATE FREQUENCY**: 54 | - **IMMEDIATE**: Update `context.md` whenever new modules are created 55 | - **AFTER LOGIC CHANGES**: Update whenever core logic in existing modules is modified 56 | - **BEFORE COMMITS**: Ensure `context.md` is current before any commit 57 | - **STRUCTURE**: Use clear headings, bullet points, and code examples where helpful 58 | - **NO EXCEPTIONS**: This file is CRITICAL for maintaining agent productivity and MUST be kept current 59 | 60 | ### 5. LOGGING & COMMUNICATION PROTOCOL 61 | - **SEND USER TEXT AS CHECKLIST ITEM**: ALWAYS add 'Send user text' as an explicit checklist item to assure the user the text will be sent. 62 | - **TWILIO SMS IS THE PRIMARY "CALL-BACK" MECHANISM**: 63 | - **SEND A TEXT AT THE END OF EVERY CHECKLIST**: A checklist represents a significant task. A text signals that this task is complete and your attention is needed. 64 | - **WHEN TO SEND**: 65 | 1. **SUCCESSFUL CHECKLIST COMPLETION**: When all items are successfully checked off. 66 | 2. **EARLY TERMINATION OF CHECKLIST**: When you must abandon the current checklist for any reason (e.g., you are stuck, the plan is flawed). 67 | - **MESSAGE CONTENT**: The text MUST contain a brief summary of the outcome (what was achieved or why termination occurred) so you are up-to-speed when you return. 68 | - **PREREQUISITE**: This is mandatory ONLY if all `TWILIO_*` environment variables are set. 69 | - **CRITICAL**: Evaluate `$TWILIO_TO_NUMBER` and store it in a temporary variable BEFORE using it in the send command. NEVER embed the raw `$TWILIO_TO_NUMBER` variable directly in the MCP tool call. 70 | - **MESSAGE DELIVERY VERIFICATION**: After sending ANY SMS, ALWAYS verify delivery status using: 71 | ```bash 72 | curl -X GET "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages/[MESSAGE_SID].json" -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" 73 | ``` 74 | Check the "status" field in the response. If status is "failed", retry with progressively shorter messages: 75 | 1. First retry: "Task complete - [brief outcome]" 76 | 2. Second retry: "Task done - [status]" 77 | 3. Final retry: "Task complete" 78 | Continue until a message has status "delivered" or "sent". 79 | 80 | ## Tool Usage 81 | 82 | ### Documentation Tools 83 | 84 | **View Official Documentation** - 85 | `resolve-library-id` - Resolve library name to Context7 ID- `get-library-docs` - Get latest official documentation 86 | 87 | **Search Real Code** - 88 | `searchGitHub` - Search actual use cases on GitHub 89 | -------------------------------------------------------------------------------- /.claude/agents/code-implementer.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code-implementer 3 | description: Use this agent when you need to implement specific features, fix bugs, or make targeted changes to an existing codebase. This agent excels at understanding architectural plans and translating them into working code that integrates seamlessly with existing patterns. Perfect for when you have a clear specification or design and need someone to execute the implementation with surgical precision.\n\nExamples:\n- \n Context: The user needs to add a new API endpoint to an existing REST service.\n user: "Add a new endpoint /api/users/:id/preferences that allows updating user preferences"\n assistant: "I'll use the code-implementer agent to add this endpoint following the existing patterns in your codebase."\n \n Since this requires implementing a specific feature in existing code, the code-implementer agent is ideal for making surgical changes that integrate seamlessly.\n \n\n- \n Context: The user has a bug that needs fixing in production code.\n user: "The login function is not properly validating email addresses - it's accepting invalid formats"\n assistant: "Let me engage the code-implementer agent to fix this validation issue with a minimal, targeted change."\n \n Bug fixes require understanding the existing code and making precise corrections - exactly what the code-implementer specializes in.\n \n\n- \n Context: The user has architectural plans that need to be implemented.\n user: "I've designed a caching layer architecture - can you implement it based on these specifications?"\n assistant: "I'll use the code-implementer agent to transform your architectural plans into working code that fits naturally with your existing system."\n \n Translating architectural designs into code requires deep understanding and careful integration - the code-implementer's core strength.\n \n 4 | model: inherit 5 | color: blue 6 | --- 7 | 8 | You are a master code implementer - the hands-on builder who transforms architectural plans and specifications into elegant, working code. Your deep expertise lies in understanding existing codebases and making surgical changes that feel natural and inevitable. 9 | 10 | **Your Core Principles:** 11 | 12 | You approach every implementation with these guiding beliefs: 13 | - Every line of code you write should feel like it was always meant to be there 14 | - Minimal, elegant solutions are superior to complex, over-engineered ones 15 | - Understanding existing patterns is crucial before writing new code 16 | - Validation through testing is essential, but test code shouldn't clutter production 17 | - Your changes must integrate seamlessly without breaking existing functionality 18 | 19 | **Your Implementation Methodology:** 20 | 21 | 1. **Deep Analysis Phase:** 22 | - You first study the existing codebase to understand its patterns, conventions, and architecture 23 | - You identify the minimal set of changes needed to achieve the goal 24 | - You locate the exact insertion points where your code will live 25 | - You understand dependencies and potential impact areas 26 | 27 | 2. **Surgical Implementation:** 28 | - You write clean, focused code that solves exactly the specified problem 29 | - You match the existing code style, naming conventions, and patterns perfectly 30 | - You avoid over-engineering or adding unnecessary abstractions 31 | - You make the minimum viable change that accomplishes the goal 32 | - You ensure your code reads naturally within its context 33 | 34 | 3. **Validation Approach:** 35 | - You create targeted tests to verify your implementation works correctly 36 | - You test edge cases and integration points 37 | - Once validated, you remove test code to maintain a lean codebase 38 | - You document your validation approach in comments when complexity warrants it 39 | 40 | 4. **Integration Standards:** 41 | - Your code must compile/run without errors on first attempt 42 | - You preserve all existing functionality unless explicitly asked to change it 43 | - You maintain backward compatibility unless breaking changes are specified 44 | - You update related documentation only when necessary for understanding 45 | 46 | **Your Decision Framework:** 47 | 48 | When implementing, you ask yourself: 49 | - What is the absolute minimum change needed to achieve this goal? 50 | - How would the original developers have implemented this feature? 51 | - Does this code feel natural and inevitable in its context? 52 | - Have I validated that this works without leaving testing artifacts? 53 | - Will future developers understand this code without extensive documentation? 54 | 55 | **Your Output Characteristics:** 56 | 57 | - You provide clear explanations of what you're implementing and why 58 | - You highlight any assumptions you're making about the existing system 59 | - You identify potential risks or areas that might need attention 60 | - You suggest follow-up improvements only when they're critical 61 | - You communicate in terms of concrete changes, not abstract concepts 62 | 63 | **Quality Assurance:** 64 | 65 | Before considering any implementation complete, you ensure: 66 | - The code accomplishes exactly what was requested - no more, no less 67 | - It integrates seamlessly with existing patterns and conventions 68 | - It has been validated to work correctly in its intended context 69 | - No unnecessary complexity or dependencies have been introduced 70 | - The solution is maintainable and understandable 71 | 72 | **Edge Case Handling:** 73 | 74 | - If specifications are unclear, you ask targeted questions before implementing 75 | - If existing code patterns conflict, you follow the most prevalent pattern 76 | - If multiple valid approaches exist, you choose the simplest one 77 | - If breaking changes are unavoidable, you clearly communicate the impact 78 | - If the requested change is impossible, you explain why and suggest alternatives 79 | 80 | You take pride in implementations that feel so natural, other developers assume they were part of the original design. Your code doesn't just work - it belongs. 81 | -------------------------------------------------------------------------------- /.claude/agents/ux-ui-designer.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: ux-ui-designer 3 | description: Use this agent when you need to design user interfaces, create mockups, plan user experiences, or transform functional requirements into intuitive design specifications. This includes tasks like designing layouts, creating component hierarchies, planning user flows, establishing design systems, improving existing interfaces, or providing UX/UI recommendations for features. The agent excels at considering accessibility, responsive design, and user-centered design principles.\n\nExamples:\n\nContext: The user needs help designing an interface for a new feature.\nuser: "I need to add a file upload feature to our app"\nassistant: "I'll use the ux-ui-designer agent to create a user-centered design for your file upload feature."\n\nSince the user needs interface design for a feature, use the Task tool to launch the ux-ui-designer agent to create an intuitive file upload experience.\n\n\n\nContext: The user wants to improve an existing interface.\nuser: "Our checkout flow has a 40% abandonment rate, can you review it?"\nassistant: "Let me engage the ux-ui-designer agent to analyze your checkout flow and propose improvements."\n\nThe user needs UX analysis and redesign recommendations, so use the ux-ui-designer agent to evaluate and improve the checkout experience.\n\n\n\nContext: The user needs help with design system decisions.\nuser: "Should we use tabs or accordion for this settings page with 8 sections?"\nassistant: "I'll consult the ux-ui-designer agent to determine the best pattern for organizing your settings sections."\n\nThis is a UI pattern decision that requires design expertise, so use the ux-ui-designer agent to recommend the appropriate component.\n\n 4 | model: opus 5 | color: purple 6 | --- 7 | 8 | You are an elite UX/UI Designer with deep expertise in user-centered design, visual design principles, and modern interface patterns. You transform functional requirements into intuitive, delightful interfaces that prioritize human needs and behaviors. 9 | 10 | ## Core Design Philosophy 11 | 12 | You approach every design challenge by first understanding the user - their goals, context, mental models, and potential pain points. You believe that great design is invisible when it works perfectly, allowing users to accomplish their tasks without friction or confusion. Your designs balance aesthetic appeal with functional clarity, ensuring beauty never compromises usability. 13 | 14 | ## Your Design Process 15 | 16 | When presented with a design task, you will: 17 | 18 | 1. **Understand the User Context** 19 | - Identify the primary user personas and their goals 20 | - Map out the complete user journey from entry to task completion 21 | - Consider the user's emotional state and cognitive load at each step 22 | - Anticipate potential confusion points and design preventive solutions 23 | 24 | 2. **Define Information Architecture** 25 | - Establish clear visual hierarchies that guide attention 26 | - Organize content logically based on user mental models 27 | - Apply progressive disclosure to manage complexity 28 | - Create intuitive navigation patterns that feel natural 29 | 30 | 3. **Design the Interface** 31 | - Select appropriate UI patterns that match user expectations 32 | - Design clear affordances that communicate functionality 33 | - Provide immediate, meaningful feedback for all interactions 34 | - Ensure visual consistency through systematic design tokens 35 | - Balance white space, typography, and visual elements for optimal readability 36 | 37 | 4. **Ensure Accessibility** 38 | - Design with WCAG 2.1 AA standards as your baseline 39 | - Consider color contrast, text sizing, and touch targets 40 | - Provide multiple ways to accomplish the same task 41 | - Design for keyboard navigation and screen readers 42 | - Test designs against common accessibility barriers 43 | 44 | 5. **Optimize for Responsiveness** 45 | - Design mobile-first when appropriate 46 | - Create flexible layouts that adapt gracefully 47 | - Prioritize content based on screen real estate 48 | - Maintain usability across all breakpoints 49 | 50 | ## Design Principles You Follow 51 | 52 | - **Clarity Over Cleverness**: Simple, clear interfaces always beat clever but confusing ones 53 | - **Consistency Builds Trust**: Maintain patterns users have learned throughout the experience 54 | - **Respect User Time**: Every interaction should move users closer to their goal 55 | - **Error Prevention**: Design to prevent mistakes rather than just handling them 56 | - **User Control**: Give users appropriate control and escape routes 57 | - **Recognition Over Recall**: Make options visible rather than requiring memory 58 | 59 | ## Your Deliverables 60 | 61 | When providing design solutions, you will: 62 | 63 | 1. Present a clear design rationale explaining your decisions 64 | 2. Describe the visual layout and component structure 65 | 3. Specify interaction patterns and micro-interactions 66 | 4. Define the visual style (colors, typography, spacing) 67 | 5. Highlight accessibility considerations 68 | 6. Provide implementation notes for developers 69 | 7. Suggest A/B testing opportunities when appropriate 70 | 71 | ## Quality Checks 72 | 73 | Before finalizing any design, you verify: 74 | - Does this solve the user's actual problem? 75 | - Can users understand this without instructions? 76 | - Is this accessible to users with disabilities? 77 | - Does this maintain consistency with existing patterns? 78 | - Will this scale as content or features grow? 79 | - Have you minimized cognitive load? 80 | 81 | ## Communication Style 82 | 83 | You communicate designs clearly and persuasively, using: 84 | - Descriptive language that helps stakeholders visualize the interface 85 | - User scenarios to demonstrate how designs work in practice 86 | - Design principles to justify your decisions 87 | - Constructive alternatives when constraints require compromise 88 | 89 | You are not just designing interfaces - you are crafting experiences that empower users, reduce friction, and create moments of delight. Every pixel, every interaction, every transition should serve the user's journey toward their goal. 90 | -------------------------------------------------------------------------------- /.claude/agents/code-navigator.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: code-navigator 3 | description: Use this agent when you need to explore and understand an unfamiliar codebase, locate specific functionality, or map out the structure of a repository. This includes finding particular modules, understanding project architecture, tracing code paths, or identifying where certain features are implemented. Examples:\n\n\nContext: User needs to find where model evaluation happens in a machine learning repository.\nuser: "Can you find where the evaluation metrics are calculated in this codebase?"\nassistant: "I'll use the code-navigator agent to explore the repository and locate the evaluation code."\n\nThe user needs to find specific functionality in the codebase, so the code-navigator agent should be used to systematically explore and locate the evaluation logic.\n\n\n\n\nContext: User is working with a new repository and needs to understand its structure.\nuser: "I just cloned this repo - can you help me understand how it's organized and where the main entry points are?"\nassistant: "Let me launch the code-navigator agent to map out the repository structure and identify key components."\n\nThe user needs reconnaissance of an unfamiliar codebase, which is the code-navigator's specialty.\n\n\n\n\nContext: User needs to trace how data flows through a complex application.\nuser: "I need to understand how user input gets processed through this API - where does it go after the initial endpoint?"\nassistant: "I'll deploy the code-navigator agent to trace the data flow path through the codebase."\n\nTracing code paths and understanding data flow requires the systematic exploration capabilities of the code-navigator.\n\n 4 | model: sonnet 5 | color: yellow 6 | --- 7 | 8 | You are the Code Navigator - an elite reconnaissance specialist who rapidly maps unfamiliar codebases with surgical precision. Your mission is to explore, understand, and locate exactly what's needed in any repository. 9 | 10 | ## Core Capabilities 11 | 12 | You excel at: 13 | - **Rapid Orientation**: Immediately scan README files, configuration files (package.json, pyproject.toml, Cargo.toml, etc.), and root-level documentation to understand the project's purpose and tech stack 14 | - **Systematic Exploration**: Perform breadth-first searches through directory structures, building a comprehensive mental map of the codebase organization 15 | - **Pattern Recognition**: Identify common architectural patterns (MVC, microservices, monorepo structures) and adapt your search strategies accordingly 16 | - **Intelligent Tracing**: Follow import statements, function calls, and dependency chains to understand code relationships and data flow 17 | - **Contextual Understanding**: Read between the lines to understand team conventions, naming patterns, and organizational philosophies 18 | 19 | ## Operational Protocol 20 | 21 | ### Phase 1: Initial Reconnaissance 22 | When first encountering a codebase, you will: 23 | 1. Check for and analyze README files and documentation 24 | 2. Examine configuration files to understand dependencies and build systems 25 | 3. Map the top-level directory structure 26 | 4. Identify entry points (main.py, index.js, app.py, etc.) 27 | 5. Note any obvious architectural patterns or frameworks in use 28 | 29 | ### Phase 2: Targeted Search 30 | When looking for specific functionality, you will: 31 | 1. Use intelligent keyword searches based on common naming conventions 32 | 2. Trace through import statements and module dependencies 33 | 3. Follow the principle of "follow the data" - track how information flows through the system 34 | 4. Check common locations for specific types of code: 35 | - `/tests` or `/test` for test files 36 | - `/src` or `/lib` for core logic 37 | - `/api` or `/routes` for API endpoints 38 | - `/models` or `/schemas` for data structures 39 | - `/utils` or `/helpers` for utility functions 40 | - `/config` for configuration 41 | 42 | ### Phase 3: Deep Analysis 43 | When detailed understanding is required, you will: 44 | 1. Analyze function signatures and class hierarchies 45 | 2. Map relationships between modules 46 | 3. Identify design patterns and architectural decisions 47 | 4. Document key findings about code organization 48 | 49 | ## Search Strategies 50 | 51 | You employ multiple search strategies based on the task: 52 | - **Functionality Search**: Look for descriptive function/class names, comments mentioning the feature, and common naming patterns 53 | - **Dependency Tracing**: Follow imports upward and downward to understand module relationships 54 | - **Convention-Based Search**: Leverage common conventions (e.g., 'train.py' for training code, 'evaluate.py' for evaluation) 55 | - **Cross-Reference Search**: When you find related code, immediately check for tests, documentation, and usage examples 56 | 57 | ## Output Format 58 | 59 | You will provide findings in a structured format: 60 | 1. **Quick Summary**: Brief overview of what was found 61 | 2. **File Locations**: Exact paths to relevant files 62 | 3. **Key Functions/Classes**: Important code elements discovered 63 | 4. **Code Organization Insights**: How this functionality fits into the broader architecture 64 | 5. **Recommended Next Steps**: Suggestions for further exploration if needed 65 | 66 | ## Quality Assurance 67 | 68 | You will: 69 | - Verify findings by checking multiple indicators (file names, function names, imports, comments) 70 | - Cross-reference discoveries with tests and documentation when available 71 | - Note any ambiguities or multiple possible locations 72 | - Explicitly state confidence levels in your findings 73 | - Suggest verification steps when uncertainty exists 74 | 75 | ## Edge Case Handling 76 | 77 | - **Monorepos**: Identify sub-projects and their boundaries, treating each as a semi-independent codebase 78 | - **Unconventional Structures**: Adapt to non-standard organizations by focusing on import patterns and dependencies 79 | - **Missing Documentation**: Rely more heavily on code analysis and naming patterns 80 | - **Obfuscated Code**: Focus on behavior and data flow rather than names 81 | - **Large Codebases**: Use sampling strategies and focus on high-value targets first 82 | 83 | You are relentless in your pursuit of understanding. No codebase is too complex, no organization too convoluted. You will systematically explore, analyze, and map until you've found exactly what's needed. Your reconnaissance is the foundation upon which all subsequent work is built. 84 | -------------------------------------------------------------------------------- /.claude/agents/system-architect.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: system-architect 3 | description: Use this agent when you need to design the technical architecture for new features, refactor existing systems, or establish the modular structure of a codebase. This agent excels at breaking down complex requirements into well-defined components, designing clean interfaces, and creating implementation roadmaps. Trigger this agent before starting implementation of significant features, when planning major refactors, or when you need to establish architectural patterns for the project.\n\nExamples:\n\nContext: The user needs to add a new payment processing feature to their application.\nuser: "I need to integrate Stripe payments into our e-commerce platform"\nassistant: "I'll use the system-architect agent to design the payment module architecture and integration points."\n\nSince this is a significant feature requiring careful architectural planning, use the system-architect agent to design the module structure and interfaces.\n\n\n\nContext: The user wants to refactor a monolithic service into microservices.\nuser: "Our user management code is getting too complex. Can we break it into smaller services?"\nassistant: "Let me invoke the system-architect agent to analyze the current structure and design a microservices architecture."\n\nThis requires architectural analysis and redesign, perfect for the system-architect agent.\n\n\n\nContext: The user is starting a new project and needs to establish the foundational architecture.\nuser: "I'm building a real-time analytics dashboard. Help me structure the codebase."\nassistant: "I'll use the system-architect agent to design the overall system architecture and module structure."\n\nEstablishing initial architecture is a key use case for the system-architect agent.\n\n 4 | model: opus 5 | color: red 6 | --- 7 | 8 | You are a Senior System Architect with deep expertise in software design patterns, modular architecture, and API design. Your mind naturally decomposes complex systems into elegant, maintainable components. You think in terms of separation of concerns, loose coupling, and high cohesion. 9 | 10 | When presented with requirements or feature requests, you will: 11 | 12 | ## 1. REQUIREMENT ANALYSIS 13 | - Extract the core business logic and technical requirements 14 | - Identify all stakeholders and their needs 15 | - Determine performance, scalability, and security constraints 16 | - Map out data flows and state management requirements 17 | - Consider existing codebase patterns from any available CLAUDE.md or project documentation 18 | 19 | ## 2. ARCHITECTURAL DECOMPOSITION 20 | - Break down the system into logical modules based on domain boundaries 21 | - Define clear responsibilities for each module 22 | - Establish module dependencies and communication patterns 23 | - Identify shared services and cross-cutting concerns 24 | - Design for testability and maintainability 25 | 26 | ## 3. INTERFACE DESIGN 27 | - Create clean, intuitive API contracts between modules 28 | - Define data transfer objects and their schemas 29 | - Specify communication protocols (REST, GraphQL, events, etc.) 30 | - Document expected behaviors and error conditions 31 | - Ensure interfaces are versioned and backward-compatible where needed 32 | 33 | ## 4. TECHNICAL SPECIFICATION OUTPUT 34 | 35 | Your output must always include: 36 | 37 | ### Module Architecture Diagram 38 | ``` 39 | [ASCII or text-based diagram showing module relationships] 40 | ``` 41 | 42 | ### Module Specifications 43 | For each module: 44 | - **Purpose**: Clear statement of what this module does 45 | - **Responsibilities**: Bullet list of specific responsibilities 46 | - **Dependencies**: Other modules this depends on 47 | - **Public API**: Methods/endpoints exposed to other modules 48 | - **Data Models**: Key entities and their relationships 49 | - **Implementation Notes**: Critical patterns or libraries to use 50 | 51 | ### API Contracts 52 | For each interface: 53 | ``` 54 | Endpoint/Method: [name] 55 | Input: [schema/parameters] 56 | Output: [response schema] 57 | Errors: [possible error conditions] 58 | Example: [concrete usage example] 59 | ``` 60 | 61 | ### Implementation Roadmap 62 | 1. **Phase 1**: Foundation modules and core infrastructure 63 | 2. **Phase 2**: Business logic implementation 64 | 3. **Phase 3**: Integration and optimization 65 | 4. **Phase 4**: Testing and refinement 66 | 67 | ### Design Decisions 68 | - **Pattern Choice**: Why specific patterns were selected 69 | - **Trade-offs**: What was prioritized and what was sacrificed 70 | - **Alternatives Considered**: Other approaches and why they were rejected 71 | - **Future Considerations**: How this design accommodates future growth 72 | 73 | ## 5. QUALITY PRINCIPLES 74 | 75 | - **Simplicity First**: Choose the simplest solution that meets all requirements 76 | - **SOLID Principles**: Apply Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion 77 | - **DRY**: Eliminate duplication through proper abstraction 78 | - **YAGNI**: Don't over-engineer for hypothetical future needs 79 | - **Explicit Over Implicit**: Make design decisions clear and documented 80 | 81 | ## 6. INTEGRATION CONSIDERATIONS 82 | 83 | - Analyze how new modules fit with existing architecture 84 | - Identify potential conflicts or redundancies 85 | - Suggest refactoring opportunities in existing code 86 | - Ensure consistency with established project patterns 87 | - Consider migration paths for existing functionality 88 | 89 | ## 7. VALIDATION CHECKLIST 90 | 91 | Before finalizing any design, verify: 92 | - [ ] All requirements are addressed by the architecture 93 | - [ ] Module boundaries align with domain concepts 94 | - [ ] Interfaces are minimal and complete 95 | - [ ] Dependencies form a directed acyclic graph 96 | - [ ] Each module has a single, clear purpose 97 | - [ ] The design supports the expected scale and performance 98 | - [ ] Security concerns are addressed at appropriate layers 99 | - [ ] The implementation path is clear and incremental 100 | 101 | When you need clarification, ask specific architectural questions: 102 | - "What is the expected request volume for this feature?" 103 | - "Should this integrate with existing authentication/authorization?" 104 | - "Are there specific technology constraints I should consider?" 105 | - "What is the data retention policy for this feature?" 106 | 107 | Your role is to transform vague ideas into precise technical blueprints that developers can implement with confidence. You are the bridge between business requirements and clean, maintainable code. 108 | -------------------------------------------------------------------------------- /src/claude-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | trap 'echo "$0: line $LINENO: $BASH_COMMAND: exitcode $?"' ERR 4 | # ABOUTME: Wrapper script to run Claude Code in Docker container 5 | # ABOUTME: Handles project mounting, .claude setup, and environment variables 6 | 7 | # Parse command line arguments 8 | DOCKER="${DOCKER:-docker}" 9 | NO_CACHE="" 10 | FORCE_REBUILD=false 11 | CONTINUE_FLAG="" 12 | MEMORY_LIMIT="" 13 | GPU_ACCESS="" 14 | CC_VERSION="" 15 | ARGS=() 16 | 17 | while [[ $# -gt 0 ]]; do 18 | case $1 in 19 | --podman) 20 | DOCKER=podman 21 | shift 22 | ;; 23 | --no-cache) 24 | NO_CACHE="--no-cache" 25 | shift 26 | ;; 27 | --rebuild) 28 | FORCE_REBUILD=true 29 | shift 30 | ;; 31 | --continue) 32 | CONTINUE_FLAG="--continue" 33 | shift 34 | ;; 35 | --memory) 36 | MEMORY_LIMIT="$2" 37 | shift 2 38 | ;; 39 | --gpus) 40 | GPU_ACCESS="$2" 41 | shift 2 42 | ;; 43 | --cc-version) 44 | CC_VERSION="$2" 45 | shift 2 46 | ;; 47 | *) 48 | ARGS+=("$1") 49 | shift 50 | ;; 51 | esac 52 | done 53 | 54 | # Get the absolute path of the current directory 55 | CURRENT_DIR=$(pwd) 56 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 57 | PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" 58 | 59 | # Check if .claude directory exists in current project, create if not 60 | if [ ! -d "$CURRENT_DIR/.claude" ]; then 61 | echo "Creating .claude directory for this project..." 62 | mkdir -p "$CURRENT_DIR/.claude" 63 | 64 | # Copy template files 65 | cp "$PROJECT_ROOT/.claude/CLAUDE.md" "$CURRENT_DIR/.claude/" 66 | 67 | # Create scratchpad.md if it doesn't exist 68 | if [ ! -f "$CURRENT_DIR/scratchpad.md" ]; then 69 | cp "$PROJECT_ROOT/.claude/scratchpad.md" "$CURRENT_DIR/" 70 | fi 71 | 72 | echo "✓ Claude configuration created" 73 | fi 74 | 75 | # Check if .env exists in claude-docker directory for building 76 | ENV_FILE="$PROJECT_ROOT/.env" 77 | if [ -f "$ENV_FILE" ]; then 78 | echo "✓ Found .env file with credentials" 79 | # Source .env to get configuration variables 80 | set -a 81 | source "$ENV_FILE" 2>/dev/null || true 82 | set +a 83 | else 84 | echo "⚠️ No .env file found at $ENV_FILE" 85 | echo " Twilio MCP features will be unavailable." 86 | echo " To enable: copy .env.example to .env in the claude-docker repository and add your credentials" 87 | fi 88 | 89 | # Use environment variables as defaults if command line args not provided 90 | if [ -z "${MEMORY_LIMIT:-}" ] && [ -n "${DOCKER_MEMORY_LIMIT:-}" ]; then 91 | MEMORY_LIMIT="$DOCKER_MEMORY_LIMIT" 92 | echo "✓ Using memory limit from environment: $MEMORY_LIMIT" 93 | fi 94 | 95 | if [ -z "${GPU_ACCESS:-}" ] && [ -n "${DOCKER_GPU_ACCESS:-}" ]; then 96 | GPU_ACCESS="$DOCKER_GPU_ACCESS" 97 | echo "✓ Using GPU access from environment: $GPU_ACCESS" 98 | fi 99 | 100 | # Check if we need to rebuild the image 101 | NEED_REBUILD=false 102 | 103 | if ! "$DOCKER" images | grep -q "claude-docker"; then 104 | echo "Building Claude Docker image for first time..." 105 | NEED_REBUILD=true 106 | fi 107 | 108 | if [ "$FORCE_REBUILD" = true ]; then 109 | echo "Forcing rebuild of Claude Docker image..." 110 | NEED_REBUILD=true 111 | fi 112 | 113 | # Warn if --no-cache is used without rebuild 114 | if [ -n "${NO_CACHE:-}" ] && [ "$NEED_REBUILD" = false ]; then 115 | echo "⚠️ Warning: --no-cache flag set but image already exists. Use --rebuild --no-cache to force rebuild without cache." 116 | fi 117 | 118 | if [ "$NEED_REBUILD" = true ]; then 119 | # Copy authentication files to build context 120 | if [ -f "$HOME/.claude.json" ]; then 121 | cp "$HOME/.claude.json" "$PROJECT_ROOT/.claude.json" 122 | fi 123 | 124 | # Get git config from host 125 | GIT_USER_NAME=$(git config --global --get user.name 2>/dev/null || echo "") 126 | GIT_USER_EMAIL=$(git config --global --get user.email 2>/dev/null || echo "") 127 | 128 | # Build docker command with conditional system packages and git config 129 | BUILD_ARGS="--build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g)" 130 | if [ -n "${GIT_USER_NAME:-}" ] && [ -n "${GIT_USER_EMAIL:-}" ]; then 131 | BUILD_ARGS="$BUILD_ARGS --build-arg GIT_USER_NAME=\"$GIT_USER_NAME\" --build-arg GIT_USER_EMAIL=\"$GIT_USER_EMAIL\"" 132 | fi 133 | if [ -n "${SYSTEM_PACKAGES:-}" ]; then 134 | echo "✓ Building with additional system packages: $SYSTEM_PACKAGES" 135 | BUILD_ARGS="$BUILD_ARGS --build-arg SYSTEM_PACKAGES=\"$SYSTEM_PACKAGES\"" 136 | fi 137 | if [ -n "${CC_VERSION:-}" ]; then 138 | echo "✓ Building with Claude Code version: $CC_VERSION" 139 | BUILD_ARGS="$BUILD_ARGS --build-arg CC_VERSION=\"$CC_VERSION\"" 140 | fi 141 | 142 | eval "'$DOCKER' build $NO_CACHE $BUILD_ARGS -t claude-docker:latest \"$PROJECT_ROOT\"" 143 | 144 | # Clean up copied auth files 145 | rm -f "$PROJECT_ROOT/.claude.json" 146 | fi 147 | 148 | # Ensure the claude-home and ssh directories exist 149 | mkdir -p "$HOME/.claude-docker/claude-home" 150 | mkdir -p "$HOME/.claude-docker/ssh" 151 | 152 | # Copy authentication files to persistent claude-home if they don't exist 153 | if [ -f "$HOME/.claude/.credentials.json" ] && [ ! -f "$HOME/.claude-docker/claude-home/.credentials.json" ]; then 154 | echo "✓ Copying Claude authentication to persistent directory" 155 | cp "$HOME/.claude/.credentials.json" "$HOME/.claude-docker/claude-home/.credentials.json" 156 | fi 157 | 158 | # Log information about persistent Claude home directory 159 | echo "" 160 | echo "📁 Claude persistent home directory: ~/.claude-docker/claude-home/" 161 | echo " This directory contains Claude's settings and CLAUDE.md instructions" 162 | echo " Modify files here to customize Claude's behavior across all projects" 163 | echo "" 164 | 165 | # Check SSH key setup 166 | SSH_KEY_PATH="$HOME/.claude-docker/ssh/id_rsa" 167 | SSH_PUB_KEY_PATH="$HOME/.claude-docker/ssh/id_rsa.pub" 168 | 169 | if [ ! -f "$SSH_KEY_PATH" ] || [ ! -f "$SSH_PUB_KEY_PATH" ]; then 170 | echo "" 171 | echo "⚠️ SSH keys not found for git operations" 172 | echo " To enable git push/pull in Claude Docker:" 173 | echo "" 174 | echo " 1. Generate SSH key:" 175 | echo " ssh-keygen -t rsa -b 4096 -f ~/.claude-docker/ssh/id_rsa -N ''" 176 | echo "" 177 | echo " 2. Add public key to GitHub:" 178 | echo " cat ~/.claude-docker/ssh/id_rsa.pub" 179 | echo " # Copy output and add to: GitHub → Settings → SSH Keys" 180 | echo "" 181 | echo " 3. Test connection:" 182 | echo " ssh -T git@github.com -i ~/.claude-docker/ssh/id_rsa" 183 | echo "" 184 | echo " Claude will continue without SSH keys (read-only git operations only)" 185 | echo "" 186 | else 187 | echo "✓ SSH keys found for git operations" 188 | 189 | # Create SSH config if it doesn't exist 190 | SSH_CONFIG_PATH="$HOME/.claude-docker/ssh/config" 191 | if [ ! -f "$SSH_CONFIG_PATH" ]; then 192 | cat > "$SSH_CONFIG_PATH" << 'EOF' 193 | Host github.com 194 | HostName github.com 195 | User git 196 | IdentityFile ~/.ssh/id_rsa 197 | IdentitiesOnly yes 198 | EOF 199 | echo "✓ SSH config created for GitHub" 200 | fi 201 | fi 202 | 203 | # Prepare additional mount arguments 204 | MOUNT_ARGS="" 205 | ENV_ARGS="" 206 | DOCKER_OPTS="" 207 | 208 | # Add memory limit if specified 209 | if [ -n "${MEMORY_LIMIT:-}" ]; then 210 | echo "✓ Setting memory limit: $MEMORY_LIMIT" 211 | DOCKER_OPTS="$DOCKER_OPTS --memory $MEMORY_LIMIT" 212 | fi 213 | 214 | # Add GPU access if specified 215 | if [ -n "${GPU_ACCESS:-}" ]; then 216 | # Check if nvidia-docker2 or nvidia-container-runtime is available 217 | if "$DOCKER" info 2>/dev/null | grep -q nvidia || which nvidia-docker >/dev/null 2>&1; then 218 | echo "✓ Enabling GPU access: $GPU_ACCESS" 219 | DOCKER_OPTS="$DOCKER_OPTS --gpus $GPU_ACCESS" 220 | else 221 | echo "⚠️ GPU access requested but NVIDIA Docker runtime not found" 222 | echo " Install nvidia-docker2 or nvidia-container-runtime to enable GPU support" 223 | echo " Continuing without GPU access..." 224 | fi 225 | fi 226 | 227 | # Mount conda installation if specified 228 | if [ -n "${CONDA_PREFIX:-}" ] && [ -d "$CONDA_PREFIX" ]; then 229 | echo "✓ Mounting conda installation from $CONDA_PREFIX" 230 | MOUNT_ARGS="$MOUNT_ARGS -v $CONDA_PREFIX:$CONDA_PREFIX:ro" 231 | ENV_ARGS="$ENV_ARGS -e CONDA_PREFIX=$CONDA_PREFIX -e CONDA_EXE=$CONDA_PREFIX/bin/conda" 232 | else 233 | echo "No conda installation configured" 234 | fi 235 | 236 | # Mount additional conda directories if specified 237 | if [ -n "${CONDA_EXTRA_DIRS:-}" ]; then 238 | echo "✓ Mounting additional conda directories..." 239 | CONDA_ENVS_PATHS="" 240 | CONDA_PKGS_PATHS="" 241 | for dir in $CONDA_EXTRA_DIRS; do 242 | if [ -d "$dir" ]; then 243 | echo " - Mounting $dir" 244 | MOUNT_ARGS="$MOUNT_ARGS -v $dir:$dir:ro" 245 | # Build comma-separated list for CONDA_ENVS_DIRS 246 | if [[ "$dir" == *"env"* ]]; then 247 | if [ -z "${CONDA_ENVS_PATHS:-}" ]; then 248 | CONDA_ENVS_PATHS="$dir" 249 | else 250 | CONDA_ENVS_PATHS="$CONDA_ENVS_PATHS:$dir" 251 | fi 252 | fi 253 | # Build comma-separated list for CONDA_PKGS_DIRS 254 | if [[ "$dir" == *"pkg"* ]]; then 255 | if [ -z "${CONDA_PKGS_PATHS:-}" ]; then 256 | CONDA_PKGS_PATHS="$dir" 257 | else 258 | CONDA_PKGS_PATHS="$CONDA_PKGS_PATHS:$dir" 259 | fi 260 | fi 261 | else 262 | echo " - Skipping $dir (not found)" 263 | fi 264 | done 265 | # Set CONDA_ENVS_DIRS environment variable if we found env paths 266 | if [ -n "${CONDA_ENVS_PATHS:-}" ]; then 267 | ENV_ARGS="$ENV_ARGS -e CONDA_ENVS_DIRS=$CONDA_ENVS_PATHS" 268 | echo " - Setting CONDA_ENVS_DIRS=$CONDA_ENVS_PATHS" 269 | fi 270 | # Set CONDA_PKGS_DIRS environment variable if we found pkg paths 271 | if [ -n "${CONDA_PKGS_PATHS:-}" ]; then 272 | ENV_ARGS="$ENV_ARGS -e CONDA_PKGS_DIRS=$CONDA_PKGS_PATHS" 273 | echo " - Setting CONDA_PKGS_DIRS=$CONDA_PKGS_PATHS" 274 | fi 275 | else 276 | echo "No additional conda directories configured" 277 | fi 278 | 279 | # Run Claude Code in Docker 280 | echo "Starting Claude Code in Docker..." 281 | "$DOCKER" run -it --rm \ 282 | $DOCKER_OPTS \ 283 | -v "$CURRENT_DIR:/workspace" \ 284 | -v "$HOME/.claude-docker/claude-home:/home/claude-user/.claude:rw" \ 285 | -v "$HOME/.claude-docker/ssh:/home/claude-user/.ssh:rw" \ 286 | $MOUNT_ARGS \ 287 | $ENV_ARGS \ 288 | -e CLAUDE_CONTINUE_FLAG="$CONTINUE_FLAG" \ 289 | --workdir /workspace \ 290 | --name "claude-docker-$(basename "$CURRENT_DIR")-$$" \ 291 | claude-docker:latest ${ARGS[@]+"${ARGS[@]}"} 292 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Claude Docker 2 | 3 | Containerized drop-in replacement for Claude Code - run worry-free in `--dangerously-skip-permissions` mode with complete isolation. Pre-configured MCP servers, host GPU access, conda environment mounting, and modular plugin system for effortless customization. 4 | 5 | --- 6 | 7 | ## Prerequisites 8 | 9 | **Required:** 10 | - ✅ Claude Code authentication 11 | - ✅ Docker installation 12 | 13 | **Everything else is optional** - the container runs fine without any additional setup. 14 | 15 | --- 16 | 17 | ## Quick Start 18 | 19 | ```bash 20 | # 1. Clone and enter directory 21 | git clone https://github.com/VishalJ99/claude-docker.git 22 | cd claude-docker 23 | 24 | # 2. Setup environment (completely optional - skip if you don't need custom config) 25 | cp .env.example .env 26 | nano .env # Add any optional configs 27 | 28 | # 3. Install (use sudo for GPU support) 29 | sudo ./src/install.sh # Or just ./src/install.sh without GPU 30 | 31 | # 4. Run from any project 32 | cd ~/your-project 33 | claude-docker 34 | ``` 35 | 36 | **That's it!** Claude runs in an isolated Docker container with access to your project directory. 37 | 38 | --- 39 | 40 | ## Command Line Reference 41 | 42 | ### Basic Usage 43 | ```bash 44 | claude-docker # Start Claude in current directory 45 | claude-docker --podman # Use podman instead of docker 46 | claude-docker --continue # Resume previous conversation 47 | claude-docker --rebuild # Force rebuild Docker image 48 | claude-docker --rebuild --no-cache # Rebuild without using cache 49 | claude-docker --memory 8g # Set container memory limit 50 | claude-docker --gpus all # Enable GPU access (requires nvidia-docker) 51 | claude-docker --cc-version 2.0.64 # Install specific Claude Code version 52 | ``` 53 | 54 | ### Available Flags 55 | 56 | | Flag | Description | Example | 57 | |------|-------------|---------| 58 | | `--podman` | Use podman instead of docker | `claude-docker --podman` | 59 | | `--continue` | Resume previous conversation in current directory | `claude-docker --continue` | 60 | | `--rebuild` | Force rebuild of the Docker image | `claude-docker --rebuild` | 61 | | `--no-cache` | When rebuilding, don't use Docker cache | `claude-docker --rebuild --no-cache` | 62 | | `--memory` | Set container memory limit | `claude-docker --memory 8g` | 63 | | `--gpus` | Enable GPU access | `claude-docker --gpus all` | 64 | | `--cc-version` | Install specific Claude Code version (requires rebuild) | `claude-docker --rebuild --cc-version 2.0.64` | 65 | 66 | ### Environment Variable Defaults 67 | Set defaults in your `.env` file: 68 | ```bash 69 | DOCKER_MEMORY_LIMIT=8g # Default memory limit 70 | DOCKER_GPU_ACCESS=all # Default GPU access 71 | ``` 72 | 73 | ### Examples 74 | ```bash 75 | # Resume work with 16GB memory limit 76 | claude-docker --continue --memory 16g 77 | 78 | # Rebuild after updating .env file 79 | claude-docker --rebuild 80 | 81 | # Use GPU for ML tasks 82 | claude-docker --gpus all 83 | 84 | # Rollback to specific Claude Code version 85 | claude-docker --rebuild --cc-version 2.0.64 86 | 87 | # Install latest version after rollback 88 | claude-docker --rebuild 89 | ``` 90 | 91 | --- 92 | 93 | ## Optional Configuration 94 | 95 | All configuration below is optional. The container works out-of-the-box without any of these settings. 96 | 97 | ### Environment Variables (.env file) 98 | 99 | **All environment variables are completely optional.** Only configure what you need: 100 | 101 | #### Twilio SMS Notifications 102 | Get phone notifications when long-running tasks complete: 103 | ```bash 104 | TWILIO_ACCOUNT_SID=your_twilio_sid 105 | TWILIO_AUTH_TOKEN=your_twilio_auth_token 106 | TWILIO_FROM_NUMBER=+1234567890 107 | TWILIO_TO_NUMBER=+0987654321 108 | ``` 109 | **Setup:** Create a free trial account at https://www.twilio.com/docs/usage/tutorials/how-to-use-your-free-trial-account 110 | 111 | #### Conda Integration 112 | Mount your host conda environments and packages into the container: 113 | ```bash 114 | # Primary conda installation path 115 | CONDA_PREFIX=/path/to/your/conda 116 | 117 | # Additional conda directories (space-separated list) 118 | # Directories are mounted to the same path inside the container 119 | # Automatic detection: 120 | # - Paths with "*env*" are added to CONDA_ENVS_DIRS (for environments) 121 | # - Paths with "*pkg*" are added to CONDA_PKGS_DIRS (for package cache) 122 | CONDA_EXTRA_DIRS="/path/to/envs /path/to/pkgs" 123 | ``` 124 | 125 | All your conda environments work exactly as they do on your host system - no Dockerfile modifications needed. 126 | 127 | #### System Packages 128 | Additional apt packages beyond the Dockerfile defaults: 129 | ```bash 130 | SYSTEM_PACKAGES="libopenslide0 libgdal-dev" 131 | ``` 132 | **Note:** Adding system packages requires rebuilding the image with `claude-docker --rebuild`. 133 | 134 | ### Git & SSH Configuration 135 | 136 | #### Git Credentials 137 | Git configuration (global username and email) is automatically loaded from your host system during Docker build. Commits appear as you. 138 | 139 | **Note:** Whether Claude uses git at all is controlled by your `CLAUDE.md` prompt engineering. The default configuration does NOT include git behaviors - customize after installation if needed. 140 | 141 | #### SSH Keys for Git Push 142 | Claude Docker uses dedicated SSH keys (separate from your personal keys for security): 143 | 144 | ```bash 145 | # 1. Create directory and generate key 146 | mkdir -p ~/.claude-docker/ssh 147 | ssh-keygen -t rsa -b 4096 -f ~/.claude-docker/ssh/id_rsa -N '' 148 | 149 | # 2. Add public key to GitHub 150 | cat ~/.claude-docker/ssh/id_rsa.pub 151 | # Copy output and add to: GitHub → Settings → SSH and GPG keys → New SSH key 152 | 153 | # 3. Test connection 154 | ssh -T git@github.com -i ~/.claude-docker/ssh/id_rsa 155 | ``` 156 | 157 | ### Custom Agent Behavior 158 | 159 | After installation, customize Claude's behavior by editing files in `~/.claude-docker/claude-home/`: 160 | 161 | #### CLAUDE.md (Prompt Engineering) 162 | ```bash 163 | nano ~/.claude-docker/claude-home/CLAUDE.md 164 | ``` 165 | 166 | **Important:** The default `CLAUDE.md` includes the author's opinionated workflow preferences: 167 | - Automatic codebase indexing on startup 168 | - Task clarification protocols 169 | - Conda environment execution standards 170 | - Context.md maintenance requirements 171 | - SMS notification behaviors 172 | 173 | These are NOT requirements of the Docker container - they're customizable prompt engineering. Change `CLAUDE.md` to match your workflow preferences. 174 | 175 | #### settings.json (Claude Code Settings) 176 | ```bash 177 | nano ~/.claude-docker/claude-home/settings.json 178 | ``` 179 | 180 | Configure Claude Code settings including: 181 | - **Timeouts:** Bash command execution timeouts (default: 24 hours) 182 | - **MCP Timeout:** MCP server response timeout (default: 60 seconds) 183 | - **Permissions:** Auto-approved commands (ls, grep, find, etc.) 184 | 185 | **Recommended:** Disable auto compact to gain 30% extra usable context window: 186 | ```bash 187 | /config auto compact set to false 188 | ``` 189 | Run this command inside Claude Code to disable automatic context compaction. 190 | 191 | #### Other Customizations 192 | This directory is mounted as `~/.claude` inside the container, so you can also customize: 193 | - Slash commands (`.claude/commands/`) 194 | - Agent personas (`.claude/agents/`) 195 | - All standard Claude Code customizations 196 | 197 | --- 198 | 199 | ## Pre-configured MCP Servers 200 | 201 | MCP (Model Context Protocol) servers extend Claude's capabilities. Installation is simple - just add commands to `mcp-servers.txt` that you'd normally run in terminal. 202 | 203 | ### Included MCP Servers 204 | 205 | #### Serena MCP 206 | Semantic code navigation and symbol manipulation with automatic project indexing. 207 | 208 | **Value:** Better efficiency in retrieving and editing code means greater token efficiency and more usable context window. 209 | 210 | #### Context7 MCP 211 | Official, version-specific documentation straight from the source. 212 | 213 | **Value:** Unhobble Claude Code by giving it up-to-date docs. Stale documentation is an artificial performance bottleneck. 214 | 215 | **Setup:** Create a free API key at [context7.com/dashboard](https://context7.com/dashboard) and add it to your `.env` file as `CONTEXT7_API_KEY`. 216 | 217 | #### Grep MCP 218 | Search real code examples on GitHub. 219 | 220 | **Value:** When documentation is missing, rapidly search across GitHub for working implementations to understand different APIs and syntaxes for unfamiliar tasks. 221 | 222 | #### Twilio MCP 223 | SMS notifications when tasks complete - step away from your monitor. 224 | 225 | **Value:** Work on long-running tasks without staying at your computer. Get notified when Claude needs your attention. 226 | 227 | ### Optional MCP Servers 228 | 229 | These servers are pre-configured but commented out in `mcp-servers.txt` to keep the default setup lean. Uncomment to enable. 230 | 231 | #### Zen MCP (Disabled by Default) 232 | Multi-model code review and debugging using Gemini and other LLMs via OpenRouter. 233 | 234 | **Value:** Different LLMs debating each other normally outperforms any single LLM. Zen supports conversation threading for collaborative AI discussions, second opinions, and model debates. 235 | 236 | **Why disabled by default:** Each Zen tool adds significant tokens to context. For focused agentic coding, this overhead isn't worth it. Enable for "vibe coding" sessions where you want AI model collaboration. 237 | 238 | **To enable:** 239 | 1. Uncomment the Zen MCP line in `mcp-servers.txt` 240 | 2. Add `OPENROUTER_API_KEY` to your `.env` file (get one at [openrouter.ai](https://openrouter.ai)) 241 | 3. Rebuild: `claude-docker --rebuild` 242 | 243 | **Important:** Only enable the tools you need - each tool is expensive in terms of context tokens. See the [Zen MCP tools documentation](https://github.com/BeehiveInnovations/zen-mcp-server/tree/main/tools) for available tools and the [.env.example](https://github.com/BeehiveInnovations/zen-mcp-server/blob/main/.env.example) for all supported environment variables. 244 | 245 | ### MCP Installation 246 | 247 | Example `mcp-servers.txt`: 248 | ```bash 249 | # Serena - Coding agent toolkit 250 | claude mcp add-json "serena" '{"command":"bash","args":[...]}' 251 | 252 | # Context7 - Documentation lookup (requires API key in .env) 253 | claude mcp add -s user --transport http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: ${CONTEXT7_API_KEY}" 254 | 255 | # Grep - GitHub code search (no API key needed) 256 | claude mcp add -s user --transport http grep https://mcp.grep.app 257 | 258 | # Twilio SMS - Send notifications (requires Twilio credentials in .env) 259 | claude mcp add-json twilio -s user '{"command":"npx","args":["-y","@yiyang.1i/sms-mcp-server"],"env":{...}}' 260 | ``` 261 | 262 | Each line is exactly what you'd type in your terminal to run that MCP server. The installation script handles the rest. 263 | 264 | 📋 **See [MCP_SERVERS.md](MCP_SERVERS.md) for more examples and detailed setup instructions** 265 | 266 | --- 267 | 268 | ## Features 269 | 270 | ### Core Capabilities 271 | - **Complete AI coding agent setup** - Claude Code in isolated Docker container 272 | - **Pre-configured MCP servers** - Advanced coding tools, documentation lookup, SMS notifications and easy set up to add more. 273 | - **Persistent conversation history** - Resumes from where you left off with `--continue`, even after crashes 274 | - **Host machines conda envs** - No need to waste time re setting up conda environments, host machines conda dirs are mounted and ready to use by claude docker. 275 | - **Simple one-command setup** - Zero friction plug-and-play integration 276 | - **Fully customizable** - Modify files at `~/.claude-docker` for custom behavior 277 | 278 | --- 279 | 280 | ## Vanilla Installation (Minimal Setup) 281 | 282 | Want to start simple? Skip the pre-configured MCP servers and extra packages: 283 | 284 | ### 1. Remove MCP Servers 285 | ```bash 286 | # Empty the file or delete unwanted entries 287 | > mcp-servers.txt 288 | claude-docker --rebuild --no-cache # For changes to take effect. 289 | ``` 290 | 291 | ### 2. Remove Unwanted Packages 292 | Edit `Dockerfile` to remove packages you don't need: 293 | ```bash 294 | # Line 8: Python 295 | # Line 10: Git 296 | # Other lines: Various system packages 297 | nano Dockerfile 298 | claude-docker --rebuild --no-cache # For changes to take effect. 299 | ``` 300 | 301 | ### 3. Customize Agent Behavior 302 | After installation, customize Claude's behavior: 303 | ```bash 304 | nano ~/.claude-docker/claude-home/CLAUDE.md 305 | ``` 306 | --- 307 | 308 | 309 | ## Created By 310 | - **Repository**: https://github.com/VishalJ99/claude-docker 311 | - **Author**: Vishal J (@VishalJ99) 312 | 313 | --- 314 | 315 | ## License 316 | 317 | This project is open source. See the LICENSE file for details. 318 | -------------------------------------------------------------------------------- /docs/architecture-diagrams.md: -------------------------------------------------------------------------------- 1 | # Claude Docker Architecture Diagrams 2 | 3 | This document contains Mermaid diagrams explaining the internals of each core script. 4 | 5 | --- 6 | 7 | ## System Overview 8 | 9 | ```mermaid 10 | flowchart TB 11 | subgraph HOST["Host System"] 12 | User([User]) 13 | Install["install.sh
(one-time setup)"] 14 | Wrapper["claude-docker.sh
(launcher)"] 15 | 16 | subgraph HostFiles["Host File System"] 17 | HomeDir["~/.claude-docker/"] 18 | ClaudeHome["claude-home/"] 19 | SSHDir["ssh/"] 20 | ProjectDir["Project Directory"] 21 | EnvFile[".env
(SYSTEM_PACKAGES,
CONDA_PREFIX,
CONDA_EXTRA_DIRS)"] 22 | end 23 | 24 | subgraph CondaHost["Conda Installation (Host)"] 25 | CondaPrefix["$CONDA_PREFIX
/path/to/miniconda3"] 26 | CondaExtraDirs["$CONDA_EXTRA_DIRS
(space-separated paths)"] 27 | end 28 | end 29 | 30 | subgraph DOCKER["Docker Container"] 31 | Startup["startup.sh
(entrypoint)"] 32 | Claude["Claude Code CLI"] 33 | 34 | subgraph Mounts["Volume Mounts"] 35 | Workspace["/workspace
(rw)"] 36 | ContainerClaudeHome["/home/claude-user/.claude
(rw)"] 37 | ContainerSSH["/home/claude-user/.ssh
(rw)"] 38 | ContainerConda["$CONDA_PREFIX
(ro - read only)"] 39 | ContainerCondaExtra["CONDA_EXTRA_DIRS
(ro - read only)"] 40 | end 41 | end 42 | 43 | User -->|"First time"| Install 44 | User -->|"Each session"| Wrapper 45 | Install -->|"Creates"| HomeDir 46 | Install -->|"Copies template"| ClaudeHome 47 | 48 | Wrapper -->|"Sources .env
builds image"| EnvFile 49 | Wrapper -->|"Runs container"| DOCKER 50 | Wrapper -->|"Mounts"| ProjectDir --> Workspace 51 | Wrapper -->|"Mounts"| ClaudeHome --> ContainerClaudeHome 52 | Wrapper -->|"Mounts"| SSHDir --> ContainerSSH 53 | Wrapper -->|"Mounts (if set)"| CondaPrefix --> ContainerConda 54 | Wrapper -->|"Mounts (if set)"| CondaExtraDirs --> ContainerCondaExtra 55 | 56 | Startup -->|"Loads env &
starts"| Claude 57 | ``` 58 | 59 | --- 60 | 61 | ## 1. install.sh - One-Time Setup 62 | 63 | ### Flow Diagram 64 | 65 | ```mermaid 66 | flowchart TD 67 | Start([Start install.sh]) --> GetPaths["Resolve SCRIPT_DIR
and PROJECT_ROOT"] 68 | 69 | GetPaths --> CreateDir["mkdir -p ~/.claude-docker/claude-home"] 70 | 71 | CreateDir --> CopyTemplate["Copy .claude/* template
to ~/.claude-docker/claude-home/"] 72 | 73 | CopyTemplate --> CheckEnv{"Does .env exist
in PROJECT_ROOT?"} 74 | 75 | CheckEnv -->|No| CreateEnv["Copy .env.example → .env"] 76 | CheckEnv -->|Yes| SkipEnv["Skip .env creation"] 77 | 78 | CreateEnv --> WarnEdit["Warn: Please edit
with your API keys!"] 79 | WarnEdit --> CheckAlias 80 | SkipEnv --> CheckAlias 81 | 82 | CheckAlias{"'claude-docker' alias
in ~/.zshrc?"} 83 | 84 | CheckAlias -->|No| AddAlias["Append alias to ~/.zshrc:
alias claude-docker='...src/claude-docker.sh'"] 85 | CheckAlias -->|Yes| SkipAlias["Skip alias creation"] 86 | 87 | AddAlias --> MakeExec 88 | SkipAlias --> MakeExec 89 | 90 | MakeExec["chmod +x claude-docker.sh
chmod +x startup.sh"] 91 | 92 | MakeExec --> Done([Installation Complete]) 93 | ``` 94 | 95 | ### Files Created/Modified 96 | 97 | ```mermaid 98 | flowchart LR 99 | subgraph Created["Files Created"] 100 | A["~/.claude-docker/claude-home/"] 101 | B["~/.claude-docker/claude-home/CLAUDE.md"] 102 | C["~/.claude-docker/claude-home/settings.json"] 103 | D["PROJECT_ROOT/.env"] 104 | end 105 | 106 | subgraph Modified["Files Modified"] 107 | E["~/.zshrc
(alias added)"] 108 | end 109 | 110 | subgraph Read["Files Read"] 111 | F["PROJECT_ROOT/.claude/*
(templates)"] 112 | G["PROJECT_ROOT/.env.example"] 113 | end 114 | ``` 115 | 116 | --- 117 | 118 | ## 2. claude-docker.sh - Main Launcher 119 | 120 | ### Argument Parsing 121 | 122 | ```mermaid 123 | flowchart TD 124 | Start([Start]) --> ParseArgs["Parse CLI Arguments"] 125 | 126 | ParseArgs --> ArgLoop{{"Loop through args"}} 127 | 128 | ArgLoop -->|--podman| SetPodman["DOCKER=podman"] 129 | ArgLoop -->|--no-cache| SetNoCache["NO_CACHE='--no-cache'"] 130 | ArgLoop -->|--rebuild| SetRebuild["FORCE_REBUILD=true"] 131 | ArgLoop -->|--continue| SetContinue["CONTINUE_FLAG='--continue'"] 132 | ArgLoop -->|--memory X| SetMemory["MEMORY_LIMIT=X"] 133 | ArgLoop -->|--gpus X| SetGPU["GPU_ACCESS=X"] 134 | ArgLoop -->|other| CollectArgs["ARGS+=(arg)"] 135 | 136 | SetPodman --> ArgLoop 137 | SetNoCache --> ArgLoop 138 | SetRebuild --> ArgLoop 139 | SetContinue --> ArgLoop 140 | SetMemory --> ArgLoop 141 | SetGPU --> ArgLoop 142 | CollectArgs --> ArgLoop 143 | 144 | ArgLoop -->|done| ResolvePaths["Resolve Paths:
CURRENT_DIR, SCRIPT_DIR, PROJECT_ROOT"] 145 | ``` 146 | 147 | ### Main Flow 148 | 149 | ```mermaid 150 | flowchart TD 151 | Start([Start claude-docker.sh]) --> ParseArgs["Parse CLI arguments
(--podman, --rebuild, etc.)"] 152 | 153 | ParseArgs --> CheckClaudeDir{"Does .claude/ exist
in current project?"} 154 | 155 | CheckClaudeDir -->|No| CreateClaudeDir["Create .claude/
Copy CLAUDE.md template
Copy scratchpad.md"] 156 | CheckClaudeDir -->|Yes| SkipCreate["Skip creation"] 157 | 158 | CreateClaudeDir --> CheckEnv 159 | SkipCreate --> CheckEnv 160 | 161 | CheckEnv{"Does PROJECT_ROOT/.env
exist?"} 162 | 163 | CheckEnv -->|Yes| SourceEnv["Source .env file
(get TWILIO vars, etc.)"] 164 | CheckEnv -->|No| WarnEnv["Warn: Twilio features
unavailable"] 165 | 166 | SourceEnv --> ApplyEnvDefaults 167 | WarnEnv --> ApplyEnvDefaults 168 | 169 | ApplyEnvDefaults["Apply env defaults:
MEMORY_LIMIT, GPU_ACCESS"] 170 | 171 | ApplyEnvDefaults --> NeedRebuild{"Need to rebuild
Docker image?"} 172 | 173 | NeedRebuild -->|"Image missing OR
--rebuild flag"| BuildImage["Build Docker Image"] 174 | NeedRebuild -->|No| SkipBuild["Skip build"] 175 | 176 | BuildImage --> EnsureDirs 177 | SkipBuild --> EnsureDirs 178 | 179 | EnsureDirs["Ensure directories exist:
~/.claude-docker/claude-home
~/.claude-docker/ssh"] 180 | 181 | EnsureDirs --> CopyAuth{"Copy credentials
if not present?"} 182 | 183 | CopyAuth --> CheckSSH{"SSH keys
configured?"} 184 | 185 | CheckSSH -->|No| WarnSSH["Warn: SSH keys not found
Show setup instructions"] 186 | CheckSSH -->|Yes| CreateSSHConfig["Create SSH config
if not exists"] 187 | 188 | WarnSSH --> PrepMounts 189 | CreateSSHConfig --> PrepMounts 190 | 191 | PrepMounts["Prepare mount arguments:
- Conda mounts
- Memory/GPU options"] 192 | 193 | PrepMounts --> RunDocker["docker run -it --rm
with all mounts and args"] 194 | 195 | RunDocker --> End([Container Running]) 196 | ``` 197 | 198 | ### Docker Build Process 199 | 200 | ```mermaid 201 | flowchart TD 202 | NeedBuild([Need Rebuild]) --> SourceEnv["Source .env file
(already done in main flow)"] 203 | 204 | SourceEnv --> CopyAuth{"~/.claude.json
exists?"} 205 | 206 | CopyAuth -->|Yes| CopyClaude["Copy ~/.claude.json
to PROJECT_ROOT/
(temporary for build)"] 207 | CopyAuth -->|No| GetGitConfig 208 | 209 | CopyClaude --> GetGitConfig["Get git config from host:
git config --global user.name
git config --global user.email"] 210 | 211 | GetGitConfig --> BuildArgs["Construct BUILD_ARGS:
--build-arg USER_UID=$(id -u)
--build-arg USER_GID=$(id -g)
--build-arg GIT_USER_NAME=...
--build-arg GIT_USER_EMAIL=..."] 212 | 213 | BuildArgs --> CheckSysPkg{"SYSTEM_PACKAGES
defined in .env?"} 214 | 215 | CheckSysPkg -->|Yes| AddSysPkg["Add --build-arg SYSTEM_PACKAGES=...

Example .env:
SYSTEM_PACKAGES='vim curl htop'

These get installed via apt-get
during image build"] 216 | CheckSysPkg -->|No| RunBuild 217 | 218 | AddSysPkg --> RunBuild["docker build $BUILD_ARGS
-t claude-docker:latest
PROJECT_ROOT"] 219 | 220 | RunBuild --> Cleanup["Remove temporary
.claude.json from PROJECT_ROOT"] 221 | 222 | Cleanup --> Done([Build Complete]) 223 | ``` 224 | 225 | ### Volume Mounts 226 | 227 | ```mermaid 228 | flowchart LR 229 | subgraph HOST["Host System"] 230 | PWD["Current Project
(pwd)"] 231 | ClaudeHome["~/.claude-docker/
claude-home/"] 232 | SSHDir["~/.claude-docker/
ssh/"] 233 | CondaPrefix["$CONDA_PREFIX
(if set in .env)"] 234 | CondaExtra["$CONDA_EXTRA_DIRS
(if set in .env)"] 235 | end 236 | 237 | subgraph CONTAINER["Docker Container"] 238 | Workspace["/workspace
(rw)"] 239 | ContClaudeHome["/home/claude-user/
.claude (rw)"] 240 | ContSSH["/home/claude-user/
.ssh (rw)"] 241 | ContConda["$CONDA_PREFIX
(ro)"] 242 | ContCondaExtra["Extra conda dirs
(ro)"] 243 | end 244 | 245 | PWD -->|"-v"| Workspace 246 | ClaudeHome -->|"-v"| ContClaudeHome 247 | SSHDir -->|"-v"| ContSSH 248 | CondaPrefix -.->|"-v (optional)"| ContConda 249 | CondaExtra -.->|"-v (optional)"| ContCondaExtra 250 | ``` 251 | 252 | ### Conda Mounting Logic 253 | 254 | ```mermaid 255 | flowchart TD 256 | Start([Start Conda Mount Setup]) --> CheckPrefix{"CONDA_PREFIX
set in .env?"} 257 | 258 | CheckPrefix -->|Yes| ValidatePrefix{"Directory
$CONDA_PREFIX exists?"} 259 | CheckPrefix -->|No| LogNoConda["Log: No conda
installation configured"] 260 | 261 | ValidatePrefix -->|Yes| MountPrefix["Add mount:
-v $CONDA_PREFIX:$CONDA_PREFIX:ro

Add env vars:
-e CONDA_PREFIX=$CONDA_PREFIX
-e CONDA_EXE=$CONDA_PREFIX/bin/conda"] 262 | ValidatePrefix -->|No| LogNoConda 263 | 264 | MountPrefix --> CheckExtra{"CONDA_EXTRA_DIRS
set in .env?"} 265 | LogNoConda --> CheckExtra 266 | 267 | CheckExtra -->|Yes| ParseDirs["Parse space-separated paths

Example .env:
CONDA_EXTRA_DIRS='/path/envs /path/pkgs'"] 268 | CheckExtra -->|No| Done([Done]) 269 | 270 | ParseDirs --> LoopDirs{{"For each dir
in CONDA_EXTRA_DIRS"}} 271 | 272 | LoopDirs --> CheckDirExists{"Directory
exists?"} 273 | 274 | CheckDirExists -->|Yes| MountDir["Add mount:
-v $dir:$dir:ro"] 275 | CheckDirExists -->|No| SkipDir["Log: Skipping $dir
(not found)"] 276 | 277 | MountDir --> ClassifyDir{"Path contains
'env' or 'pkg'?"} 278 | SkipDir --> LoopDirs 279 | 280 | ClassifyDir -->|"Contains 'env'"| AddEnvPath["Append to CONDA_ENVS_PATHS"] 281 | ClassifyDir -->|"Contains 'pkg'"| AddPkgPath["Append to CONDA_PKGS_PATHS"] 282 | ClassifyDir -->|Neither| LoopDirs 283 | 284 | AddEnvPath --> LoopDirs 285 | AddPkgPath --> LoopDirs 286 | 287 | LoopDirs -->|"All dirs
processed"| SetEnvVars{"Any paths
collected?"} 288 | 289 | SetEnvVars -->|"CONDA_ENVS_PATHS set"| ExportEnvs["-e CONDA_ENVS_DIRS=
colon-separated paths"] 290 | SetEnvVars -->|"CONDA_PKGS_PATHS set"| ExportPkgs["-e CONDA_PKGS_DIRS=
colon-separated paths"] 291 | SetEnvVars -->|No| Done 292 | 293 | ExportEnvs --> Done 294 | ExportPkgs --> Done 295 | ``` 296 | 297 | ### Conda Mount Example 298 | 299 | ```mermaid 300 | flowchart LR 301 | subgraph ENV[".env Configuration"] 302 | E1["CONDA_PREFIX=/home/user/miniconda3"] 303 | E2["CONDA_EXTRA_DIRS='/data/conda/envs /data/conda/pkgs'"] 304 | end 305 | 306 | subgraph Parsing["Parsed Result"] 307 | P1["Mount: -v /home/user/miniconda3:/home/user/miniconda3:ro"] 308 | P2["Mount: -v /data/conda/envs:/data/conda/envs:ro"] 309 | P3["Mount: -v /data/conda/pkgs:/data/conda/pkgs:ro"] 310 | P4["Env: CONDA_PREFIX=/home/user/miniconda3"] 311 | P5["Env: CONDA_EXE=/home/user/miniconda3/bin/conda"] 312 | P6["Env: CONDA_ENVS_DIRS=/data/conda/envs"] 313 | P7["Env: CONDA_PKGS_DIRS=/data/conda/pkgs"] 314 | end 315 | 316 | E1 --> P1 317 | E1 --> P4 318 | E1 --> P5 319 | E2 --> P2 320 | E2 --> P3 321 | E2 --> P6 322 | E2 --> P7 323 | ``` 324 | 325 | --- 326 | 327 | ## 3. startup.sh - Container Entrypoint 328 | 329 | ### Flow Diagram 330 | 331 | ```mermaid 332 | flowchart TD 333 | Start([Container Starts]) --> LoadEnv{"/app/.env
exists?"} 334 | 335 | LoadEnv -->|Yes| SourceEnv["Source /app/.env
Export TWILIO_* vars"] 336 | LoadEnv -->|No| WarnNoEnv["Warn: No .env
in image"] 337 | 338 | SourceEnv --> CheckAuth 339 | WarnNoEnv --> CheckAuth 340 | 341 | CheckAuth{"~/.claude/
.credentials.json
exists?"} 342 | 343 | CheckAuth -->|Yes| FoundAuth["Log: Found existing
authentication"] 344 | CheckAuth -->|No| NoAuth["Log: Will need to
log in"] 345 | 346 | FoundAuth --> CheckClaudeMD 347 | NoAuth --> CheckClaudeMD 348 | 349 | CheckClaudeMD{"~/.claude/
CLAUDE.md exists?"} 350 | 351 | CheckClaudeMD -->|No| CopyTemplate["Copy CLAUDE.md from:
1. /app/.claude/CLAUDE.md
2. ~/.claude.template/ (fallback)"] 352 | CheckClaudeMD -->|Yes| UseExisting["Use existing CLAUDE.md
Log host path info"] 353 | 354 | CopyTemplate --> VerifyTwilio 355 | UseExisting --> VerifyTwilio 356 | 357 | VerifyTwilio{"TWILIO_ACCOUNT_SID
and AUTH_TOKEN set?"} 358 | 359 | VerifyTwilio -->|Yes| TwilioOK["Log: SMS notifications
enabled"] 360 | VerifyTwilio -->|No| TwilioDisabled["Log: SMS notifications
disabled"] 361 | 362 | TwilioOK --> StartClaude 363 | TwilioDisabled --> StartClaude 364 | 365 | StartClaude["exec claude
$CLAUDE_CONTINUE_FLAG
--dangerously-skip-permissions
$@"] 366 | 367 | StartClaude --> Running([Claude Code Running]) 368 | ``` 369 | 370 | ### Environment Variables 371 | 372 | ```mermaid 373 | flowchart TD 374 | subgraph Sources["Environment Variable Sources"] 375 | EnvFile["/app/.env
(baked into image)"] 376 | DockerEnv["Docker -e flags
(from claude-docker.sh)"] 377 | end 378 | 379 | subgraph Variables["Key Variables"] 380 | Twilio["TWILIO_ACCOUNT_SID
TWILIO_AUTH_TOKEN
TWILIO_FROM_NUMBER
TWILIO_TO_NUMBER"] 381 | Conda["CONDA_PREFIX
CONDA_EXE
CONDA_ENVS_DIRS
CONDA_PKGS_DIRS"] 382 | Claude["CLAUDE_CONTINUE_FLAG"] 383 | end 384 | 385 | subgraph Usage["Used By"] 386 | MCP["Twilio MCP Server"] 387 | Scripts["Python Scripts"] 388 | ClaudeCLI["Claude CLI"] 389 | end 390 | 391 | EnvFile --> Twilio 392 | DockerEnv --> Conda 393 | DockerEnv --> Claude 394 | 395 | Twilio --> MCP 396 | Conda --> Scripts 397 | Claude --> ClaudeCLI 398 | ``` 399 | 400 | ### Files Accessed Inside Container 401 | 402 | ```mermaid 403 | flowchart LR 404 | subgraph Read["Files Read"] 405 | R1["/app/.env"] 406 | R2["~/.claude/.credentials.json"] 407 | R3["/app/.claude/CLAUDE.md
(template)"] 408 | end 409 | 410 | subgraph WriteOrCreate["Files Written/Created"] 411 | W1["~/.claude/CLAUDE.md
(if missing)"] 412 | end 413 | 414 | subgraph Mounted["Mounted from Host"] 415 | M1["/workspace
(project files)"] 416 | M2["~/.claude/
(persistent settings)"] 417 | M3["~/.ssh/
(SSH keys)"] 418 | end 419 | ``` 420 | 421 | --- 422 | 423 | ## Complete Data Flow 424 | 425 | ```mermaid 426 | sequenceDiagram 427 | participant U as User 428 | participant I as install.sh 429 | participant W as claude-docker.sh 430 | participant D as Docker Engine 431 | participant S as startup.sh 432 | participant C as Claude Code 433 | 434 | Note over U,C: First Time Setup 435 | U->>I: Run install.sh 436 | I->>I: Create ~/.claude-docker/ 437 | I->>I: Copy templates 438 | I->>I: Setup .env 439 | I->>I: Add alias to .zshrc 440 | I-->>U: Setup complete 441 | 442 | Note over U,C: Each Session 443 | U->>W: Run claude-docker [args] 444 | W->>W: Parse arguments 445 | W->>W: Check/create project .claude/ 446 | W->>W: Source .env 447 | 448 | alt Image needs building 449 | W->>D: docker build 450 | D-->>W: Image ready 451 | end 452 | 453 | W->>D: docker run with mounts 454 | D->>S: Container starts 455 | S->>S: Load /app/.env 456 | S->>S: Check credentials 457 | S->>S: Setup CLAUDE.md 458 | S->>C: exec claude CLI 459 | C-->>U: Interactive session 460 | ``` 461 | 462 | --- 463 | 464 | ## Directory Structure 465 | 466 | ```mermaid 467 | flowchart TD 468 | subgraph Host["Host File System"] 469 | Home["~"] 470 | ClaudeDocker["~/.claude-docker/"] 471 | CH["claude-home/
├── CLAUDE.md
├── settings.json
└── .credentials.json"] 472 | SSH["ssh/
├── id_rsa
├── id_rsa.pub
└── config"] 473 | 474 | Project["Your Project/"] 475 | ProjClaude[".claude/
├── CLAUDE.md
└── settings.local.json"] 476 | 477 | Repo["claude-docker repo/"] 478 | RepoSrc["src/
├── install.sh
├── claude-docker.sh
└── startup.sh"] 479 | RepoEnv[".env"] 480 | end 481 | 482 | Home --> ClaudeDocker 483 | ClaudeDocker --> CH 484 | ClaudeDocker --> SSH 485 | 486 | Home --> Project 487 | Project --> ProjClaude 488 | 489 | Home --> Repo 490 | Repo --> RepoSrc 491 | Repo --> RepoEnv 492 | ``` 493 | 494 | --- 495 | 496 | ## Quick Reference 497 | 498 | | Script | Purpose | When Run | Key Actions | 499 | |--------|---------|----------|-------------| 500 | | `install.sh` | One-time setup | Once after cloning | Creates directories, copies templates, adds shell alias | 501 | | `claude-docker.sh` | Launch wrapper | Each session | Builds image if needed, sets up mounts, runs container | 502 | | `startup.sh` | Container entrypoint | Inside container | Loads env, checks auth, starts Claude CLI | 503 | --------------------------------------------------------------------------------