bootstrap
Adom Hydrogen (platform base)
Public Made by Adomby adom
Layer Hydrogen's workspace onto a standard Adom workstation.
← Commit history
0.5.39: the clock widget's own page, docs field, hydrogen-widget skill 1.2.0
6 files changed
+113−58
hydrogen-widget.json+9−2@@ -7,6 +7,13 @@ "width": 110, "width_tall": 84, "install": "adom/hydrogen-bootstrap",- "launch": { "command": "hydrogen-widget-clock", "port": 8933 },- "health": { "url": "/", "timeout_seconds": 60 }+ "launch": {+ "command": "hydrogen-widget-clock",+ "port": 8933+ },+ "health": {+ "url": "/",+ "timeout_seconds": 60+ },+ "docs": "widgets/README.md" }
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.38",+ "version": "0.5.39", "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.38",+ "version": "0.5.39", "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" ]-}+}
skills/hydrogen-widget/SKILL.md+79−53@@ -1,32 +1,34 @@ --- name: hydrogen-widget-description: "Build, list, open and drive Hydrogen widgets: small live panels in Hydrogen Desktop's title bar (Claude usage, Codex usage, a clock, or your own), each served by a binary inside the workspace and mounted in a sandboxed slot. Covers the hydrogen-widget.json facet a wiki repo carries (alone, or next to its dock manifest and project workspace), the launch contract (HYDROGEN_WIDGET_ID / _PORT / _SLOT, the health URL, the optional explicit takeover), the curated list on adom/hydrogen-bootstrap, the Widgets pulldown, and the control API (GET /widgets, POST /widgets/open|close|navigate|refresh|menu, GET /widgets/status) so an AI can do all of it with no mouse. Trigger words: hydrogen widget, hydrogen-widget, title bar widget, widgets pulldown, widget slot, claude usage widget, codex usage widget, tokens left widget, usage meter in the title bar, hydrogen-widget.json, /widgets/open, make a widget, add a widget to hydrogen, widget SDK."-version: 1.0.0+description: "Build, list, open and drive Hydrogen Widgets: small live panels in Hydrogen Desktop's Title Bar (Claude usage, Codex usage, a clock, or your own), each served by a binary inside the workspace and mounted in a sandboxed slot. Covers the hydrogen-widget.json facet a wiki repo carries (alone, or next to its dock manifest and project workspace), the per-widget page the pulldown links to, the launch contract (HYDROGEN_WIDGET_ID / _PORT / _SLOT / HYDROGEN_PROXY_PORT, the health URL, the explicit takeover, stop-first relaunch), the tall and compact layouts, vendor marks, private repos (read with the user's session), the curated list on adom/hydrogen-bootstrap, the Hydrogen Widgets pulldown, and the control API (GET /widgets, POST /widgets/open|close|navigate|refresh|menu, GET /widgets/status) so an AI can do all of it with no mouse. Trigger words: hydrogen widget, hydrogen-widget, title bar widget, widgets pulldown, widget slot, claude usage widget, codex usage widget, tokens left widget, usage meter in the title bar, hydrogen-widget.json, /widgets/open, make a widget, add a widget to hydrogen, private widget, widget SDK."+version: 1.2.0 --- -# hydrogen-widget: small live panels in Hydrogen Desktop's title bar+# hydrogen-widget: small live panels in Hydrogen Desktop's Title Bar -A **hydrogen-widget** is a page about 30 px tall that lives in the title bar, left of the-bell. It is served by a binary that runs **inside the workspace** (the WSL2 distro on the-desktop), the same way a dock app serves its dashboard, and Hydrogen mounts it in a-sandboxed iframe slot. The user opens and closes widgets from the **Hydrogen Widgets** pulldown (the-grid icon in the title bar); an AI does the same through the control API. Open widgets are-remembered per user and come back on the next start.+The bar across the top of the Hydrogen window is the **Title Bar**: the Adom menu, the+widgets, the CPU/RAM/GPU meter, the bell, your avatar and the window controls. Its short form+(the chevron at the top edge) is the **compact Title Bar**. A **Hydrogen Widget** is a page+that lives in a slot of that bar, left of the meter, served by a binary that runs **inside the+workspace** (the WSL2 distro on the desktop), the way a dock app serves its dashboard. Hydrogen+mounts it in a sandboxed iframe. The user opens and closes widgets from the **Hydrogen+Widgets** pulldown (the puzzle-piece icon); an AI does the same through the control API. Open+widgets are remembered per user and come back on the next start. The name has a prefix on purpose: wiki-widget is the component-page widget, and future-surfaces (kicad-widget, fusion-widget) get their own. This skill is only about Hydrogen's-title bar.+surfaces (kicad-widget, fusion-widget) get their own. This skill is only about the Title Bar. ## The three that ship -| id | what it shows | source of the numbers |-|---|---|---|-| `claude-usage` | 5-hour session, weekly, and the weekly model bucket that applies, as percent used | the Claude Code sign-in in `~/.claude/.credentials.json`, asked at `api.anthropic.com/api/oauth/usage` (what `/usage` in Claude Code shows) |-| `codex-usage` | the plan's rate-limit window as percent used, plus a secondary window when the plan has one | the Codex sign-in in `~/.codex/auth.json`, asked at `chatgpt.com/backend-api/wham/usage` (what `/status` in Codex shows) |-| `clock` | the time and date | the workspace clock; the smallest possible widget, the one to copy |+| id | what it shows | source of the numbers | repo |+|---|---|---|---|+| `claude-usage` | 5-hour session, weekly, and every weekly limit scoped to a model on your plan (Fable, Opus, ...), as percent used, in the provider's severity colour | the Claude Code sign-in in `~/.claude/.credentials.json`, asked at `api.anthropic.com/api/oauth/usage`; the `limits` list in that answer is what Claude Code's `/usage` panel draws | a facet of adom/adom-vscode |+| `codex-usage` | the plan's rate-limit window as percent used, plus a secondary window when the plan has one | the Codex sign-in in `~/.codex/auth.json`, asked at `chatgpt.com/backend-api/wham/usage` (what `/status` shows) | a facet of adom/adom-vscode |+| `clock` | the time and date, stacked when tall, inline when compact; the one to copy | the workspace clock | a facet of adom/hydrogen-bootstrap | -`claude-usage` and `codex-usage` are a facet of the adom/adom-vscode repo (their binaries-ship with that package); `clock` is a facet of adom/hydrogen-bootstrap.+Neither usage call runs a model, so neither costs quota. They ask at most once every three+minutes per provider, 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. ## Drive it from an AI (no mouse) @@ -36,7 +38,7 @@ the host). Nothing in the pulldown needs a click. ``` GET /widgets # the list: id, name, wiki_repo, source, open, status, url POST /widgets/refresh # re-read the curated list and the checkout-POST /widgets/open {"id":"claude-usage"} # mount, install, launch, hand the slot over+POST /widgets/open {"id":"claude-usage"} # mount, install, stop any old instance, launch, hand the slot over POST /widgets/close {"id":"claude-usage"} # unmount and stop it POST /widgets/navigate {"id":"...","url":"..."} # point an open slot at a URL yourself POST /widgets/menu {"open":true} # show or hide the pulldown@@ -50,6 +52,24 @@ install, launch or health wait failed (`ok:false, error`); the slot stays mounte reason so the user can see it, and `/widgets/close` removes it. The launch log is `~/.adom/widgets/<id>.log` in the workspace. +## What happens on open, exactly++1. The slot mounts with a compact placeholder (a ring and a status line, sized by the slot).+2. `adom-wiki pkg install <install>` runs in the workspace, every open, so publishing a new+ version of your package is enough to update the widget.+3. Any previous instance is stopped first (`launch.stop`, else a `pkill` on the command's first+ word), so a new version actually gets the port. The slot's frame is remounted on the+ placeholder for the same reason: a stale page never stays put.+4. `launch.command` runs backgrounded as the workspace user, from the repo folder when the widget+ came from the checkout, with `HYDROGEN_WIDGET_ID`, `HYDROGEN_WIDGET_PORT`,+ `HYDROGEN_WIDGET_SLOT` and `HYDROGEN_PROXY_PORT` in its environment plus the workspace env+ every login shell has (`ADOM_HD_CONTROL_URL`, `ADOM_HYDROGEN_URL`).+5. Hydrogen polls `http://<port>.localhost:<proxy>/<health.url>` (its subdomain port proxy)+ until it answers, up to `health.timeout_seconds`, then navigates the slot to that page.+6. Your page owns the slot from then on: poll your own JSON, redraw, push whatever you want.+ Explicit takeover, when you want the slot before health is up or want another page:+ `POST $ADOM_HD_CONTROL_URL/widgets/navigate {"id": $HYDROGEN_WIDGET_ID, "url": "..."}`.+ ## Make one: the facet Put a `hydrogen-widget.json` at the root of a wiki repo. It can sit next to a dock manifest@@ -62,10 +82,12 @@ and a `hydrogen/workspace.json`, or be the whole repo. One widget: "name": "Clock", "icon": "mdi:clock-outline", "brief": "The time and date, the smallest widget there is.",- "width": 96,+ "width": 110,+ "width_tall": 84, "install": "adom/hydrogen-bootstrap", "launch": { "command": "hydrogen-widget-clock", "port": 8933 },- "health": { "url": "/", "timeout_seconds": 60 }+ "health": { "url": "/", "timeout_seconds": 60 },+ "docs": "widgets/README.md" } ``` @@ -74,53 +96,57 @@ Several in one repo: `{"widgets": [ {...}, {...} ]}`. | field | meaning | |---|---| | `id` | unique, lowercase, stable; the curated list and the control API address it |-| `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) |+| `name`, `brief` | the pulldown row and its hover text |+| `icon` | an iconify name for the 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 in the compact Title Bar (one horizontal row); clamped to 48..320 |+| `width_tall` | slot width in the full Title Bar, where your page stacks its rows; defaults to 60 percent of `width` |+| `install` | the adom-wiki package that provides the command; defaults to the repo itself |+| `launch.command` | run in the workspace as the workspace user, backgrounded; `launch.stop` optional |+| `launch.port` | the port the page listens on, 127.0.0.1 inside the workspace | | `health.url` | path Hydrogen polls until it answers (default `/`); `timeout_seconds` default 60 |+| `docs` | the widget's own page: a repo file path (`widgets/README.md`) or a full URL. The pulldown row links to it. Defaults to `<repo>/files/widgets/README.md` | -### The launch contract+### The widget's own page (what the pulldown row opens) -Hydrogen sets, in the command's environment: `HYDROGEN_WIDGET_ID`, `HYDROGEN_WIDGET_PORT`,-`HYDROGEN_WIDGET_SLOT` (the slot's identity), plus the workspace env every login shell has-(`ADOM_HD_CONTROL_URL`, `ADOM_HYDROGEN_URL`). Serve one page on the port, sized for the strip-(transparent background, no scrollbars, 30 px tall content). As soon as `health.url` answers,-Hydrogen navigates the slot to your page and your page owns it: poll your own JSON, redraw,-push whatever you want.+Every widget should ship a page a person can read before opening it. The convention is+`widgets/README.md` in the repo (the default `docs`), with: a picture of the widget in the full+and the compact Title Bar, what it shows and where the numbers come from, how often it asks+anything, the list of files in the repo that make it a widget, and a link back to this skill. The+two shipped examples: adom/adom-vscode `widgets/README.md` and adom/hydrogen-bootstrap+`widgets/README.md`. -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.+### The page in the slot: two layouts, chosen by height -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": "..."}`.+The slot is 38 px tall in the full Title Bar (like the meter) and 20 px in the compact one.+Size your page by its height, never in fixed px: `@media (min-height: 34px)` stack rows+(label, bar, value) to use the room; `@media (max-height: 33px)` one horizontal row with+`clamp()` font sizes. Transparent background, no scrollbars. The shipped helper does this;+copy it. ### Listing it - **Your checkout**: any repo under `~/project` (one clone folder down too) with a- `hydrogen-widget.json` appears in the pulldown as "(checkout)", no publish needed. Good for- developing one.+ `hydrogen-widget.json` appears in the pulldown as "(checkout)", no publish needed. - **Everyone**: publish the repo (with the binary in its package) and ask the adom team to add `{ "id", "wiki_repo", "order" }` to `widgets/widgets.json` on adom/hydrogen-bootstrap, the curated list Hydrogen reads. The list only orders and names repos; every other fact comes from the repo's own manifest.+- **Just you, or your team (private)**: keep the repo private on the wiki (`adom-wiki page+ create --private`, `adom-wiki page share` for teammates). Hydrogen reads the curated list and+ every manifest **with the signed-in user's session**, so a private repo's widget lists and+ installs for the people the page is shared with and nobody else. Private widgets are not in+ the curated list; they come from your checkout, or from your own `widgets.json` if you fork+ the bootstrap for your org. ### A binary in fifty lines The shipped widgets are Python 3 scripts (already in every workspace), one file each plus a-shared helper: an `http.server` that answers `GET /` with a 30 px page, `GET /data.json` with-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.+shared helper: an `http.server` that answers `GET /` with the page, `GET /data.json` with fresh+numbers (cached per interval, refreshed only when asked after the interval, exponential backoff+on errors), and `GET /health`. Copy `hydrogen-widget-clock` and `hydrogen-widget-lib.py` from+adom/hydrogen-bootstrap `bin/`, change `data()` and the render expression, add a+`hydrogen-widget.json`, a `widgets/README.md` and an `install.sh` line that symlinks your script+into `~/.local/bin`. That is the whole SDK. ## Ralph test @@ -130,5 +156,5 @@ curl -s $ADOM_HD_CONTROL_URL/widgets/status curl -s http://8933.localhost:$(python3 -c "import json;print(json.load(open('/home/adom/.adom/ports.json'))['proxy'])")/data.json ``` -Then look: a screenshot of the Hydrogen window shows the slot beside the bell, and-`/widgets/close` makes it go away.+Then look: a screenshot of the Hydrogen window shows the slot left of the meter, the chevron+makes the Title Bar compact and the slot follows, and `/widgets/close` makes it go away.
widgets/README.mdadded+22@@ -0,0 +1,22 @@+# The Clock widget: the smallest Hydrogen Widget, and the one to copy++++A Hydrogen Widget is a small live page in Hydrogen Desktop's Title Bar, served by a program inside your workspace. This one shows the time and date: stacked in the full Title Bar, inline in the compact one. It is a **facet** of this repo: the bootstrap package installs `bin/hydrogen-widget-clock` and the shared helper, and the `hydrogen-widget.json` at the repo root tells Hydrogen it exists. Open it from the Hydrogen Widgets pulldown (the puzzle-piece icon left of the meter) or `POST /widgets/open {"id":"clock"}`.++## The files in this repo that make it a widget++```+hydrogen-widget.json the facet: id, name, icon, widths, launch, health, docs+bin/hydrogen-widget-clock the widget: fifteen lines on top of the helper+bin/hydrogen-widget-lib.py the shared helper: http.server, the two-layout page, the interval cache+bin/hydrogen-widget-marks.py vendor marks (for widgets that show a provider's numbers)+widgets/widgets.json the curated list Hydrogen reads (which widgets everyone sees)+widgets/README.md this page (linked from the pulldown row)+```++`install.sh` copies `bin/hydrogen-widget-*` into `~/.local/bin`, which is where `launch.command` finds it.++## Copy it++Take `hydrogen-widget-clock` and `hydrogen-widget-lib.py`, change `data()` and the render expression, add a `hydrogen-widget.json`, a page like this one, and an install line. The [hydrogen-widget skill](https://wiki.adom.inc/adom/hydrogen-bootstrap/files/skills/hydrogen-widget/SKILL.md) has every field, the launch contract, the tall and compact layouts, and how private repos work. The overview with pictures is the [Widgets page](https://wiki.adom.inc/adom/hydrogen/files/widgets/README.md) on the Hydrogen wiki.
widgets/docs/clock.pngadded⋯ 1 unchanged line ⋯