Files
gh-timurkhakhalev-cc-plugin…/scripts/validate-agent-setup.py
2025-11-30 09:02:01 +08:00

270 lines
8.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
CLI Agent Setup Validation Script
This script checks if various AI coding CLI agents are properly installed,
configured, and authenticated for headless operation.
Usage:
python validate-agent-setup.py [agent_name]
If agent_name is provided, only that agent will be checked.
Otherwise, all available agents will be validated.
"""
import subprocess
import sys
import json
import os
from typing import Dict, List, Tuple, Optional
# Agent configuration
AGENTS = {
"claude": {
"commands": ["claude", "claude -p 'test'"],
"install_url": "https://claude.ai/install",
"auth_check": "claude auth status",
"description": "Anthropic Claude Code CLI"
},
"codex": {
"commands": ["codex", "codex exec 'test'"],
"install_url": "https://platform.openai.com/docs/cli",
"auth_check": "codex auth verify",
"description": "OpenAI Codex CLI"
},
"gemini": {
"commands": ["gemini", "gemini -p 'test'"],
"install_url": "https://geminicli.com/docs/installation",
"auth_check": "gemini auth status",
"description": "Google Gemini CLI"
},
"opencode": {
"commands": ["opencode", "opencode -p 'test'"],
"install_url": "https://github.com/opencode-ai/opencode",
"auth_check": "echo 'Check environment variables for API keys'",
"description": "OpenCode CLI (multi-provider)"
},
"qwen": {
"commands": ["qwen", "qwen -p 'test'"],
"install_url": "https://github.com/QwenLM/qwen-code",
"auth_check": "qwen auth status",
"description": "Alibaba Qwen Code CLI"
},
"droid": {
"commands": ["droid", "droid exec 'test'"],
"install_url": "https://docs.factory.ai/cli/installation",
"auth_check": "droid auth status",
"description": "Factory Droid CLI"
}
}
def run_command(cmd: str, timeout: int = 30) -> Tuple[int, str, str]:
"""Run a command and return exit code, stdout, stderr"""
try:
result = subprocess.run(
cmd.split() if isinstance(cmd, str) else cmd,
capture_output=True,
text=True,
timeout=timeout
)
return result.returncode, result.stdout, result.stderr
except subprocess.TimeoutExpired:
return -1, "", "Command timed out"
except Exception as e:
return -1, "", str(e)
def check_agent_installation(agent_name: str, config: Dict) -> Dict:
"""Check if an agent is properly installed"""
results = {
"agent": agent_name,
"description": config["description"],
"installed": False,
"version": None,
"auth_status": "unknown",
"basic_test": False,
"errors": [],
"recommendations": []
}
# Check if command exists
cmd = config["commands"][0]
exit_code, stdout, stderr = run_command(f"which {cmd}")
if exit_code != 0:
results["errors"].append(f"Command '{cmd}' not found in PATH")
results["recommendations"].append(f"Install from: {config['install_url']}")
return results
results["installed"] = True
results["version"] = stdout.strip() or "Unknown version"
# Check authentication
if "auth_check" in config:
exit_code, auth_stdout, auth_stderr = run_command(config["auth_check"])
if exit_code == 0:
results["auth_status"] = "authenticated"
else:
results["auth_status"] = "not_authenticated"
results["errors"].append(f"Authentication check failed: {auth_stderr}")
results["recommendations"].append("Run authentication command for this agent")
# Basic functionality test (try to get help)
exit_code, help_stdout, help_stderr = run_command(f"{cmd} --help", timeout=10)
if exit_code == 0:
results["basic_test"] = True
return results
def check_environment_requirements() -> Dict:
"""Check general environment requirements"""
results = {
"python_version": sys.version,
"working_directory": os.getcwd(),
"environment_variables": {},
"recommendations": []
}
# Check for common environment variables
env_vars = [
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
"GOOGLE_API_KEY",
"OPENAI_BASE_URL",
"CLAUDE_API_KEY"
]
for var in env_vars:
value = os.environ.get(var)
results["environment_variables"][var] = "SET" if value else "NOT_SET"
# Check git availability
exit_code, stdout, stderr = run_command("git --version")
if exit_code != 0:
results["recommendations"].append("Install git for better agent integration")
return results
def print_results(results: List[Dict], env_info: Dict, format_type: str = "table"):
"""Print validation results in specified format"""
if format_type == "json":
output = {
"environment": env_info,
"agents": results
}
print(json.dumps(output, indent=2))
return
# Table format
print("\n" + "="*80)
print("🤖 CLI AGENT SETUP VALIDATION")
print("="*80)
print(f"\n📁 Working Directory: {env_info['working_directory']}")
print(f"🐍 Python Version: {env_info['python_version'].split()[0]}")
print("\n🔑 Environment Variables:")
for var, status in env_info["environment_variables"].items():
status_icon = "" if status == "SET" else ""
print(f" {status_icon} {var}: {status}")
print("\n" + "="*80)
print("AGENT STATUS")
print("="*80)
for result in results:
agent = result["agent"]
description = result["description"]
# Status icons
install_icon = "" if result["installed"] else ""
auth_icon = "" if result["auth_status"] == "authenticated" else "" if result["auth_status"] == "not_authenticated" else "⚠️"
test_icon = "" if result["basic_test"] else ""
print(f"\n{install_icon} {agent.upper()}: {description}")
print(f" 📦 Installed: {'Yes' if result['installed'] else 'No'}")
print(f" 🔐 Auth Status: {result['auth_status']}")
print(f" 🧪 Basic Test: {'Pass' if result['basic_test'] else 'Fail'}")
if result["version"]:
print(f" 📋 Version: {result['version']}")
if result["errors"]:
print(" ❌ Errors:")
for error in result["errors"]:
print(f"{error}")
if result["recommendations"]:
print(" 💡 Recommendations:")
for rec in result["recommendations"]:
print(f"{rec}")
print("\n" + "="*80)
print("SUMMARY")
print("="*80)
installed_count = sum(1 for r in results if r["installed"])
auth_count = sum(1 for r in results if r["auth_status"] == "authenticated")
print(f"📦 Agents Installed: {installed_count}/{len(results)}")
print(f"🔐 Agents Authenticated: {auth_count}/{len(results)}")
if env_info["recommendations"]:
print("\n💡 General Recommendations:")
for rec in env_info["recommendations"]:
print(f"{rec}")
def main():
"""Main validation function"""
import argparse
parser = argparse.ArgumentParser(description="Validate CLI agent setup")
parser.add_argument("agent", nargs="?", choices=list(AGENTS.keys()),
help="Specific agent to check (default: all)")
parser.add_argument("--format", choices=["table", "json"], default="table",
help="Output format (default: table)")
parser.add_argument("--quiet", action="store_true",
help="Only show summary")
args = parser.parse_args()
# Check environment
env_info = check_environment_requirements()
# Check agents
if args.agent:
agents_to_check = {args.agent: AGENTS[args.agent]}
else:
agents_to_check = AGENTS
results = []
for agent_name, config in agents_to_check.items():
result = check_agent_installation(agent_name, config)
results.append(result)
if not args.quiet:
print(f"Checking {agent_name}...", end=" ")
if result["installed"]:
print("✅ Found")
else:
print("❌ Not found")
# Print results
if not args.quiet:
print_results(results, env_info, args.format)
else:
# Quiet summary
installed = sum(1 for r in results if r["installed"])
authenticated = sum(1 for r in results if r["auth_status"] == "authenticated")
print(f"Installed: {installed}/{len(results)} | Authenticated: {authenticated}/{len(results)}")
# Exit code based on results
if not any(r["installed"] for r in results):
sys.exit(2) # No agents installed
elif not all(r["installed"] for r in results):
sys.exit(1) # Some agents missing
else:
sys.exit(0) # All good
if __name__ == "__main__":
main()