app
adom-vscode-macos
Public Made by Adomby adom
macOS Hydrogen line of adom-vscode: the same CLI + VS Code extension (same extension id, same :8821 API) built natively for the arm64 Linux workspace Hydrogen runs on a Mac, minus the AI title bar (Hydrogen's agent bar and AI accounts popup own the title bar there). Installs over adom/adom-vscode; Hydrogen keeps this line registered. Upstream: adom-inc/adom-vscode.
main
#!/usr/bin/env python3
"""Claude usage in the title bar: 5-hour session, weekly, and the weekly model buckets that
apply to your plan, as percent used. Reads the Claude Code sign-in in ~/.claude/.credentials.json
and asks the same usage endpoint the Claude Code CLI shows in /usage. Asks the provider at most once every three minutes, pauses while the window is hidden, retries at 5, 15, 45 s on errors. Click the slot to cycle the views (rows, one number, a ring, a pair, all numbers, all rings)."""
import json, os, sys, time
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
from importlib.machinery import SourceFileLoader
marks = SourceFileLoader('hwmarks', os.path.join(os.path.dirname(os.path.realpath(__file__)), 'hydrogen-widget-marks.py')).load_module()
lib = SourceFileLoader('hwlib', os.path.join(os.path.dirname(os.path.realpath(__file__)), 'hydrogen-widget-lib.py')).load_module()
def data():
if not os.path.exists(os.path.expanduser('~/.claude/.credentials.json')):
return {'error': 'sign in to Claude Code in this workspace'}
c = lib.read_json_if_changed('~/.claude/.credentials.json')
oa = c.get('claudeAiOauth') or c
tok = oa.get('accessToken')
if not tok: return {'error': 'not signed in to Claude Code'}
exp = oa.get('expiresAt') or 0
if exp and exp < time.time() * 1000:
# Do not spend a call on a token the file already says is expired; Claude Code refreshes
# it on its next run and read_json_if_changed picks the new file up.
e = Exception('token expired'); e.code = 401; raise e
u = lib.http_json('https://api.anthropic.com/api/oauth/usage', {'Authorization': 'Bearer ' + tok, 'anthropic-beta': 'oauth-2025-04-20', 'User-Agent': 'hydrogen-widget-claude-usage'})
bars = []
# The structured list is what Claude Code's own Usage panel draws: the session window, the
# weekly window, and every weekly limit scoped to a model (Fable, Opus, ...), each with the
# provider's severity. Fall back to the flat fields on an older response.
for lim in u.get('limits') or []:
kind = lim.get('kind'); pct = lim.get('percent')
if pct is None: continue
if kind == 'session': label = '5h'
elif kind == 'weekly_all': label = 'week'
elif kind == 'weekly_scoped':
scope = lim.get('scope') or {}; model = scope.get('model') or {}
label = model.get('display_name') or 'model'
else: label = kind or 'limit'
bars.append({'label': label, 'pct': pct, 'severity': lim.get('severity') or 'normal'})
if not bars:
for label, key in (('5h', 'five_hour'), ('week', 'seven_day')):
v = (u.get(key) or {}).get('utilization')
if v is not None: bars.append({'label': label, 'pct': v, 'severity': 'normal'})
for k, v in u.items():
if k.startswith('seven_day_') and isinstance(v, dict) and v.get('utilization') is not None:
bars.append({'label': k[len('seven_day_'):].replace('_', ' '), 'pct': v['utilization'], 'severity': 'normal'})
return {'items': bars}
RENDER = r"""(d.error?`<span class="err">${d.error}</span>`:(d.items||[]).map(b=>bar(b.label,b.pct,b.severity)).join(''))"""
lib.serve('Claude usage', data, RENDER, 180000, mark=marks.MARKS['claude'], default_view='nums')