forked from stomde/copilot-sdk-STOMA.-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpr_visualization.py
More file actions
161 lines (132 loc) · 4.83 KB
/
pr_visualization.py
File metadata and controls
161 lines (132 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/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"""
<context>
You are analyzing pull requests for the GitHub repository: {owner}/{repo_name}
The current working directory is: {os.getcwd()}
</context>
<instructions>
- 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
</instructions>
"""
}
)
# 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()