Skip to content

Commit 22875c2

Browse files
committed
Restore mini_copilot/login.py as it is required by auth command
1 parent 5daa638 commit 22875c2

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

mini_copilot/login.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
import json
3+
import sys
4+
import time
5+
from datetime import datetime, timezone
6+
from pathlib import Path
7+
8+
import requests
9+
10+
CONFIG_PATH = Path.home() / ".config" / "mini-copilot" / "config.json"
11+
GITHUB_CLIENT_ID = "01ab8ac9400c4e429b23" # VSCode's client ID
12+
13+
14+
def get_device_code():
15+
resp = requests.post(
16+
"https://github.com/login/device/code",
17+
headers={"Accept": "application/json", "Content-Type": "application/json"},
18+
json={"client_id": GITHUB_CLIENT_ID, "scope": "read:user repo"},
19+
)
20+
resp.raise_for_status()
21+
data = resp.json()
22+
print(f"\n➡️ Visit: {data['verification_uri']}")
23+
print(f"➡️ Enter code: {data['user_code']}\n")
24+
return data
25+
26+
27+
def poll_for_access_token(device_code, interval=5):
28+
while True:
29+
time.sleep(interval)
30+
resp = requests.post(
31+
"https://github.com/login/oauth/access_token",
32+
headers={"Accept": "application/json", "Content-Type": "application/json"},
33+
json={
34+
"client_id": GITHUB_CLIENT_ID,
35+
"device_code": device_code,
36+
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
37+
},
38+
)
39+
resp.raise_for_status()
40+
data = resp.json()
41+
42+
if "access_token" in data:
43+
print("✅ GitHub OAuth token obtained.")
44+
return data["access_token"]
45+
elif data.get("error") == "authorization_pending":
46+
print("⏳ Waiting for user authorization...", end="\r")
47+
elif data.get("error") == "slow_down":
48+
interval += 5
49+
elif data.get("error") == "expired_token":
50+
raise RuntimeError("Device code expired. Please restart.")
51+
else:
52+
raise RuntimeError(f"OAuth error: {json.dumps(data)}")
53+
54+
55+
def main():
56+
try:
57+
device_data = get_device_code()
58+
github_token = poll_for_access_token(
59+
device_data["device_code"], device_data.get("interval", 5)
60+
)
61+
62+
config = {
63+
"github_token": github_token,
64+
"created_at": datetime.now(timezone.utc).isoformat(),
65+
}
66+
67+
CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
68+
CONFIG_PATH.write_text(json.dumps(config, indent=2))
69+
print(f"\n✅ Saved GitHub token to {CONFIG_PATH}")
70+
print("🚀 Now you can run 'mini-copilot' to start chatting.")
71+
except Exception as e:
72+
print(f"\n❌ Error: {e}", file=sys.stderr)
73+
sys.exit(1)
74+
75+
76+
if __name__ == "__main__":
77+
main()

0 commit comments

Comments
 (0)