feat: Complete sync of all Claude Code CLI upgrades
- Add all 21 commands (clawd, ralph, prometheus*, dexto*) - Add all hooks (intelligent-router, clawd-*, prometheus-wrapper, unified-integration-v2) - Add skills (ralph, prometheus master) - Add MCP servers (registry.json, manager.sh) - Add plugins directory with marketplaces - Add health-check.sh and aliases.sh scripts - Complete repository synchronization with local ~/.claude/ Total changes: 100+ new files added All integrations now fully backed up in repository 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
393
hooks/unified-integration.sh
Executable file
393
hooks/unified-integration.sh
Executable file
@@ -0,0 +1,393 @@
|
||||
#!/bin/bash
|
||||
# Claude Code Unified Integration Hook
|
||||
# Auto-triggers Ralph Orchestrator, ARC Protocol, and manages claude-mem
|
||||
# ALWAYS-ON MODE - Ralph runs continuously and orchestrates all tasks
|
||||
#
|
||||
# Architecture:
|
||||
# Claude Code (User) -> Hook -> Ralph Orchestrator (ALWAYS-ON)
|
||||
# |
|
||||
# +-> ARC Protocol Workers (parallel execution)
|
||||
# +-> claude-mem (persistent memory)
|
||||
# +-> Multiple AI Backends (Claude, Gemini, etc.)
|
||||
#
|
||||
# Environment Variables:
|
||||
# RALPH_MODE - "always" (default), "agents", "off"
|
||||
# RALPH_BACKEND - "claude" (default), "kiro", "gemini", "opencode"
|
||||
# RALPH_PRESET - "claude-code" (default), "feature", "tdd-red-green", etc.
|
||||
# ARC_ENABLED - "true" (default) to enable ARC Protocol workers
|
||||
# CLAUDE_MEM_ENABLED - "true" (default) to enable claude-mem memory
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ============================================================================
|
||||
# CONFIGURATION
|
||||
# ============================================================================
|
||||
|
||||
CLAUDE_DIR="${HOME}/.claude"
|
||||
RALPH_DIR="${CLAUDE_DIR}/ralph-integration"
|
||||
ARC_DIR="${RALPH_DIR}/arc"
|
||||
LOG_DIR="${RALPH_DIR}/logs"
|
||||
|
||||
# Ralph State Files
|
||||
RALPH_LOCK_FILE="${RALPH_DIR}/ralph.lock"
|
||||
RALPH_PID_FILE="${RALPH_DIR}/ralph.pid"
|
||||
RALPH_LOG_FILE="${LOG_DIR}/ralph.log"
|
||||
RALPH_CONFIG="${RALPH_DIR}/ralph.yml"
|
||||
|
||||
# ARC State Files
|
||||
ARC_LOCK_FILE="${RALPH_DIR}/arc.lock"
|
||||
ARC_PID_FILE="${RALPH_DIR}/arc.pid"
|
||||
ARC_LOG_FILE="${LOG_DIR}/arc.log"
|
||||
ARC_CONFIG="${ARC_DIR}/.arc/STATE.md"
|
||||
|
||||
# Integration Log
|
||||
INTEGRATION_LOG="${LOG_DIR}/integration.log"
|
||||
|
||||
# Default Settings (override via environment variables)
|
||||
RALPH_MODE="${RALPH_MODE:-always}"
|
||||
RALPH_BACKEND="${RALPH_BACKEND:-claude}"
|
||||
RALPH_PRESET="${RALPH_PRESET:-claude-code}"
|
||||
ARC_ENABLED="${ARC_ENABLED:-true}"
|
||||
CLAUDE_MEM_ENABLED="${CLAUDE_MEM_ENABLED:-true}"
|
||||
|
||||
# Maximum Ralph iterations
|
||||
RALPH_MAX_ITERATIONS="${RALPH_MAX_ITERATIONS:-100}"
|
||||
|
||||
# Create directories
|
||||
mkdir -p "${RALPH_DIR}" "${LOG_DIR}" "${ARC_DIR}"
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
local level="$1"
|
||||
shift
|
||||
echo "[$(date -u +"%Y-%m-%d %H:%M:%S UTC")] [${level}] $*" | tee -a "${INTEGRATION_LOG}"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# INPUT PROCESSING
|
||||
# ============================================================================
|
||||
|
||||
# Read hook input from stdin
|
||||
HOOK_INPUT=$(cat)
|
||||
USER_PROMPT=$(echo "$HOOK_INPUT" | jq -r '.prompt // empty' 2>/dev/null || echo "")
|
||||
|
||||
# Fallback: if no JSON input, use first argument
|
||||
if [[ -z "$USER_PROMPT" && $# -gt 0 ]]; then
|
||||
USER_PROMPT="$1"
|
||||
fi
|
||||
|
||||
log INFO "Unified integration triggered"
|
||||
log INFO "Mode: ${RALPH_MODE}"
|
||||
log INFO "Prompt: ${USER_PROMPT:0:100}..."
|
||||
|
||||
# ============================================================================
|
||||
# RALPH ORCHESTRATOR INTEGRATION
|
||||
# ============================================================================
|
||||
|
||||
start_ralph() {
|
||||
local prompt="$1"
|
||||
|
||||
# Check if Ralph is already running
|
||||
if [[ -f "$RALPH_LOCK_FILE" ]]; then
|
||||
local lock_pid
|
||||
lock_pid=$(cat "$RALPH_LOCK_FILE" 2>/dev/null || echo "")
|
||||
if [[ -n "$lock_pid" ]] && kill -0 "$lock_pid" 2>/dev/null; then
|
||||
log INFO "Ralph already running (PID: ${lock_pid})"
|
||||
return 0
|
||||
else
|
||||
log WARN "Ralph lock file exists but process dead, cleaning up"
|
||||
rm -f "$RALPH_LOCK_FILE" "$RALPH_PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create Ralph configuration
|
||||
create_ralph_config
|
||||
|
||||
# Start Ralph in background
|
||||
log INFO "Starting Ralph Orchestrator..."
|
||||
nohup ralph run \
|
||||
-c "$RALPH_CONFIG" \
|
||||
-p "$prompt" \
|
||||
--max-iterations "$RALPH_MAX_ITERATIONS" \
|
||||
--no-tui \
|
||||
>> "$RALPH_LOG_FILE" 2>&1 &
|
||||
|
||||
local ralph_pid=$!
|
||||
echo "$ralph_pid" > "$RALPH_PID_FILE"
|
||||
echo "$ralph_pid" > "$RALPH_LOCK_FILE"
|
||||
|
||||
log INFO "Ralph started (PID: ${ralph_pid})"
|
||||
log INFO "Config: ${RALPH_CONFIG}"
|
||||
log INFO "Log: ${RALPH_LOG_FILE}"
|
||||
|
||||
# Notify user
|
||||
echo "🤖 Ralph Orchestrator: ACTIVE" >&2
|
||||
echo " PID: ${ralph_pid}" >&2
|
||||
echo " Mode: ${RALPH_MODE}" >&2
|
||||
echo " Monitor: tail -f ${RALPH_LOG_FILE}" >&2
|
||||
}
|
||||
|
||||
create_ralph_config() {
|
||||
# Determine preset to use
|
||||
local preset_config
|
||||
preset_config=$(get_ralph_preset "$RALPH_PRESET")
|
||||
|
||||
cat > "$RALPH_CONFIG" << EOF
|
||||
# Ralph Orchestrator Configuration for Claude Code
|
||||
# Auto-generated: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
# Mode: ${RALPH_MODE}
|
||||
# Backend: ${RALPH_BACKEND}
|
||||
|
||||
${preset_config}
|
||||
|
||||
# Claude Code Integration Settings
|
||||
cli:
|
||||
backend: "${RALPH_BACKEND}"
|
||||
prompt_mode: "arg"
|
||||
|
||||
# Integration with claude-mem
|
||||
memories:
|
||||
enabled: ${CLAUDE_MEM_ENABLED}
|
||||
inject: auto
|
||||
|
||||
# Integration with ARC Protocol
|
||||
arc_integration:
|
||||
enabled: ${ARC_ENABLED}
|
||||
bridge_path: "${ARC_DIR}/.agent/mcp/arc_mcp_server.py"
|
||||
dashboard_enabled: true
|
||||
|
||||
# Core Behaviors
|
||||
core:
|
||||
scratchpad: "${RALPH_DIR}/scratchpad.md"
|
||||
specs_dir: "./specs/"
|
||||
guardrails:
|
||||
- "Fresh context each iteration - scratchpad and memories are state"
|
||||
- "Don't assume 'not implemented' - search first"
|
||||
- "Backpressure is law - tests/typecheck/lint must pass"
|
||||
- "Use ARC workers for parallel execution when possible"
|
||||
- "Leverage claude-mem for context from previous sessions"
|
||||
EOF
|
||||
|
||||
log INFO "Ralph config created: ${RALPH_CONFIG}"
|
||||
}
|
||||
|
||||
get_ralph_preset() {
|
||||
local preset="$1"
|
||||
|
||||
case "$preset" in
|
||||
"claude-code")
|
||||
# Optimized preset for Claude Code integration
|
||||
cat << 'PRESET_EOF'
|
||||
# Claude Code Preset - Planner-Builder-Verifier Workflow
|
||||
event_loop:
|
||||
completion_promise: "TASK_COMPLETE"
|
||||
max_iterations: 100
|
||||
starting_event: "task.start"
|
||||
|
||||
hats:
|
||||
planner:
|
||||
name: "📋 Planner"
|
||||
description: "Break down tasks into actionable steps, identify dependencies"
|
||||
triggers: ["task.start", "plan.failed"]
|
||||
publishes: ["plan.ready", "task.complete"]
|
||||
instructions: |
|
||||
You are the Planner. Analyze the user's request and:
|
||||
1. Break down the task into clear, actionable steps
|
||||
2. Identify dependencies and parallelizable work
|
||||
3. Consider using ARC workers for parallel execution
|
||||
4. Search claude-mem for relevant context from past sessions
|
||||
5. Create a detailed plan before proceeding
|
||||
|
||||
builder:
|
||||
name: "🔨 Builder"
|
||||
description: "Implement code following the plan and best practices"
|
||||
triggers: ["plan.ready", "build.failed"]
|
||||
publishes: ["build.done", "build.blocked"]
|
||||
instructions: |
|
||||
You are the Builder. Implement the plan:
|
||||
1. Follow the plan created by the Planner
|
||||
2. Write clean, well-documented code
|
||||
3. Use ARC workers for parallel tasks when beneficial
|
||||
4. Run tests, linting, and type checking
|
||||
5. Only publish build.done when all quality gates pass
|
||||
|
||||
verifier:
|
||||
name: "✅ Verifier"
|
||||
description: "Verify implementation meets requirements and quality standards"
|
||||
triggers: ["build.done"]
|
||||
publishes: ["verification.passed", "verification.failed", "task.complete"]
|
||||
instructions: |
|
||||
You are the Verifier. Ensure quality:
|
||||
1. Review the implementation against the plan
|
||||
2. Verify all tests pass
|
||||
3. Check for edge cases and error handling
|
||||
4. Ensure code follows best practices
|
||||
5. Store lessons learned in memories for future sessions
|
||||
PRESET_EOF
|
||||
;;
|
||||
"autonomous")
|
||||
# Fully autonomous mode
|
||||
cat << 'PRESET_EOF'
|
||||
# Autonomous Mode - Single Hat with Full Autonomy
|
||||
event_loop:
|
||||
completion_promise: "TASK_COMPLETE"
|
||||
max_iterations: 150
|
||||
|
||||
core:
|
||||
guardrails:
|
||||
- "You are fully autonomous - plan, execute, and verify independently"
|
||||
- "Use ARC workers for all parallelizable tasks"
|
||||
- "Leverage memories extensively for context"
|
||||
- "Iterate until the task is completely done"
|
||||
PRESET_EOF
|
||||
;;
|
||||
*)
|
||||
# Default/feature preset
|
||||
cat << 'PRESET_EOF'
|
||||
# Default Feature Development Preset
|
||||
event_loop:
|
||||
completion_promise: "TASK_COMPLETE"
|
||||
max_iterations: 100
|
||||
PRESET_EOF
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# ARC PROTOCOL INTEGRATION
|
||||
# ============================================================================
|
||||
|
||||
start_arc() {
|
||||
if [[ "$ARC_ENABLED" != "true" ]]; then
|
||||
log INFO "ARC Protocol disabled"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if ARC is already running
|
||||
if [[ -f "$ARC_LOCK_FILE" ]]; then
|
||||
local lock_pid
|
||||
lock_pid=$(cat "$ARC_LOCK_FILE" 2>/dev/null || echo "")
|
||||
if [[ -n "$lock_pid" ]] && kill -0 "$lock_pid" 2>/dev/null; then
|
||||
log INFO "ARC already running (PID: ${lock_pid})"
|
||||
return 0
|
||||
else
|
||||
log WARN "ARC lock file exists but process dead, cleaning up"
|
||||
rm -f "$ARC_LOCK_FILE" "$ARC_PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup ARC directory
|
||||
setup_arc_directory
|
||||
|
||||
# Start ARC dashboard
|
||||
log INFO "Starting ARC Protocol..."
|
||||
cd "$ARC_DIR"
|
||||
|
||||
# Start the ARC dashboard in background
|
||||
nohup python3 ./dash >> "$ARC_LOG_FILE" 2>&1 &
|
||||
local arc_pid=$!
|
||||
echo "$arc_pid" > "$ARC_PID_FILE"
|
||||
echo "$arc_pid" > "$ARC_LOCK_FILE"
|
||||
|
||||
log INFO "ARC started (PID: ${arc_pid})"
|
||||
log INFO "Dashboard: http://localhost:37373"
|
||||
|
||||
echo "🚀 ARC Protocol: ACTIVE" >&2
|
||||
echo " PID: ${arc_pid}" >&2
|
||||
echo " Dashboard: http://localhost:37373" >&2
|
||||
}
|
||||
|
||||
setup_arc_directory() {
|
||||
# Create .arc structure if it doesn't exist
|
||||
mkdir -p "${ARC_DIR}/.arc/"{planning,archive,templates}
|
||||
|
||||
# Initialize ARC state
|
||||
cat > "$ARC_CONFIG" << EOF
|
||||
# ARC Protocol State
|
||||
# Initialized: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
|
||||
**Status:** Active
|
||||
**Mode:** Integrated with Ralph Orchestrator
|
||||
**Workspace:** ${ARC_DIR}
|
||||
|
||||
## Integration
|
||||
|
||||
This ARC instance is managed by Ralph Orchestrator.
|
||||
All worker dispatch and coordination happens through Ralph.
|
||||
|
||||
## Available Commands
|
||||
|
||||
- Check status: cat ${ARC_CONFIG}
|
||||
- View logs: tail -f ${ARC_LOG_FILE}
|
||||
- Stop integration: kill \$(cat ${ARC_LOCK_FILE})
|
||||
EOF
|
||||
|
||||
log INFO "ARC directory initialized: ${ARC_DIR}"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# CLAUDE-MEM INTEGRATION
|
||||
# ============================================================================
|
||||
|
||||
check_claude_mem() {
|
||||
if [[ "$CLAUDE_MEM_ENABLED" != "true" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if claude-mem plugin is installed
|
||||
local mem_plugin="${CLAUDE_DIR}/plugins/cache/thedotmack/claude-mem"
|
||||
|
||||
if [[ -d "$mem_plugin" ]]; then
|
||||
log INFO "claude-mem plugin found"
|
||||
return 0
|
||||
else
|
||||
log WARN "claude-mem not installed"
|
||||
echo "📦 claude-mem: NOT INSTALLED" >&2
|
||||
echo " Install: /plugin marketplace add thedotmack/claude-mem" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN EXECUTION
|
||||
# ============================================================================
|
||||
|
||||
main() {
|
||||
# Exit if disabled
|
||||
if [[ "$RALPH_MODE" == "off" ]]; then
|
||||
log INFO "Integration disabled (RALPH_MODE=off)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Determine if we should trigger
|
||||
local should_trigger=false
|
||||
|
||||
case "$RALPH_MODE" in
|
||||
"always")
|
||||
should_trigger=true
|
||||
;;
|
||||
"agents")
|
||||
# Detect agent or development keywords
|
||||
if echo "$USER_PROMPT" | grep -qiE "build|create|implement|develop|fix|add|refactor|optimize|write|generate|delegate|autonomous|agent|task|feature|pr"; then
|
||||
should_trigger=true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$should_trigger" == true ]]; then
|
||||
# Start components
|
||||
check_claude_mem
|
||||
start_arc
|
||||
start_ralph "$USER_PROMPT"
|
||||
|
||||
log INFO "Integration complete"
|
||||
else
|
||||
log INFO "Skipped (no trigger keywords)"
|
||||
fi
|
||||
|
||||
# Always exit immediately (non-blocking)
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user