app
adom-vscode
Public Made by Adomby adom
Let Claude, Codex and Kimi drive VS Code inside your Adom container
← Commit history
release 1.1.65
11 files changed
+31−12
README.md+2@@ -276,6 +276,8 @@ v1.1.20: /command returns errorCode command_not_found (HTTP 400) with did-you-me v1.1.21: event-driven tab census + Claude session identity (John 2026-09-03: never poll the iframes again). GET /tabs and the SSE stream GET /tabs/events publish the extension host's own tabGroups census on every change; POST /claude/session-start ingests the Claude SessionStart hook (id + transcript path, before the jsonl is flushed) and GET /claude/sessions lists it; POST /claude/open-session opens an existing conversation by id and confirms the bind (retagging sdk-cli transcripts, which the Claude extension otherwise declines). Capability markers in /health: tabs.list, tabs.events, claude.open-session, claude.session-start, claude.sessions. +v1.1.65: the Claude usage widget reads the structured limits list, so model-scoped weekly limits (Fable limit 93 percent) show with their own name and the provider severity colour, next to the session and weekly bars.+ v1.1.64: the usage widgets ask their provider at most once every three minutes, pause while the window is hidden, back off on errors (doubling to 15 minutes), and re-read the sign-in file only when it changes. v1.1.63: the Claude and Codex usage widgets carry their vendor marks (the launch bar artwork) so you can tell them apart at a glance, in the slot and in the Widgets pulldown.
VERSION+1−1@@ -1 +1 @@-1.1.64+1.1.65
bin/adom-vscode⋯ 1 unchanged line ⋯
bin/hydrogen-widget-claude-usage+23−6@@ -16,11 +16,28 @@ def data(): tok = oa.get('accessToken') if not tok: return {'error': 'not signed in to Claude Code'} 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'})- out = {'five_hour': (u.get('five_hour') or {}).get('utilization'), 'seven_day': (u.get('seven_day') or {}).get('utilization'), 'models': []}- for k, v in u.items():- if k.startswith('seven_day_') and isinstance(v, dict) and v.get('utilization') is not None:- out['models'].append({'name': k[len('seven_day_'):].replace('_', ' '), 'pct': v['utilization']})- return out+ 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 {'bars': bars} -RENDER = r"""(d.error?`<span class="err">${d.error}</span>`:bar('5h',d.five_hour??0)+bar('week',d.seven_day??0)+(d.models||[]).slice(0,1).map(m=>bar(m.name,m.pct)).join(''))"""+RENDER = r"""(d.error?`<span class="err">${d.error}</span>`:(d.bars||[]).map(b=>bar(b.label,b.pct,b.severity)).join(''))""" lib.serve('Claude usage', data, RENDER, 180000, mark=marks.MARKS['claude'])
bin/hydrogen-widget-codex-usagebin/hydrogen-widget-lib.py+1−1@@ -23,7 +23,7 @@ html,body{margin:0;height:100%%;background:transparent;color:#e6ebef;font-family </style><body><div class="w"><span class="mark" style="color:%(mark_color)s">%(mark_svg)s</span><div class="w" id="w" style="padding-left:0">%(title)s…</div></div> <script> const R=%(refresh_ms)d;-function bar(l,p){const c=p>=90?'hot':p>=70?'warn':'';return `<span class="lbl">${l}</span><span class="bar ${c}"><i style="width:${Math.max(0,Math.min(100,p))}%%"></i></span><span class="v">${Math.round(p)}%%</span>`;}+function bar(l,p,sev){const c=(sev==='critical'||p>=90)?'hot':(sev==='warning'||p>=70)?'warn':'';return `<span class="lbl">${l}</span><span class="bar ${c}"><i style="width:${Math.max(0,Math.min(100,p))}%%"></i></span><span class="v">${Math.round(p)}%%</span>`;} async function tick(){try{const r=await fetch('/data.json',{cache:'no-store'});const d=await r.json();document.getElementById('w').innerHTML=%(render_js)s;}catch(e){document.getElementById('w').innerHTML='<span class="err">no data</span>';}} let tm=null;function arm(){if(tm)return;tm=setInterval(tick,R);}function disarm(){if(tm){clearInterval(tm);tm=null;}} document.addEventListener('visibilitychange',()=>{if(document.hidden)disarm();else{tick();arm();}});
bin/hydrogen-widget-marks.pyhydrogen-widget.json+1−1@@ -6,7 +6,7 @@ "name": "Claude usage", "icon": "vendor:claude", "brief": "Your Claude limits at a glance: 5-hour session, weekly, and the weekly model bucket that applies, as percent used. Reads the Claude Code sign-in in this workspace.",- "width": 250,+ "width": 320, "install": "adom/adom-vscode", "launch": { "command": "hydrogen-widget-claude-usage", "port": 8931 }, "health": { "url": "/", "timeout_seconds": 60 }
install.shpackage.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-vscode",- "version": "1.1.64",+ "version": "1.1.65", "type": "app", "description": "CLI + VS Code extension that lets AI assistants and the Hydrogen Desktop frontend drive VS Code from inside an Adom container: open files, live get/set of any setting/theme/font (no reload), native streamed exec, a frontend event queue, container identity (hd/hw), api-key status/inject, extension query/update, modes, paste screenshots, and any VS Code command via a local HTTP API on port 8821 (with port-file fallback discovery).", "license": "PROPRIETARY",
page.json+2−2@@ -4,7 +4,7 @@ "slug": "adom-vscode", "title": "adom-vscode", "brief": "Let Claude, Codex and Kimi drive VS Code inside your Adom container",- "version": "1.1.64",+ "version": "1.1.65", "license": "PROPRIETARY", "visibility": "public", "hero": {@@ -141,4 +141,4 @@ "adom-vscode-extensions", "adom-vscode-modes" ]-}+}