← Commit history
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.68: tall layout never clips: natural-width columns with the bar taking the rest, tall widths set in the manifest, and the page re-renders on its own resize event.+ v1.1.67: each widget names its own page (docs: widgets/README.md, shipped with the package) so the Hydrogen Widgets pulldown row links to what it shows, its manifest and files, and how to make your own.  v1.1.66: widget pages have two layouts chosen by the slot height: rows stacked in the full Title Bar (like the meter), one horizontal row when it is compact.
VERSION+1−1
@@ -1 +1 @@-1.1.67+1.1.68
bin/adom-vscode
⋯ 1 unchanged line ⋯
bin/hydrogen-widget-claude-usage

  
bin/hydrogen-widget-codex-usage

  
bin/hydrogen-widget-lib.py+13−5
@@ -30,20 +30,28 @@ html,body{margin:0;height:100%%;background:transparent;color:#e6ebef;font-family   .mark{width:clamp(10px,55vh,17px);height:clamp(10px,55vh,17px)} } @media (min-height:34px){+  /* Tall: rows stacked. Columns take their natural width (label, value) and the bar takes the+     rest, so nothing is ever clipped whatever the slot width; a long label is trimmed with an+     ellipsis instead of pushing the value out of view. */   .w{font-size:9px;line-height:1;padding:2px 6px}-  .rows{flex-direction:column;align-items:stretch;justify-content:center;gap:2px}-  .row{display:grid;grid-template-columns:2.8em 1fr 2.6em;gap:5px}-  .lbl{font-size:7.5px}.bar{width:auto;height:5px}.v{font-size:9px}-  .big{font-size:15px}.err{font-size:9px}+  .rows{flex-direction:column;align-items:stretch;justify-content:center;gap:2px;min-width:0}+  .row{display:grid;grid-template-columns:auto minmax(14px,1fr) auto;align-items:center;gap:4px;min-width:0}+  .lbl{font-size:7.5px;max-width:5.5em;overflow:hidden;text-overflow:ellipsis}.bar{width:auto;height:5px}.v{font-size:9px;min-width:0}+  .big{font-size:15px}.err{font-size:9px;white-space:normal;line-height:1.1} }+@media (max-height:33px){ .err{overflow:hidden;text-overflow:ellipsis;max-width:100%%} } </style><body><div class="w"><span class="mark" style="color:%(mark_color)s">%(mark_svg)s</span><div class="rows" id="w">%(title)s…</div></div> <script> const R=%(refresh_ms)d; function bar(l,p,sev){const c=(sev==='critical'||p>=90)?'hot':(sev==='warning'||p>=70)?'warn':'';return `<span class="row"><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></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>';}}+function render(d){document.getElementById('w').innerHTML=%(render_js)s;}+async function tick(){try{const r=await fetch('/data.json',{cache:'no-store'});const d=await r.json();window.__last=d;render(d);}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();}}); tick();if(!document.hidden)arm();+/* The slot resizes when the Title Bar goes compact or tall; the iframe's own window gets the resize event and the+   height media queries above re-evaluate. Re-render too, for widgets whose render depends on the size. */+let rz=null;window.addEventListener('resize',()=>{clearTimeout(rz);rz=setTimeout(()=>{if(window.__last)render(window.__last);},80);}); </script></body>"""  def serve(title, data_fn, render_js, refresh_ms=60000, mark=None):
bin/hydrogen-widget-marks.py

  
hydrogen-widget.json+4−2
@@ -16,7 +16,8 @@         "url": "/",         "timeout_seconds": 60       },-      "docs": "widgets/README.md"+      "docs": "widgets/README.md",+      "width_tall": 175     },     {       "id": "codex-usage",@@ -33,7 +34,8 @@         "url": "/",         "timeout_seconds": 60       },-      "docs": "widgets/README.md"+      "docs": "widgets/README.md",+      "width_tall": 135     }   ] }
install.sh

  
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-vscode",-  "version": "1.1.67",+  "version": "1.1.68",   "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.67",+  "version": "1.1.68",   "license": "PROPRIETARY",   "visibility": "public",   "hero": {@@ -141,4 +141,4 @@     "adom-vscode-extensions",     "adom-vscode-modes"   ]-}\ No newline at end of file+}