#!/usr/bin/env python3 import subprocess import sys import os import re from copilot import CopilotClient # ============================================================================ # Git & GitHub Detection # ============================================================================ def is_git_repo(): try: subprocess.run( ["git", "rev-parse", "--git-dir"], check=True, capture_output=True ) return True except (subprocess.CalledProcessError, FileNotFoundError): return False def get_github_remote(): try: result = subprocess.run( ["git", "remote", "get-url", "origin"], check=True, capture_output=True, text=True ) remote_url = result.stdout.strip() # Handle SSH: git@github.com:owner/repo.git ssh_match = re.search(r"git@github\.com:(.+/.+?)(?:\.git)?$", remote_url) if ssh_match: return ssh_match.group(1) # Handle HTTPS: https://github.com/owner/repo.git https_match = re.search(r"https://github\.com/(.+/.+?)(?:\.git)?$", remote_url) if https_match: return https_match.group(1) return None except (subprocess.CalledProcessError, FileNotFoundError): return None def parse_args(): args = sys.argv[1:] if "--repo" in args: idx = args.index("--repo") if idx + 1 < len(args): return {"repo": args[idx + 1]} return {} def prompt_for_repo(): return input("Enter GitHub repo (owner/repo): ").strip() # ============================================================================ # Main Application # ============================================================================ def main(): print("šŸ” PR Age Chart Generator\n") # Determine the repository args = parse_args() repo = None if "repo" in args: repo = args["repo"] print(f"šŸ“¦ Using specified repo: {repo}") elif is_git_repo(): detected = get_github_remote() if detected: repo = detected print(f"šŸ“¦ Detected GitHub repo: {repo}") else: print("āš ļø Git repo found but no GitHub remote detected.") repo = prompt_for_repo() else: print("šŸ“ Not in a git repository.") repo = prompt_for_repo() if not repo or "/" not in repo: print("āŒ Invalid repo format. Expected: owner/repo") sys.exit(1) owner, repo_name = repo.split("/", 1) # Create Copilot client - no custom tools needed! client = CopilotClient(log_level="error") client.start() session = client.create_session( model="gpt-5", system_message={ "content": f""" You are analyzing pull requests for the GitHub repository: {owner}/{repo_name} The current working directory is: {os.getcwd()} - Use the GitHub MCP Server tools to fetch PR data - Use your file and code execution tools to generate charts - Save any generated images to the current working directory - Be concise in your responses """ } ) # Set up event handling def handle_event(event): if event["type"] == "assistant.message": print(f"\nšŸ¤– {event['data']['content']}\n") elif event["type"] == "tool.execution_start": print(f" āš™ļø {event['data']['toolName']}") session.on(handle_event) # Initial prompt - let Copilot figure out the details print("\nšŸ“Š Starting analysis...\n") session.send(prompt=f""" Fetch the open pull requests for {owner}/{repo_name} from the last week. Calculate the age of each PR in days. Then generate a bar chart image showing the distribution of PR ages (group them into sensible buckets like <1 day, 1-3 days, etc.). Save the chart as "pr-age-chart.png" in the current directory. Finally, summarize the PR health - average age, oldest PR, and how many might be considered stale. """) session.wait_for_idle() # Interactive loop print("\nšŸ’” Ask follow-up questions or type \"exit\" to quit.\n") print("Examples:") print(" - \"Expand to the last month\"") print(" - \"Show me the 5 oldest PRs\"") print(" - \"Generate a pie chart instead\"") print(" - \"Group by author instead of age\"") print() while True: user_input = input("You: ").strip() if user_input.lower() in ["exit", "quit"]: print("šŸ‘‹ Goodbye!") break if user_input: session.send(prompt=user_input) session.wait_for_idle() session.destroy() client.stop() if __name__ == "__main__": main()