← Commit history

0.5.35: hydrogen-widget skill (vendor icons, compact sizing, Title Bar), widget helper with marks

John Lauer ·dd80f68d4a ·1mo ago ·parent 8d54376
5 files changed +27−7
bin/hydrogen-widget-lib.py+5−3
@@ -19,7 +19,8 @@ html,body{margin:0;height:100%%;background:transparent;color:#e6ebef;font-family .v{font-variant-numeric:tabular-nums;min-width:2.4em;text-align:right} .big{font-size:clamp(9px,47vh,14px);font-weight:600;font-variant-numeric:tabular-nums} .err{color:#f0a060;font-size:clamp(7px,33vh,10px)}-</style><body><div class="w" id="w">%(title)s…</div>+.mark{display:inline-flex;flex:none;width:clamp(10px,55vh,17px);height:clamp(10px,55vh,17px)}.mark svg{width:100%%;height:100%%}+</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>`;}@@ -27,7 +28,8 @@ async function tick(){try{const r=await fetch('/data.json',{cache:'no-store'});c tick();setInterval(tick,R); </script></body>""" -def serve(title, data_fn, render_js, refresh_ms=60000):+def serve(title, data_fn, render_js, refresh_ms=60000, mark=None):+    mark = mark or {'svg': '', 'color': 'currentColor'}     port = int(os.environ.get('HYDROGEN_WIDGET_PORT') or (sys.argv[sys.argv.index('--port')+1] if '--port' in sys.argv else 8930))     cache = {'t': 0, 'v': {'error': 'starting'}}     lock = threading.Lock()@@ -46,7 +48,7 @@ def serve(title, data_fn, render_js, refresh_ms=60000):         def do_GET(self):             if self.path.startswith('/data.json'): self._send(200, 'application/json', json.dumps(data()).encode())             elif self.path.startswith('/health'): self._send(200, 'application/json', b'{"ok":true}')-            else: self._send(200, 'text/html; charset=utf-8', (PAGE % {'title': title, 'refresh_ms': refresh_ms, 'render_js': render_js}).encode())+            else: self._send(200, 'text/html; charset=utf-8', (PAGE % {'title': title, 'refresh_ms': refresh_ms, 'render_js': render_js, 'mark_svg': ('<svg viewBox="0 0 16 16">' + mark['svg'] + '</svg>') if mark['svg'] else '', 'mark_color': mark['color']}).encode())     srv = ThreadingHTTPServer(('127.0.0.1', port), H)     # Tell Hydrogen we are up (the health poll would find us anyway; this is the explicit handshake).     ctl = os.environ.get('ADOM_HD_CONTROL_URL'); wid = os.environ.get('HYDROGEN_WIDGET_ID')
bin/hydrogen-widget-marks.pyadded+6
@@ -0,0 +1,6 @@+"""Vendor marks, generated from browser/ai-titlebar.js (the AI launch bar): the same artwork+and colours users already know from the editor. Do not edit; regenerate."""+MARKS = {+  "claude": {"svg": '<g transform="scale(0.0645)"><path fill="currentColor" d="M52.4285 162.873L98.7844 136.879L99.5485 134.602L98.7844 133.334H96.4921L88.7237 132.862L62.2346 132.153L39.3113 131.207L17.0249 130.026L11.4214 128.844L6.2 121.873L6.7094 118.447L11.4214 115.257L18.171 115.847L33.0711 116.911L55.485 118.447L71.6586 119.392L95.728 121.873H99.5485L100.058 120.337L98.7844 119.392L97.7656 118.447L74.5877 102.732L49.4995 86.1905L36.3823 76.62L29.3779 71.7757L25.7854 67.1678L24.2572 57.2427L30.6511 50.1533L39.3113 50.7441L41.5205 51.3349L50.2643 58.0698L68.9853 72.4849L93.4359 90.4432L96.9848 93.3972L98.4111 92.3901L98.5808 91.6812L96.9848 88.9635L83.7836 65.0987L69.6647 40.8793L63.4406 30.8361L61.7427 24.8099C61.2334 22.3284 60.7241 20.2018 60.7241 17.6021L68.0084 7.71947L72.0871 6.41968L81.7658 7.71947L85.8446 11.2643L91.9174 25.1645L101.766 46.9043L117.001 76.6199L121.42 85.4033L123.799 93.5154L124.648 95.9969H126.176V94.5787L127.365 78.6265L129.574 59.1298L131.782 34.0801L132.461 26.9906L135.859 18.6603L142.763 13.0964L148.157 15.6961L152.575 21.9587L151.896 25.9761L149.176 43.4573L143.951 70.9977L140.554 89.4287H142.593L144.971 87.0654L154.31 74.7811L170.054 55.2844L177.128 47.4498L185.115 38.9012L190.34 34.7656H200.019L207.093 45.2049L203.865 56.0578L193.917 68.7554L185.624 79.4128L173.792 95.2905L166.378 108.089L167.057 109.096L168.755 108.919L195.445 103.207L209.812 100.607L227.07 97.6528L234.823 101.316L235.672 105.017L232.614 112.579L214.187 117.128L192.559 121.44L160.392 129.079L159.882 129.374L160.392 129.965L174.929 131.325L181.153 131.68H196.388L224.69 133.807L232.104 138.71L236.522 144.677L235.842 149.226L224.52 154.965L209.133 151.353L173.282 142.786L160.902 139.717H159.203V140.782L169.492 150.821L188.258 167.777L211.851 189.635L213.04 195.011L210.002 199.324L206.773 198.851L185.965 183.15L177.887 176.061L159.882 160.892H158.693V162.489L162.77 168.574L184.767 201.687L185.965 211.845L184.427 215.153L178.716 217.162L172.432 216.03L159.543 197.848L146.315 177.541L135.518 159.237L134.159 159.946L127.875 228.319L124.987 231.746L118.193 234.346L112.481 230.028L109.593 222.902L112.481 208.996L116.049 190.874L118.872 176.406L121.42 158.469L122.949 152.502L122.779 152.089L121.59 152.325L108.913 169.759L89.5688 195.898L74.3336 212.201L70.7659 213.68L64.4807 210.371L65.0692 204.581L68.6369 199.442L89.5688 172.831L102.077 156.409L110.28 146.883L110.11 145.522H109.593L54.1264 181.553L44.1084 182.913L39.8228 178.831L40.3322 172.24L42.3716 170.113L59.2917 158.469L52.4285 162.873Z"/></g>', "color": "#d97757"},+  "codex": {"svg": '<g transform="scale(0.6667)"><path fill="currentColor" d="M22.28 9.82a5.98 5.98 0 0 0-.52-4.91 6.05 6.05 0 0 0-6.51-2.9A6.07 6.07 0 0 0 4.98 4.18a5.98 5.98 0 0 0-4 2.9 6.05 6.05 0 0 0 .74 7.1 5.98 5.98 0 0 0 .51 4.91 6.05 6.05 0 0 0 6.51 2.9A5.98 5.98 0 0 0 13.26 24a6.06 6.06 0 0 0 5.77-4.21 5.99 5.99 0 0 0 4-2.9 6.06 6.06 0 0 0-.75-7.07zm-9.02 12.61a4.48 4.48 0 0 1-2.88-1.04l.14-.08 4.78-2.76a.79.79 0 0 0 .39-.68v-6.74l2.02 1.17a.07.07 0 0 1 .04.05v5.58a4.5 4.5 0 0 1-4.49 4.5zm-9.66-4.13a4.47 4.47 0 0 1-.54-3.01l.14.09 4.78 2.76a.77.77 0 0 0 .78 0l5.84-3.37v2.33a.08.08 0 0 1-.03.06l-4.83 2.79a4.5 4.5 0 0 1-6.14-1.65zM2.34 7.9a4.48 4.48 0 0 1 2.37-1.97v5.68a.77.77 0 0 0 .38.67l5.81 3.36-2.02 1.17a.08.08 0 0 1-.07 0l-4.83-2.79A4.5 4.5 0 0 1 2.34 7.9zm16.6 3.86l-5.84-3.37 2.02-1.17a.08.08 0 0 1 .07 0l4.83 2.79a4.49 4.49 0 0 1-.69 8.1v-5.68a.79.79 0 0 0-.39-.67zm2.01-3.02l-.14-.09-4.78-2.77a.78.78 0 0 0-.78 0L9.42 9.24V6.91a.07.07 0 0 1 .03-.06l4.83-2.79a4.5 4.5 0 0 1 6.68 4.66zM8.32 12.86l-2.02-1.16a.08.08 0 0 1-.04-.06V6.06a4.5 4.5 0 0 1 7.38-3.45l-.14.08-4.78 2.76a.79.79 0 0 0-.39.68zm1.1-2.37l2.6-1.5 2.6 1.5v3l-2.6 1.5-2.6-1.5z"/></g>', "color": "#e6ebef"},+}
package.json+1−1
@@ -4,7 +4,7 @@   "type": "bootstrap",   "title": "Adom Hydrogen (platform base)",   "brief": "Layer Hydrogen's workspace onto a standard Adom workstation.",-  "version": "0.5.34",+  "version": "0.5.35",   "description": "Hydrogen's PLATFORM-GENERIC workspace layer on top of adom/core. Installs adom/core for the full Adom ecosystem, then adds everything common to running inside Hydrogen on ANY platform: the runtime-neutral hydrogen-* skills and the generic editor configuration (Claude Code CLI + extension, VS Code settings, trusted domains). Platform-specific layers depend on THIS: adom/hydrogen-windows-bootstrap (WSL2), adom/hydrogen-mac-bootstrap, adom/hydrogen-ubuntu-bootstrap. The reference design other orgs copy to build their own bootstrap on adom/core.",   "org": "adom",   "tags": [
page.json+2−2
@@ -4,7 +4,7 @@   "type": "bootstrap",   "title": "Adom Hydrogen (platform base)",   "brief": "Layer Hydrogen's workspace onto a standard Adom workstation.",-  "version": "0.5.34",+  "version": "0.5.35",   "description": "Hydrogen's PLATFORM-GENERIC workspace layer on top of adom/core. Installs adom/core for the full Adom ecosystem, then adds everything common to running inside Hydrogen on ANY platform: the runtime-neutral hydrogen-* skills and the generic editor configuration (Claude Code CLI + extension, VS Code settings, trusted domains). Platform-specific layers depend on THIS: adom/hydrogen-windows-bootstrap (WSL2), adom/hydrogen-mac-bootstrap, adom/hydrogen-ubuntu-bootstrap. The reference design other orgs copy to build their own bootstrap on adom/core.",   "org": "adom",   "tags": [@@ -49,4 +49,4 @@     "hydrogen editor configuration",     "where do hydrogen skills come from"   ]-}\ No newline at end of file+}
skills/hydrogen-widget/SKILL.md+13−1
@@ -74,7 +74,8 @@ Several in one repo: `{"widgets": [ {...}, {...} ]}`. | field | meaning | |---|---| | `id` | unique, lowercase, stable; the curated list and the control API address it |-| `width` | slot width in px, clamped to 48..320 (the strip is about 30 px tall) |+| `icon` | an iconify name for the pulldown row (`mdi:clock-outline`), or `vendor:claude` / `vendor:codex` for the vendor marks the AI launch bar paints, so a person can tell whose numbers a widget shows |+| `width` | slot width in px, clamped to 48..320. The strip is 30 px tall in the full Title Bar and 20 px in the compact one (the chevron at the top edge), and the slot shrinks to 80 percent width in compact; size your page by its height (`100vh`, `clamp()`), never in fixed px, so it fits both | | `install` | the adom-wiki package that provides the command; defaults to the repo itself. Hydrogen runs `adom-wiki pkg install <install>` before launching, every open, so publishing a new version is enough | | `launch.command` | run in the workspace as the workspace user, backgrounded, from the repo folder when the widget came from the checkout; `launch.stop` optional (default: pkill on the command's first word) | | `launch.port` | the port the page listens on, 127.0.0.1 inside the workspace; Hydrogen reaches it as `http://<port>.localhost:<proxy>/` (its subdomain port proxy) |@@ -89,6 +90,10 @@ Hydrogen sets, in the command's environment: `HYDROGEN_WIDGET_ID`, `HYDROGEN_WID Hydrogen navigates the slot to your page and your page owns it: poll your own JSON, redraw, push whatever you want. +While the widget installs and starts, the slot shows a compact placeholder (a ring and a+status line, sized by the slot) that speaks the dock placeholder's protocol+(`{hdDock:{status|failed|navigate}}`); you never have to touch it.+ Explicit takeover, when you want the slot before health is up or want to point it at another page: `POST $ADOM_HD_CONTROL_URL/widgets/navigate {"id": $HYDROGEN_WIDGET_ID, "url": "..."}`. @@ -110,6 +115,13 @@ fresh numbers (cached, refreshed every minute), and `GET /health`. Copy `hydrogen-widget-clock` from adom/hydrogen-bootstrap `bin/` and change `data()` and the render expression; that is the whole SDK. +## Where it lives, by name++The bar across the top of the Hydrogen window is the **Title Bar** (Adom menu, meters,+widgets, bell, avatar, window controls); its short form is the **compact Title Bar**. The+Widgets pulldown is the puzzle-piece icon left of the bell, and its last row, "Make your own+widget", opens the Widgets page on the Hydrogen wiki, which links back here.+ ## Ralph test  ```