Add Ralph CLI verification to verify-claude-setup.sh
Changes: - Add section #8: Ralph CLI Check (Advanced - Optional) - Verify Ralph CLI installation and version - Check Ralph auto-trigger hook existence and permissions - Verify hooks.json Ralph configuration - Check ralph-config.env environment file - Update Summary section number from #8 to #9 The verification script now covers all 3 auto-triggering systems: 1. PROACTIVELY agents (built-in to agent definitions) 2. Ralph CLI (optional autonomous looping) 3. Hooks-based event triggers Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,237 +1,282 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
################################################################################
|
################################################################################
|
||||||
# Claude Code Setup Verification Script
|
# Claude Code Setup Verification Script
|
||||||
# Checks if all customizations are properly installed
|
# Checks if all customizations are properly installed
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
BLUE='\033[0;34m'
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
CLAUDE_DIR="$HOME/.claude"
|
CLAUDE_DIR="$HOME/.claude"
|
||||||
AGENTS_DIR="$CLAUDE_DIR/agents"
|
AGENTS_DIR="$CLAUDE_DIR/agents"
|
||||||
PLUGINS_DIR="$CLAUDE_DIR/plugins"
|
PLUGINS_DIR="$CLAUDE_DIR/plugins"
|
||||||
|
|
||||||
PASSED=0
|
PASSED=0
|
||||||
FAILED=0
|
FAILED=0
|
||||||
WARNINGS=0
|
WARNINGS=0
|
||||||
|
|
||||||
check_pass() {
|
check_pass() {
|
||||||
echo -e "${GREEN}✓${NC} $1"
|
echo -e "${GREEN}✓${NC} $1"
|
||||||
PASSED=$((PASSED+1))
|
PASSED=$((PASSED+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
check_fail() {
|
check_fail() {
|
||||||
echo -e "${RED}✗${NC} $1"
|
echo -e "${RED}✗${NC} $1"
|
||||||
FAILED=$((FAILED+1))
|
FAILED=$((FAILED+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
check_warn() {
|
check_warn() {
|
||||||
echo -e "${YELLOW}⚠${NC} $1"
|
echo -e "${YELLOW}⚠${NC} $1"
|
||||||
WARNINGS=$((WARNINGS+1))
|
WARNINGS=$((WARNINGS+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
check_info() {
|
check_info() {
|
||||||
echo -e "${BLUE}ℹ${NC} $1"
|
echo -e "${BLUE}ℹ${NC} $1"
|
||||||
}
|
}
|
||||||
|
|
||||||
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||||
echo -e "${BLUE}║ Claude Code Customizations - Verification ║${NC}"
|
echo -e "${BLUE}║ Claude Code Customizations - Verification ║${NC}"
|
||||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 1. Check directory structure
|
# 1. Check directory structure
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Directory Structure"
|
echo "Directory Structure"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
[ -d "$CLAUDE_DIR" ] && check_pass "Claude directory exists" || check_fail "Claude directory missing"
|
[ -d "$CLAUDE_DIR" ] && check_pass "Claude directory exists" || check_fail "Claude directory missing"
|
||||||
[ -d "$AGENTS_DIR" ] && check_pass "Agents directory exists" || check_fail "Agents directory missing"
|
[ -d "$AGENTS_DIR" ] && check_pass "Agents directory exists" || check_fail "Agents directory missing"
|
||||||
[ -d "$PLUGINS_DIR" ] && check_pass "Plugins directory exists" || check_fail "Plugins directory missing"
|
[ -d "$PLUGINS_DIR" ] && check_pass "Plugins directory exists" || check_fail "Plugins directory missing"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Agent Categories"
|
echo "Agent Categories"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
CATEGORIES=("engineering" "marketing" "product" "studio-operations" "project-management" "testing" "design" "bonus")
|
CATEGORIES=("engineering" "marketing" "product" "studio-operations" "project-management" "testing" "design" "bonus")
|
||||||
AGENT_COUNT=0
|
AGENT_COUNT=0
|
||||||
|
|
||||||
for category in "${CATEGORIES[@]}"; do
|
for category in "${CATEGORIES[@]}"; do
|
||||||
if [ -d "$AGENTS_DIR/$category" ]; then
|
if [ -d "$AGENTS_DIR/$category" ]; then
|
||||||
count=$(ls -1 "$AGENTS_DIR/$category"/*.md 2>/dev/null | wc -l)
|
count=$(ls -1 "$AGENTS_DIR/$category"/*.md 2>/dev/null | wc -l)
|
||||||
if [ $count -gt 0 ]; then
|
if [ $count -gt 0 ]; then
|
||||||
echo -e "${GREEN}✓${NC} $category: $count agents"
|
echo -e "${GREEN}✓${NC} $category: $count agents"
|
||||||
AGENT_COUNT=$((AGENT_COUNT + count))
|
AGENT_COUNT=$((AGENT_COUNT + count))
|
||||||
else
|
else
|
||||||
check_warn "$category: directory exists but no agents"
|
check_warn "$category: directory exists but no agents"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
check_fail "$category: directory missing"
|
check_fail "$category: directory missing"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
check_info "Total agents: $AGENT_COUNT"
|
check_info "Total agents: $AGENT_COUNT"
|
||||||
|
|
||||||
# 2. Check configuration files
|
# 2. Check configuration files
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Configuration Files"
|
echo "Configuration Files"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
[ -f "$CLAUDE_DIR/settings.json" ] && check_pass "settings.json exists" || check_fail "settings.json missing"
|
[ -f "$CLAUDE_DIR/settings.json" ] && check_pass "settings.json exists" || check_fail "settings.json missing"
|
||||||
[ -f "$CLAUDE_DIR/settings.local.json" ] && check_pass "settings.local.json exists" || check_fail "settings.local.json missing"
|
[ -f "$CLAUDE_DIR/settings.local.json" ] && check_pass "settings.local.json exists" || check_fail "settings.local.json missing"
|
||||||
[ -f "$PLUGINS_DIR/installed_plugins.json" ] && check_pass "installed_plugins.json exists" || check_fail "installed_plugins.json missing"
|
[ -f "$PLUGINS_DIR/installed_plugins.json" ] && check_pass "installed_plugins.json exists" || check_fail "installed_plugins.json missing"
|
||||||
[ -f "$PLUGINS_DIR/known_marketplaces.json" ] && check_pass "known_marketplaces.json exists" || check_fail "known_marketplaces.json missing"
|
[ -f "$PLUGINS_DIR/known_marketplaces.json" ] && check_pass "known_marketplaces.json exists" || check_fail "known_marketplaces.json missing"
|
||||||
|
|
||||||
# 3. Check MCP tools
|
# 3. Check MCP tools
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "MCP Tools"
|
echo "MCP Tools"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
if command -v npx &> /dev/null; then
|
if command -v npx &> /dev/null; then
|
||||||
check_pass "npx available"
|
check_pass "npx available"
|
||||||
|
|
||||||
# Check if @z_ai/mcp-server can be accessed
|
# Check if @z_ai/mcp-server can be accessed
|
||||||
if npx -y @z_ai/mcp-server --help &> /dev/null; then
|
if npx -y @z_ai/mcp-server --help &> /dev/null; then
|
||||||
check_pass "@z_ai/mcp-server accessible"
|
check_pass "@z_ai/mcp-server accessible"
|
||||||
else
|
else
|
||||||
check_warn "@z_ai/mcp-server not directly accessible (may download on first use)"
|
check_warn "@z_ai/mcp-server not directly accessible (may download on first use)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if @z_ai/coding-helper can be accessed
|
# Check if @z_ai/coding-helper can be accessed
|
||||||
if npx -y @z_ai/coding-helper --help &> /dev/null; then
|
if npx -y @z_ai/coding-helper --help &> /dev/null; then
|
||||||
check_pass "@z_ai/coding-helper accessible"
|
check_pass "@z_ai/coding-helper accessible"
|
||||||
else
|
else
|
||||||
check_warn "@z_ai/coding-helper not directly accessible (may download on first use)"
|
check_warn "@z_ai/coding-helper not directly accessible (may download on first use)"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
check_fail "npx not available - MCP tools may not work"
|
check_fail "npx not available - MCP tools may not work"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. Check plugins
|
# 4. Check plugins
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Plugins"
|
echo "Plugins"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
if [ -f "$PLUGINS_DIR/installed_plugins.json" ]; then
|
if [ -f "$PLUGINS_DIR/installed_plugins.json" ]; then
|
||||||
# Check if GLM plugins are registered
|
# Check if GLM plugins are registered
|
||||||
if grep -q "glm-plan-bug" "$PLUGINS_DIR/installed_plugins.json" 2>/dev/null; then
|
if grep -q "glm-plan-bug" "$PLUGINS_DIR/installed_plugins.json" 2>/dev/null; then
|
||||||
check_pass "glm-plan-bug plugin registered"
|
check_pass "glm-plan-bug plugin registered"
|
||||||
else
|
else
|
||||||
check_warn "glm-plan-bug plugin not registered"
|
check_warn "glm-plan-bug plugin not registered"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if grep -q "glm-plan-usage" "$PLUGINS_DIR/installed_plugins.json" 2>/dev/null; then
|
if grep -q "glm-plan-usage" "$PLUGINS_DIR/installed_plugins.json" 2>/dev/null; then
|
||||||
check_pass "glm-plan-usage plugin registered"
|
check_pass "glm-plan-usage plugin registered"
|
||||||
else
|
else
|
||||||
check_warn "glm-plan-usage plugin not registered"
|
check_warn "glm-plan-usage plugin not registered"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 5. Sample agent check
|
# 5. Sample agent check
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Agent Content Verification"
|
echo "Agent Content Verification"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
CRITICAL_AGENTS=(
|
CRITICAL_AGENTS=(
|
||||||
"engineering/test-writer-fixer.md"
|
"engineering/test-writer-fixer.md"
|
||||||
"engineering/frontend-developer.md"
|
"engineering/frontend-developer.md"
|
||||||
"marketing/tiktok-strategist.md"
|
"marketing/tiktok-strategist.md"
|
||||||
"product/sprint-prioritizer.md"
|
"product/sprint-prioritizer.md"
|
||||||
"project-management/studio-producer.md"
|
"project-management/studio-producer.md"
|
||||||
"project-management/project-shipper.md"
|
"project-management/project-shipper.md"
|
||||||
"project-management/experiment-tracker.md"
|
"project-management/experiment-tracker.md"
|
||||||
"design/whimsy-injector.md"
|
"design/whimsy-injector.md"
|
||||||
"bonus/studio-coach.md"
|
"bonus/studio-coach.md"
|
||||||
"bonus/agent-updater.md"
|
"bonus/agent-updater.md"
|
||||||
)
|
)
|
||||||
|
|
||||||
for agent in "${CRITICAL_AGENTS[@]}"; do
|
for agent in "${CRITICAL_AGENTS[@]}"; do
|
||||||
if [ -f "$AGENTS_DIR/$agent" ]; then
|
if [ -f "$AGENTS_DIR/$agent" ]; then
|
||||||
# Check file has content
|
# Check file has content
|
||||||
if [ -s "$AGENTS_DIR/$agent" ]; then
|
if [ -s "$AGENTS_DIR/$agent" ]; then
|
||||||
check_pass "$agent exists and has content"
|
check_pass "$agent exists and has content"
|
||||||
else
|
else
|
||||||
check_warn "$agent exists but is empty"
|
check_warn "$agent exists but is empty"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
check_warn "$agent missing"
|
check_warn "$agent missing"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# 6. Settings validation
|
# 6. Settings validation
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Settings Validation"
|
echo "Settings Validation"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
if [ -f "$CLAUDE_DIR/settings.json" ]; then
|
if [ -f "$CLAUDE_DIR/settings.json" ]; then
|
||||||
# Check if JSON is valid
|
# Check if JSON is valid
|
||||||
if python3 -m json.tool "$CLAUDE_DIR/settings.json" &> /dev/null; then
|
if python3 -m json.tool "$CLAUDE_DIR/settings.json" &> /dev/null; then
|
||||||
check_pass "settings.json is valid JSON"
|
check_pass "settings.json is valid JSON"
|
||||||
|
|
||||||
# Check for API token placeholder
|
# Check for API token placeholder
|
||||||
if grep -q "YOUR_API_TOKEN_HERE\|YOUR_TOKEN_HERE" "$CLAUDE_DIR/settings.json" 2>/dev/null; then
|
if grep -q "YOUR_API_TOKEN_HERE\|YOUR_TOKEN_HERE" "$CLAUDE_DIR/settings.json" 2>/dev/null; then
|
||||||
check_warn "API token not configured (still placeholder)"
|
check_warn "API token not configured (still placeholder)"
|
||||||
else
|
else
|
||||||
if grep -q "ANTHROPIC_AUTH_TOKEN" "$CLAUDE_DIR/settings.json" 2>/dev/null; then
|
if grep -q "ANTHROPIC_AUTH_TOKEN" "$CLAUDE_DIR/settings.json" 2>/dev/null; then
|
||||||
check_pass "ANTHROPIC_AUTH_TOKEN is set"
|
check_pass "ANTHROPIC_AUTH_TOKEN is set"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
check_fail "settings.json is not valid JSON"
|
check_fail "settings.json is not valid JSON"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 7. Sync Script Check
|
# 7. Sync Script Check
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Sync Script Check"
|
echo "Sync Script Check"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
if [ -f "$CLAUDE_DIR/sync-agents.sh" ]; then
|
if [ -f "$CLAUDE_DIR/sync-agents.sh" ]; then
|
||||||
check_pass "sync-agents.sh script exists"
|
check_pass "sync-agents.sh script exists"
|
||||||
if [ -x "$CLAUDE_DIR/sync-agents.sh" ]; then
|
if [ -x "$CLAUDE_DIR/sync-agents.sh" ]; then
|
||||||
check_pass "sync-agents.sh is executable"
|
check_pass "sync-agents.sh is executable"
|
||||||
else
|
else
|
||||||
check_warn "sync-agents.sh exists but is not executable"
|
check_warn "sync-agents.sh exists but is not executable"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
check_warn "sync-agents.sh not found (optional, for updating agents)"
|
check_warn "sync-agents.sh not found (optional, for updating agents)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 8. Summary
|
# 8. Ralph CLI Check (Advanced - Optional)
|
||||||
echo ""
|
echo ""
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
echo "Summary"
|
echo "Ralph CLI (Advanced - Optional)"
|
||||||
echo "═══════════════════════════════════════════════════════════"
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
if [ $FAILED -eq 0 ]; then
|
if command -v ralph &> /dev/null; then
|
||||||
echo -e "${GREEN}✓ All critical checks passed!${NC}"
|
check_pass "Ralph CLI is installed"
|
||||||
echo ""
|
RALPH_VERSION=$(ralph --version 2>/dev/null || echo "unknown")
|
||||||
echo "Passed: $PASSED"
|
check_info "Ralph version: $RALPH_VERSION"
|
||||||
echo "Warnings: $WARNINGS"
|
|
||||||
echo "Failed: $FAILED"
|
# Check Ralph hook
|
||||||
echo ""
|
if [ -f "$CLAUDE_DIR/hooks/ralph-auto-trigger.sh" ]; then
|
||||||
echo -e "${GREEN}Your Claude Code setup is ready to use!${NC}"
|
check_pass "Ralph auto-trigger hook exists"
|
||||||
exit 0
|
if [ -x "$CLAUDE_DIR/hooks/ralph-auto-trigger.sh" ]; then
|
||||||
else
|
check_pass "Ralph hook is executable"
|
||||||
echo -e "${RED}✗ Some checks failed${NC}"
|
else
|
||||||
echo ""
|
check_warn "Ralph hook exists but is not executable"
|
||||||
echo "Passed: $PASSED"
|
fi
|
||||||
echo "Warnings: $WARNINGS"
|
else
|
||||||
echo "Failed: $FAILED"
|
check_warn "Ralph hook not found (auto-trigger not configured)"
|
||||||
echo ""
|
fi
|
||||||
echo "Please fix the failed checks above."
|
|
||||||
exit 1
|
# Check hooks.json
|
||||||
fi
|
if [ -f "$CLAUDE_DIR/hooks.json" ]; then
|
||||||
|
if grep -q "ralph-auto-trigger" "$CLAUDE_DIR/hooks.json" 2>/dev/null; then
|
||||||
|
check_pass "hooks.json configured for Ralph"
|
||||||
|
else
|
||||||
|
check_warn "hooks.json exists but Ralph not configured"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_warn "hooks.json not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Ralph config
|
||||||
|
if [ -f "$CLAUDE_DIR/ralph-config.env" ]; then
|
||||||
|
check_pass "Ralph configuration file exists"
|
||||||
|
else
|
||||||
|
check_warn "ralph-config.env not found (environment not configured)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
check_info "Ralph CLI not installed (optional advanced feature)"
|
||||||
|
check_info "Install with: npm install -g @iannuttall/ralph"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 9. Summary
|
||||||
|
echo ""
|
||||||
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
echo "Summary"
|
||||||
|
echo "═══════════════════════════════════════════════════════════"
|
||||||
|
|
||||||
|
if [ $FAILED -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ All critical checks passed!${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Passed: $PASSED"
|
||||||
|
echo "Warnings: $WARNINGS"
|
||||||
|
echo "Failed: $FAILED"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Your Claude Code setup is ready to use!${NC}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Some checks failed${NC}"
|
||||||
|
echo ""
|
||||||
|
echo "Passed: $PASSED"
|
||||||
|
echo "Warnings: $WARNINGS"
|
||||||
|
echo "Failed: $FAILED"
|
||||||
|
echo ""
|
||||||
|
echo "Please fix the failed checks above."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user