#!/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()