#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE_DIR="$SCRIPT_DIR/templates/code-intel"
SKILLS_TEMPLATE_DIR="$SCRIPT_DIR/templates/skills/claude"
CLAUDE_TEMPLATE_DIR="$SCRIPT_DIR/templates/claude"
# Usage
usage() {
echo "Usage: $0 <project-path> [options]"
echo ""
echo "Initialize a project for Code Intel MCP Server v1.15"
echo ""
echo "Arguments:"
echo " project-path Path to the target project (required)"
echo ""
echo "Options:"
echo " --include Directories/files to index (default: entire project)"
echo " Comma-separated, relative to project root"
echo " Supports: directories, files, glob patterns"
echo " --exclude Additional directories/files to exclude"
echo " Comma-separated, added to default exclusions"
echo " --sync-ttl Hours between auto-sync (default: 1)"
echo " --help Show this help message"
echo ""
echo "Examples:"
echo " $0 /path/to/my-project"
echo " $0 /path/to/my-project --include=src,lib"
echo " $0 /path/to/my-project --exclude=tests,docs,*.log"
echo " $0 /path/to/my-project --include=app/src --exclude=app/src/vendor"
exit 1
}
# Parse arguments
PROJECT_PATH=""
INCLUDE_DIRS=""
EXCLUDE_DIRS=""
SYNC_TTL_HOURS="1"
while [[ $# -gt 0 ]]; do
case $1 in
--include=*)
INCLUDE_DIRS="${1#*=}"
shift
;;
--exclude=*)
EXCLUDE_DIRS="${1#*=}"
shift
;;
--sync-ttl=*)
SYNC_TTL_HOURS="${1#*=}"
shift
;;
--help|-h)
usage
;;
-*)
echo "Unknown option: $1"
usage
;;
*)
if [ -z "$PROJECT_PATH" ]; then
PROJECT_PATH="$1"
else
echo "Too many arguments"
usage
fi
shift
;;
esac
done
if [ -z "$PROJECT_PATH" ]; then
echo "Error: project-path is required"
echo ""
usage
fi
# Resolve absolute path
PROJECT_PATH="$(cd "$PROJECT_PATH" 2>/dev/null && pwd)" || {
echo "Error: Directory does not exist: $PROJECT_PATH"
exit 1
}
echo "=== Code Intel Project Initialization v1.15 ==="
echo ""
echo "Project: $PROJECT_PATH"
echo "MCP Server: $SCRIPT_DIR"
echo ""
# Create .code-intel directory structure
echo "Creating .code-intel/ directory..."
mkdir -p "$PROJECT_PATH/.code-intel/agreements"
mkdir -p "$PROJECT_PATH/.code-intel/chroma"
mkdir -p "$PROJECT_PATH/.code-intel/logs"
mkdir -p "$PROJECT_PATH/.code-intel/sessions"
mkdir -p "$PROJECT_PATH/.code-intel/verifiers"
mkdir -p "$PROJECT_PATH/.code-intel/doc_research"
mkdir -p "$PROJECT_PATH/.code-intel/review_prompts"
mkdir -p "$PROJECT_PATH/.code-intel/interventions"
echo " ✓ .code-intel/"
echo " ✓ .code-intel/agreements/"
echo " ✓ .code-intel/chroma/"
echo " ✓ .code-intel/logs/"
echo " ✓ .code-intel/sessions/"
echo " ✓ .code-intel/verifiers/"
echo " ✓ .code-intel/doc_research/"
echo " ✓ .code-intel/review_prompts/"
echo " ✓ .code-intel/interventions/"
# Process --include (default to "." for entire project)
if [ -z "$INCLUDE_DIRS" ]; then
INCLUDE_DIRS="."
fi
# Convert comma-separated include dirs to JSON array
IFS=',' read -ra INCL_ARRAY <<< "$INCLUDE_DIRS"
INCL_JSON=""
for item in "${INCL_ARRAY[@]}"; do
item=$(echo "$item" | xargs) # trim whitespace
if [ -n "$INCL_JSON" ]; then
INCL_JSON="$INCL_JSON, "
fi
INCL_JSON="$INCL_JSON\"$item\""
done
# Default exclude patterns
DEFAULT_EXCLUDES=(
"**/node_modules/**"
"**/__pycache__/**"
"**/venv/**"
"**/vendor/**"
"**/.git/**"
"**/.code-intel/**"
)
# Process --exclude and merge with defaults
declare -a FINAL_EXCLUDES=("${DEFAULT_EXCLUDES[@]}")
if [ -n "$EXCLUDE_DIRS" ]; then
IFS=',' read -ra EXCL_ARRAY <<< "$EXCLUDE_DIRS"
for item in "${EXCL_ARRAY[@]}"; do
item=$(echo "$item" | xargs) # trim whitespace
# Convert to glob pattern if needed
if [[ "$item" == *"*"* ]]; then
# Already a glob pattern, use as-is but ensure ** prefix
if [[ "$item" != "**/"* ]]; then
item="**/$item"
fi
elif [ -d "$PROJECT_PATH/$item" ]; then
# Directory: add /** suffix
item="**/$item/**"
elif [ -f "$PROJECT_PATH/$item" ]; then
# File: add **/ prefix
item="**/$item"
else
# Assume it's a pattern/path, add ** prefix and suffix
item="**/$item/**"
fi
FINAL_EXCLUDES+=("$item")
done
fi
# Convert exclude array to JSON
EXCL_JSON=""
for pattern in "${FINAL_EXCLUDES[@]}"; do
if [ -n "$EXCL_JSON" ]; then
EXCL_JSON="$EXCL_JSON,"
fi
EXCL_JSON="$EXCL_JSON
\"$pattern\""
done
# Generate config.json (only if not exists - preserve user settings)
if [ ! -f "$PROJECT_PATH/.code-intel/config.json" ]; then
if [ -f "$TEMPLATE_DIR/config.json" ]; then
cp "$TEMPLATE_DIR/config.json" "$PROJECT_PATH/.code-intel/config.json"
echo " ✓ .code-intel/config.json (from template)"
else
cat > "$PROJECT_PATH/.code-intel/config.json" << EOF
{
"version": "1.0",
"embedding_model": "multilingual-e5-small",
"source_dirs": [$INCL_JSON],
"exclude_patterns": [$EXCL_JSON
],
"chunk_strategy": "ast",
"chunk_max_tokens": 512,
"sync_ttl_hours": $SYNC_TTL_HOURS,
"sync_on_start": true,
"max_chunks": 10000,
"search_weights": {
"vector": 0.4,
"keyword": 0.2,
"definition": 0.3,
"reference": 0.1
}
}
EOF
echo " ✓ .code-intel/config.json"
fi
else
echo " - .code-intel/config.json already exists (skipped)"
fi
# Generate context.yml (only if not exists - preserve user settings)
if [ ! -f "$PROJECT_PATH/.code-intel/context.yml" ]; then
if [ -f "$TEMPLATE_DIR/context.yml" ]; then
cp "$TEMPLATE_DIR/context.yml" "$PROJECT_PATH/.code-intel/context.yml"
echo " ✓ .code-intel/context.yml (from template)"
else
cat > "$PROJECT_PATH/.code-intel/context.yml" << 'EOF'
# Code Intel Context Configuration v1.3
# See: https://github.com/tech-spoke/llm-helper
# Project rules (optional, auto-detected from CLAUDE.md)
# project_rules:
# source: "CLAUDE.md"
# summary: "" # Auto-generated by LLM
# Document research settings (v1.3)
# Sub-agent researches design docs for task-specific rules
doc_research:
enabled: true
docs_path:
- "docs/"
default_prompts:
- "default.md"
# Document search settings for analyze_impact
document_search:
include_patterns:
- "**/*.md"
- "**/README*"
- "**/docs/**/*"
exclude_patterns:
- "node_modules/**"
- "vendor/**"
- ".git/**"
- ".venv/**"
- "__pycache__/**"
EOF
echo " ✓ .code-intel/context.yml"
fi
else
echo " - .code-intel/context.yml already exists (skipped)"
fi
# Copy default verifier templates (if not exists)
if [ -d "$TEMPLATE_DIR/verifiers" ]; then
for file in "$TEMPLATE_DIR/verifiers"/*.md; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [ ! -f "$PROJECT_PATH/.code-intel/verifiers/$filename" ]; then
cp "$file" "$PROJECT_PATH/.code-intel/verifiers/"
echo " ✓ .code-intel/verifiers/$filename"
fi
fi
done
fi
# Copy default doc_research prompts (if not exists)
if [ -d "$TEMPLATE_DIR/doc_research" ]; then
for file in "$TEMPLATE_DIR/doc_research"/*.md; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [ ! -f "$PROJECT_PATH/.code-intel/doc_research/$filename" ]; then
cp "$file" "$PROJECT_PATH/.code-intel/doc_research/"
echo " ✓ .code-intel/doc_research/$filename"
fi
fi
done
fi
# Copy review_prompts (garbage_detection, quality_review)
if [ -d "$TEMPLATE_DIR/review_prompts" ]; then
for file in "$TEMPLATE_DIR/review_prompts"/*.md; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [ ! -f "$PROJECT_PATH/.code-intel/review_prompts/$filename" ]; then
cp "$file" "$PROJECT_PATH/.code-intel/review_prompts/"
echo " ✓ .code-intel/review_prompts/$filename"
fi
fi
done
fi
# Copy interventions prompts (v1.4)
if [ -d "$TEMPLATE_DIR/interventions" ]; then
for file in "$TEMPLATE_DIR/interventions"/*.md; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [ ! -f "$PROJECT_PATH/.code-intel/interventions/$filename" ]; then
cp "$file" "$PROJECT_PATH/.code-intel/interventions/"
echo " ✓ .code-intel/interventions/$filename"
fi
fi
done
fi
# Copy user_escalation.md (v1.13)
if [ -f "$TEMPLATE_DIR/user_escalation.md" ]; then
if [ ! -f "$PROJECT_PATH/.code-intel/user_escalation.md" ]; then
cp "$TEMPLATE_DIR/user_escalation.md" "$PROJECT_PATH/.code-intel/"
echo " ✓ .code-intel/user_escalation.md"
fi
fi
# Copy task_planning.md (v1.11)
if [ -f "$TEMPLATE_DIR/task_planning.md" ]; then
if [ ! -f "$PROJECT_PATH/.code-intel/task_planning.md" ]; then
cp "$TEMPLATE_DIR/task_planning.md" "$PROJECT_PATH/.code-intel/"
echo " ✓ .code-intel/task_planning.md"
fi
fi
# Copy phase_contract.yml (v1.13)
if [ -f "$TEMPLATE_DIR/phase_contract.yml" ]; then
if [ ! -f "$PROJECT_PATH/.code-intel/phase_contract.yml" ]; then
cp "$TEMPLATE_DIR/phase_contract.yml" "$PROJECT_PATH/.code-intel/"
echo " ✓ .code-intel/phase_contract.yml"
fi
fi
# Copy .claude directory (project rules, guides, and skills)
if [ -d "$SCRIPT_DIR/.claude" ] || [ -d "$SKILLS_TEMPLATE_DIR" ]; then
mkdir -p "$PROJECT_PATH/.claude/commands"
# Generate CLAUDE.md template (project-specific rules)
if [ ! -f "$PROJECT_PATH/.claude/CLAUDE.md" ]; then
PROJECT_NAME=$(basename "$PROJECT_PATH")
cat > "$PROJECT_PATH/.claude/CLAUDE.md" << EOF
# $PROJECT_NAME
## Core Rules
1. **Use \`/code\`** for guided implementation workflow with phase gates
## Project-Specific Rules
<!-- Add your project-specific rules here -->
EOF
echo " ✓ .claude/CLAUDE.md (template)"
fi
# Copy skill files (templates/skills/claude/*.md)
if [ -d "$SKILLS_TEMPLATE_DIR" ]; then
for file in "$SKILLS_TEMPLATE_DIR"/*.md; do
if [ -f "$file" ]; then
filename=$(basename "$file")
if [ ! -f "$PROJECT_PATH/.claude/commands/$filename" ]; then
cp "$file" "$PROJECT_PATH/.claude/commands/"
echo " ✓ .claude/commands/$filename"
fi
fi
done
fi
fi
# Show configured paths
echo ""
echo "Index configuration:"
echo " Include: $INCLUDE_DIRS"
if [ -n "$EXCLUDE_DIRS" ]; then
echo " Exclude: $EXCLUDE_DIRS (+ defaults)"
else
echo " Exclude: (defaults only)"
fi
# Update .gitignore
GITIGNORE_ENTRIES="
# Code Intel MCP Server
.code-intel/vectors-*.db
.code-intel/chroma/
.code-intel/ctags_cache/
.code-intel/sessions/
.code-intel/sync_state.json
.code-intel/.last_sync
.code-intel/learned_pairs.json
.code-intel/logs/
"
if [ -f "$PROJECT_PATH/.gitignore" ]; then
if ! grep -q ".code-intel/chroma" "$PROJECT_PATH/.gitignore" 2>/dev/null; then
echo "$GITIGNORE_ENTRIES" >> "$PROJECT_PATH/.gitignore"
echo " ✓ Updated .gitignore"
else
echo " - .gitignore already configured"
fi
else
echo "$GITIGNORE_ENTRIES" > "$PROJECT_PATH/.gitignore"
echo " ✓ Created .gitignore"
fi
# Get paths for MCP config
SERVER_PATH="$SCRIPT_DIR/code_intel_server.py"
if [ -f "$SCRIPT_DIR/venv/bin/python" ]; then
PYTHON_PATH="$SCRIPT_DIR/venv/bin/python"
else
# Fallback to system python
PYTHON_PATH=$(which python3 || which python)
echo " ⚠ venv not found, using system Python: $PYTHON_PATH"
fi
echo ""
echo "=== Initialization Complete ==="
echo ""
echo "Project structure:"
echo " $PROJECT_PATH/"
echo " ├── .claude/"
echo " │ ├── CLAUDE.md (project rules for LLM)"
echo " │ └── commands/ (skill files: /code, etc.)"
echo " └── .code-intel/"
echo " ├── config.json (indexing configuration)"
echo " ├── context.yml (context & doc research settings)"
echo " ├── phase_contract.yml (phase contract definitions, v1.13)"
echo " ├── agreements/ (learned NL->Symbol pairs)"
echo " ├── chroma/ (ChromaDB vector database)"
echo " ├── logs/ (DecisionLog, OutcomeLog)"
echo " ├── sessions/ (checkpoint persistence, v1.12)"
echo " ├── verifiers/ (verification prompts)"
echo " ├── doc_research/ (document research prompts)"
echo " ├── review_prompts/ (garbage detection, quality review)"
echo " ├── interventions/ (intervention prompts)"
echo " ├── task_planning.md (task decomposition guide, v1.11)"
echo " ├── user_escalation.md (user escalation procedure, v1.13)"
echo " └── sync_state.json (incremental sync state)"
echo ""
echo "=== Next Steps ==="
echo ""
echo "1. Install chromadb (required):"
echo ""
echo " pip install chromadb"
echo ""
echo "2. Add to your .mcp.json (create if not exists):"
echo ""
cat << EOF
{
"mcpServers": {
"code-intel": {
"type": "stdio",
"command": "$PYTHON_PATH",
"args": ["$SERVER_PATH"],
"env": {
"PYTHONPATH": "$SCRIPT_DIR"
}
}
}
}
EOF
echo ""
echo "3. Restart Claude Code to load the MCP server."
echo ""
echo "=== Features ==="
echo ""
echo "• ChromaDB-based semantic search (Forest/Map architecture)"
echo "• AST-based chunking for PHP, Python, JS, Blade, etc."
echo "• Fingerprint-based incremental sync (SHA256)"
echo "• Phase-gated implementation workflow"
echo "• Document research with sub-agent (v1.3)"
echo "• Intervention system for verification failures (v1.4)"
echo "• Quality review phase (v1.5)"
echo "• Git branch isolation for garbage detection (v1.2/v1.6)"
echo "• Parallel execution for search_text, Read, Grep (v1.7 - saves 27-35s)"
echo "• Optimized phase transitions with skip_implementation (v1.8)"
echo "• Phase necessity checks Q1/Q2/Q3 (v1.10)"
echo "• Deferred branch creation to READY phase (v1.11)"
echo "• Unified submit_phase API with compaction resilience (v1.11)"
echo "• Server-enforced task orchestration (v1.11)"
echo "• Session checkpoint persistence for CLI restart recovery (v1.12)"
echo "• Phase contract formalization with tools_used enforcement (v1.13)"
echo "• Distribution structure reorganization with templates/ (v1.14)"
echo "• LLM message externalization to phase_contract.yml (v1.15)"
echo ""
echo "Use '/code' skill for guided implementation workflow."
echo "Use 'sync_index' tool to manually trigger re-indexing."
echo ""