Files
claudetools/.claude/hooks/user-prompt-submit
Mike Swanson 390b10b32c Complete Phase 6: MSP Work Tracking with Context Recall System
Implements production-ready MSP platform with cross-machine persistent memory for Claude.

API Implementation:
- 130 REST API endpoints across 21 entities
- JWT authentication on all endpoints
- AES-256-GCM encryption for credentials
- Automatic audit logging
- Complete OpenAPI documentation

Database:
- 43 tables in MariaDB (172.16.3.20:3306)
- 42 SQLAlchemy models with modern 2.0 syntax
- Full Alembic migration system
- 99.1% CRUD test pass rate

Context Recall System (Phase 6):
- Cross-machine persistent memory via database
- Automatic context injection via Claude Code hooks
- Automatic context saving after task completion
- 90-95% token reduction with compression utilities
- Relevance scoring with time decay
- Tag-based semantic search
- One-command setup script

Security Features:
- JWT tokens with Argon2 password hashing
- AES-256-GCM encryption for all sensitive data
- Comprehensive audit trail for credentials
- HMAC tamper detection
- Secure configuration management

Test Results:
- Phase 3: 38/38 CRUD tests passing (100%)
- Phase 4: 34/35 core API tests passing (97.1%)
- Phase 5: 62/62 extended API tests passing (100%)
- Phase 6: 10/10 compression tests passing (100%)
- Overall: 144/145 tests passing (99.3%)

Documentation:
- Comprehensive architecture guides
- Setup automation scripts
- API documentation at /api/docs
- Complete test reports
- Troubleshooting guides

Project Status: 95% Complete (Production-Ready)
Phase 7 (optional work context APIs) remains for future enhancement.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 06:00:26 -07:00

120 lines
3.7 KiB
Bash

#!/bin/bash
#
# Claude Code Hook: user-prompt-submit
# Runs BEFORE each user message is processed
# Injects relevant context from the database into the conversation
#
# Expected environment variables:
# CLAUDE_PROJECT_ID - UUID of the current project
# JWT_TOKEN - Authentication token for API
# CLAUDE_API_URL - API base URL (default: http://localhost:8000)
# CONTEXT_RECALL_ENABLED - Set to "false" to disable (default: true)
# MIN_RELEVANCE_SCORE - Minimum score for context (default: 5.0)
# MAX_CONTEXTS - Maximum number of contexts to retrieve (default: 10)
#
# Load configuration if exists
CONFIG_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/context-recall-config.env"
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
fi
# Default values
API_URL="${CLAUDE_API_URL:-http://localhost:8000}"
ENABLED="${CONTEXT_RECALL_ENABLED:-true}"
MIN_SCORE="${MIN_RELEVANCE_SCORE:-5.0}"
MAX_ITEMS="${MAX_CONTEXTS:-10}"
# Exit early if disabled
if [ "$ENABLED" != "true" ]; then
exit 0
fi
# Detect project ID from git repo if not set
if [ -z "$CLAUDE_PROJECT_ID" ]; then
# Try to get from git config
PROJECT_ID=$(git config --local claude.projectid 2>/dev/null)
if [ -z "$PROJECT_ID" ]; then
# Try to derive from git remote URL
GIT_REMOTE=$(git config --get remote.origin.url 2>/dev/null)
if [ -n "$GIT_REMOTE" ]; then
# Hash the remote URL to create a consistent ID
PROJECT_ID=$(echo -n "$GIT_REMOTE" | md5sum | cut -d' ' -f1)
fi
fi
else
PROJECT_ID="$CLAUDE_PROJECT_ID"
fi
# Exit if no project ID available
if [ -z "$PROJECT_ID" ]; then
# Silent exit - no context available
exit 0
fi
# Exit if no JWT token
if [ -z "$JWT_TOKEN" ]; then
exit 0
fi
# Build API request URL
RECALL_URL="${API_URL}/api/conversation-contexts/recall"
QUERY_PARAMS="project_id=${PROJECT_ID}&limit=${MAX_ITEMS}&min_relevance_score=${MIN_SCORE}"
# Fetch context from API (with timeout and error handling)
CONTEXT_RESPONSE=$(curl -s --max-time 3 \
"${RECALL_URL}?${QUERY_PARAMS}" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "Accept: application/json" 2>/dev/null)
# Check if request was successful
if [ $? -ne 0 ] || [ -z "$CONTEXT_RESPONSE" ]; then
# Silent failure - API unavailable
exit 0
fi
# Parse and format context (expects JSON array of context objects)
# Example response: [{"title": "...", "dense_summary": "...", "relevance_score": 8.5}, ...]
CONTEXT_COUNT=$(echo "$CONTEXT_RESPONSE" | grep -o '"id"' | wc -l)
if [ "$CONTEXT_COUNT" -gt 0 ]; then
echo "<!-- Context Recall: Retrieved $CONTEXT_COUNT relevant context(s) -->"
echo ""
echo "## 📚 Previous Context"
echo ""
echo "The following context has been automatically recalled from previous sessions:"
echo ""
# Extract and format each context entry
# Note: This uses simple text parsing. For production, consider using jq if available.
echo "$CONTEXT_RESPONSE" | python3 -c "
import sys, json
try:
contexts = json.load(sys.stdin)
if isinstance(contexts, list):
for i, ctx in enumerate(contexts, 1):
title = ctx.get('title', 'Untitled')
summary = ctx.get('dense_summary', '')
score = ctx.get('relevance_score', 0)
ctx_type = ctx.get('context_type', 'unknown')
print(f'### {i}. {title} (Score: {score}/10)')
print(f'*Type: {ctx_type}*')
print()
print(summary)
print()
print('---')
print()
except:
pass
" 2>/dev/null
echo ""
echo "*This context was automatically injected to help maintain continuity across sessions.*"
echo ""
fi
# Exit successfully
exit 0