clawd/scripts/claude-usage.py

84 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
Fetch Claude.ai usage limits by connecting to existing Chrome session.
Requires: pip install playwright
Usage: python3 claude-usage.py [--json]
"""
import asyncio
import json
import re
import sys
from playwright.async_api import async_playwright
CDP_URL = "http://127.0.0.1:9222" # Chrome DevTools Protocol
async def get_usage():
async with async_playwright() as p:
try:
# Connect to existing Chrome instance
browser = await p.chromium.connect_over_cdp(CDP_URL)
except Exception as e:
print(f"Error: Can't connect to Chrome at {CDP_URL}", file=sys.stderr)
print("Make sure Chrome is running with: --remote-debugging-port=9222", file=sys.stderr)
sys.exit(1)
# Get the default context (existing session with cookies)
context = browser.contexts[0] if browser.contexts else await browser.new_context()
page = await context.new_page()
try:
await page.goto("https://claude.ai/settings/usage", wait_until="networkidle", timeout=30000)
await page.wait_for_selector("text=Plan usage limits", timeout=10000)
content = await page.content()
# Parse usage data
usage = {}
# Current session
session_match = re.search(r'Current session.*?(\d+)%\s*used', content, re.DOTALL)
if session_match:
usage['session_percent'] = int(session_match.group(1))
reset_match = re.search(r'Resets in\s*(\d+)\s*hr\s*(\d+)\s*min', content)
if reset_match:
usage['session_resets_hr'] = int(reset_match.group(1))
usage['session_resets_min'] = int(reset_match.group(2))
# Weekly limits - All models
weekly_match = re.search(r'All models.*?(\d+)%\s*used', content, re.DOTALL)
if weekly_match:
usage['weekly_percent'] = int(weekly_match.group(1))
weekly_reset_match = re.search(r'Resets\s*(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s*(\d+:\d+\s*[AP]M)', content)
if weekly_reset_match:
usage['weekly_resets'] = f"{weekly_reset_match.group(1)} {weekly_reset_match.group(2)}"
# Sonnet only
sonnet_match = re.search(r'Sonnet only.*?(\d+)%\s*used', content, re.DOTALL)
if sonnet_match:
usage['sonnet_percent'] = int(sonnet_match.group(1))
return usage
except Exception as e:
print(f"Error fetching usage: {e}", file=sys.stderr)
sys.exit(1)
finally:
await page.close()
def main():
usage = asyncio.run(get_usage())
if "--json" in sys.argv:
print(json.dumps(usage))
else:
print(f"📊 Claude.ai Usage")
print(f" Session: {usage.get('session_percent', '?')}% (resets in {usage.get('session_resets_hr', '?')}h {usage.get('session_resets_min', '?')}m)")
print(f" Weekly: {usage.get('weekly_percent', '?')}% (resets {usage.get('weekly_resets', '?')})")
print(f" Sonnet: {usage.get('sonnet_percent', '?')}%")
if __name__ == "__main__":
main()