← Commit history
adom-cli
⋯ 1 unchanged line ⋯
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-cli",-  "version": "4.3.11",+  "version": "4.3.12",   "type": "app",   "org": "adom",   "description": "Adom CLI \u2014 platform binary for containers, repos, workspaces, orgs, SSH keys, Hydrogen settings, and more",
page.json+3−3
@@ -1,9 +1,9 @@ {   "slug": "adom-cli",-  "version": "4.3.11",+  "version": "4.3.12",   "type": "app",   "org": "adom",-  "description": "Adom CLI — platform binary for containers, repos, workspaces, orgs, SSH keys, Hydrogen settings, and more",+  "description": "Adom CLI \u2014 platform binary for containers, repos, workspaces, orgs, SSH keys, Hydrogen settings, and more",   "dependencies": {},   "scripts": {     "install": "./install.sh",@@ -59,4 +59,4 @@       "prompt": "add my ssh key to my adom account"     }   ]-}\ No newline at end of file+}
skills/adom-cli/containers/SKILL.md+41−11
@@ -7,6 +7,20 @@ description: "Adom Containers: Create, inspect, list, resize, and manage contain  Create and manage Adom containers -- SSH-accessible development environments tied to repositories. +## Desktop Hydrogen: these verbs address CLOUD containers only++Inside desktop Hydrogen (macOS Lima machine, Windows WSL) the workspace is a **local+machine, not a cloud container**. Hydrogen's local reverse proxy intercepts every+`/containers/...` path and answers with a synthetic record whose slug is+`hydrogen-local`. adom-cli detects that record and fails loudly, so+`get`/`images`/`port-add`/`port-remove`/`resize`/`acl *` exit 1 there instead of+reporting a success that never reached carbon.++What still works on desktop Hydrogen: `carbon containers list` (it reaches carbon) and+`carbon containers current` (which answers `hydrogen-local`, i.e. "there is no cloud+container to target"). To act on a cloud container from a desktop workspace, pass a real+slug from `carbon containers list`.+ ## Auto-detection  All repo-scoped commands auto-detect the current repo from `VSCODE_PROXY_URI`. **You do not need to parse the slug or pass owner/repo** -- just omit them:@@ -16,7 +30,7 @@ All repo-scoped commands auto-detect the current repo from `VSCODE_PROXY_URI`. * adom-cli carbon containers list-for-repo  # Or explicitly target a different repo-adom-cli carbon containers list-for-repo kcknox other-repo+adom-cli carbon containers list-for-repo <owner> other-repo ```  ## Listing is paged: never read one page as "all of them"@@ -79,7 +93,7 @@ adom-cli carbon containers images  # Create lightweight container (SSH on by default — just --repo-id required) adom-cli carbon containers create \-  --image-id 69b43b3e58d13e5ce628cdc5 \+  --image-id <DEFAULT_LIGHT_IMAGE_ID> \   # from `containers images`   --class small \   --repo-id <REPO_ID> ```@@ -121,10 +135,24 @@ adom-cli carbon containers get <slug>  ### Find the current container -The `containers current` endpoint is **buggy -- do not use it**. Instead parse `VSCODE_PROXY_URI`:+```bash+adom-cli carbon containers current+```++Returns the container this API key belongs to. Inside desktop Hydrogen it returns+`slug: hydrogen-local` plus a `_hint` — that means this workspace is a local machine and+there is no cloud container to act on.++The hostname parse below applies **only to cloud containers**, whose `VSCODE_PROXY_URI`+is `https://<owner>-<repo>-<slug>.adom.cloud/proxy/{{port}}/`. On desktop Hydrogen the+proxy URI is `http://localhost:7380/proxy/{{port}}/` and the same sed yields garbage:  ```bash-SLUG=$(echo "$VSCODE_PROXY_URI" | sed 's|https://||;s|\.adom\.cloud.*||' | rev | cut -d- -f1 | rev)+# Cloud containers only — check for the .adom.cloud suffix first+case "$VSCODE_PROXY_URI" in+  *.adom.cloud*) SLUG=$(echo "$VSCODE_PROXY_URI" | sed 's|https://||;s|\.adom\.cloud.*||' | rev | cut -d- -f1 | rev) ;;+  *) SLUG=$(adom-cli carbon containers current | sed -n 's/.*"slug": *"\([^"]*\)".*/\1/p') ;;+esac adom-cli carbon containers get "$SLUG" ``` @@ -133,10 +161,12 @@ adom-cli carbon containers get "$SLUG" adom-cli carbon containers images ``` -Two images are available:+Run it to see the current list rather than assuming; at the time of writing it returns: - **Default VSCode** (`default-vscode`): Full VS Code environment with IDE, ~4GB RAM - **Default Light Weight** (`default-light`): sshd only, ~7MB RAM idle +(Cloud only — inside desktop Hydrogen this verb exits 1, see the note at the top.)+ ### Add a port mapping ```bash adom-cli carbon containers port-add <slug> --port 5173 --prefix dev@@ -166,8 +196,9 @@ the opposite: its own clean subdomain, anonymous, revocable  **Flow:** -1. Resolve the container slug (parse `VSCODE_PROXY_URI` — see "Find the-   current container" above).+1. Resolve the container slug (`adom-cli carbon containers current` — see "Find the+   current container" above). Cloud containers only: on desktop Hydrogen there is no+   slug to map a port on. 2. Pick a URL-safe prefix. Let the user choose, or derive it from the    app/project name (e.g. `dancing-robot` → `--prefix robot`). Keep it    short (≤10 chars) and lowercase.@@ -182,7 +213,7 @@ the opposite: its own clean subdomain, anonymous, revocable **Example (dancing robot on port 8796):**  ```bash-SLUG=$(echo "$VSCODE_PROXY_URI" | sed 's|https://||;s|\.adom\.cloud.*||' | rev | cut -d- -f1 | rev)+SLUG=$(adom-cli carbon containers current | sed -n 's/.*"slug": *"\([^"]*\)".*/\1/p') adom-cli carbon containers port-add "$SLUG" --port 8796 --prefix robot # → https://robot-<random>.adom.cloud ```@@ -244,7 +275,7 @@ When you add the **first user** to a container's ACL, that container's session t **Implications:** - Adding a user to a container that's running `adom-cli` workloads will instantly lock that container out of every API. - The CLI's `acl add` hint explains this, but **the AI should ask the user before adding to any container being actively used for CLI/AI work.**-- Recovery from a locked container requires either (a) setting `ADOM_API_KEY` to a personal key from another container, or (b) creating a fresh container for CLI work, or (c) asking the user to remove members via the repo page on https://carbon.adom.inc.+- Recovery from a locked container requires either (a) setting `ADOM_API_KEY` to a personal key from another container, or (b) creating a fresh container for CLI work, or (c) asking the user to remove members via the repo page on https://hydrogen.adom.inc/<owner>/<repo>.  **Rule of thumb:** only ACL-share containers that are intentionally collaborative spaces. Never share the container the AI is driving. @@ -252,7 +283,6 @@ When you add the **first user** to a container's ACL, that container's session t  - Only the creator can list/add/remove. ACL members get 403 FORBIDDEN. - `containers list` returns containers where the user is creator OR on the ACL.-- `containers get` accepts `?bypass_permissions_check=true` to skip the ACL check (for inspecting from outside). - SSH access for ACL members works as long as the creator still has write access to the underlying repo.  ## Known Limitations@@ -260,7 +290,7 @@ When you add the **first user** to a container's ACL, that container's session t - **No container delete command.** Containers created via `adom-cli` cannot currently be deleted through the API or CLI. See [carbon#39](https://github.com/adom-inc/carbon/issues/39). - **Repo association is creation-time only.** The `--repo-id` flag can only be set when creating a container. It cannot be changed later. See [carbon#37](https://github.com/adom-inc/carbon/issues/37). - **No default container setting.** When a repo has multiple containers, there's no API to set which one opens by default. See [carbon#38](https://github.com/adom-inc/carbon/issues/38).-- **Legacy containers lack SSH.** Containers created before the SSH jumphost was deployed return "Could not connect to your container". Create a new container with `--ssh` instead.+- **Legacy containers lack SSH.** Containers created before the SSH jumphost was deployed return "Could not connect to your container". Create a new container instead (SSH is on by default; `--ssh` is a deprecated no-op).  ## Authentication 
skills/adom-cli/hydrogen-settings/SKILL.md+5
@@ -7,6 +7,11 @@ description: "Adom Hydrogen: Update IDE settings and keybindings."  Update the user's Hydrogen IDE preferences stored in Carbon. +**Cloud Hydrogen (hydrogen.adom.inc) only.** These verbs write the account-level settings+that the browser IDE reads. Desktop Hydrogen (macOS and Windows) keeps its own settings+locally, in the app's Settings window, and does not read this store — the command will+report success while changing nothing the desktop user can see.+ ## When to use  - User wants to change their Hydrogen theme or settings
skills/adom-cli/notify/SKILL.md+31−5
@@ -1,6 +1,6 @@ --- name: notify-description: "Send system-level browser notifications to the Hydrogen editor window. Visible even when the editor tab is backgrounded or browser is minimized. Supports title, body, icon, tag (for update-not-stack), require-interaction, silent, and focus-on-click."+description: "Send system-level browser notifications to the Hydrogen editor window (cloud Hydrogen and Windows Hydrogen). Supports title, body, icon, tag (for update-not-stack), require-interaction, silent, and focus-on-click. macOS Hydrogen has no browser Notifications API — use the control API instead." ---  # Browser Notifications@@ -9,13 +9,37 @@ Send system-level browser notifications from containers to the Hydrogen editor.  All commands auto-detect auth, owner, and repo from `VSCODE_PROXY_URI`. No setup needed. +## Platform: where this verb works++| Platform | `notify send` |+|---|---|+| **Cloud Hydrogen** (browser) | works — the whole permission/bell/rate-limit model below applies |+| **Windows Hydrogen** | works — the editor runs in a WebView2 with the Notifications API |+| **macOS Hydrogen** | **does not deliver.** The editor runs in a WKWebView, which exposes no `window.Notification`, so the API answers `status: "unsupported"` (and the nav bell renders as unsupported for the same reason). |++**Desktop Hydrogen (macOS) — use the native path instead:**++```bash+curl -sS -X POST "$ADOM_HYDROGEN_CONTROL_URL/notify" \+  -H 'content-type: application/json' \+  -d '{"title":"Build complete","body":"All tests passed","level":"info"}'+```++That delivers through macOS Notification Center (see the `hydrogen-notifications-mac`+skill). `adom-cli hydrogen caption show "..."` is the in-workspace overlay alternative on+every platform.++Everything below describes the **browser** surface (cloud and Windows Hydrogen): the bell+icon, the permission prompt, the queue and the rate limiter all live there. The desktop+proxy has no rate limiter.+ ## Permission  Three states:  - **Granted** → bell is hidden, notifications fire instantly - **Default (Ask)** → bell is visible but quiet until you send a notification. Then: bell rings with an amber badge, notification is **queued**. User clicks bell → permission prompt → on grant, all queued notifications fire automatically. **No retry needed** — `permission_required` exits 0.-- **Denied** → bell visible with "off" icon. API returns `denied` immediately (no queue). User must unblock in browser settings (lock icon → Notifications → Allow).+- **Denied** → bell visible with "off" icon. API returns `denied` immediately (no queue). User must unblock in browser settings (the browser URL bar's lock/site-settings icon → Notifications → Allow).  ## Quick Recipes @@ -62,8 +86,8 @@ adom-cli notify --title "Info" --no-focus-on-click "Just a heads-up" |--------|------|---------|------------| | `shown` | 0 | Notification displayed | Nothing — it worked | | `permission_required` | **0** | **Queued** — bell icon is ringing in the editor nav | Tell user: "Check the bell icon in the editor nav and click it to enable notifications — your queued message will fire automatically." **No need to retry** — the notification delivers itself when permission is granted. |-| `denied` | 1 | User has blocked notifications in browser settings | Tell user to unblock at the URL bar's lock icon → Notifications → Allow. Consider falling back to `caption show` for inline overlay. |-| `unsupported` | 1 | Browser doesn't support Notifications API | Degrade gracefully — use `caption show` or print inline |+| `denied` | 1 | User has blocked notifications in browser settings (cloud Hydrogen) | Tell user to unblock at the browser URL bar's lock/site-settings icon → Notifications → Allow. Consider falling back to `caption show` for inline overlay. |+| `unsupported` | **0** | No browser Notifications API in this host — **macOS Hydrogen always answers this** (also headless Chrome, some mobile browsers). The message was NOT delivered. | Use the control-API `/notify` route (macOS, see above), `caption show`, or print inline | | `no_browser` | 1 | No editor tab open (10s timeout) | User needs to open the editor first | | `rate_limited` (429) | 1 | Too many distinct notifications | Wait `retryAfterSec` seconds. Use `--tag` to update instead of stack (exempt from rate limit) | @@ -79,7 +103,9 @@ When the user hasn't granted permission yet, notifications are **queued** instea  **`permission_required` exits 0** (not 1) because the notification is queued and will deliver itself. No retry needed from the CLI side. -## Rate Limits+## Rate Limits (cloud Hydrogen only)++The desktop Hydrogen proxy has no limiter; these numbers describe cloud Hydrogen.  | Limit | Value | |-------|-------|
skills/adom-cli/repos/SKILL.md+8−2
@@ -12,11 +12,17 @@ Manage repositories on the Adom platform. All repo-scoped commands auto-detect the current repo from `VSCODE_PROXY_URI`. **Omit owner/repo to target the current repo:**  ```bash-# These are equivalent when inside the kcknox/gallia container:+# These are equivalent when inside the <owner>/<repo> container: adom-cli carbon repos get-adom-cli carbon repos get kcknox gallia+adom-cli carbon repos get <owner> <repo> ``` +Auto-detection needs a repo-backed workspace. In a cloud container the owner/repo come+from the `<owner>-<repo>-<slug>.adom.cloud` proxy hostname; in desktop Hydrogen (macOS+Lima machine, Windows WSL) the proxy URI is a plain `http://localhost:7380/...`, so the+CLI asks the server (`/containers/current`) instead. If the workspace is not backed by a+repo, pass owner/repo explicitly.+ ## When to use  - User asks to list, create, update, or delete repos
skills/adom-cli/setup/SKILL.md+8−2
@@ -18,9 +18,15 @@ adom-cli carbon containers images  **Do NOT** run `adom-cli config set-token` or `adom-cli config set-url` in Adom containers. The defaults are correct. +**Do NOT run `adom-cli login` inside an Adom workspace or container.** There is no browser+there, and on success it stores a personal token in `~/.config/adom-cli/config.json` that+*outranks* the workspace's rotating key (`/var/run/adom/api-key`) — a later key rotation or+sign-out is then ignored by the CLI. `login` is for a fresh machine with no Adom identity.+To undo it, delete `~/.config/adom-cli/config.json`.+ ## Outside Adom containers -On any machine already signed in to Adom (Adom Bridge on a desktop, an ah+On any machine already signed in to Adom (Adom Bridge on a desktop, a Hydrogen workspace), **no setup is needed either**: the CLI falls back to the platform sign-in at `~/.adom/session.json`, read fresh on every call, so a rotated session never strands it.@@ -46,7 +52,7 @@ First match wins: 1. `ADOM_API_TOKEN` env (absolute precedence: the recovery escape hatch; `ADOM_API_KEY` is accepted as an alias) 2. Stored config token (`~/.config/adom-cli/config.json`, via `config set-token`) 3. Container token file (`/var/run/adom/api-key`): **the default in Adom containers**-4. `~/.adom/session.json` `session_token`: the platform sign-in (Adom Bridge desktops, ah workspaces)+4. `~/.adom/session.json` `session_token`: the platform sign-in (Adom Bridge desktops, Hydrogen workspaces)  `adom-cli config show` prints `token_source`, naming which link is active. 
skills/adom-cli/status/SKILL.md+7−1
@@ -19,7 +19,13 @@ Check connectivity to the Carbon API. ```bash adom-cli carbon status ```-Hits the `/health` endpoint and prints the response. Exits with code 1 if unreachable.+Hits the `/health` endpoint and prints the response. Exits 1 if the API is unreachable.++**Desktop Hydrogen:** `ADOM_CARBON_URL` points at Hydrogen's own local reverse proxy, so+`/health` reports the *proxy's* health. The CLI recognises that (`service: "hydrogen-proxy"`)+and prints `Hydrogen proxy is up at <url>; carbon.adom.inc reachable: yes|no`, exiting 1+when `carbon_reachable` is `false` — that is the field that tells you whether cloud+platform verbs (containers, repos, orgs) will work.   ## Authentication
skills/adom-cli/workspace/SKILL.md+85−46
@@ -1,6 +1,6 @@ --- name: workspace-description: "Hydrogen Workspace & Panels: Get layout, add/remove tabs, split/resize/close panes, move/swap tabs, activate tabs, Web View control, Sandbox eval/reset, screenshots (panel/workspace/screen). Auto-detects current repo."+description: "Hydrogen Workspace & Panels: Get layout, add/remove tabs, split/resize/close panes, move/swap tabs, activate tabs, Web View control, screenshots (panel/workspace/screen), captions, alerts, recording. Auto-detects current repo. Sandbox panel verbs are cloud Hydrogen only." ---  # Workspace Management@@ -9,6 +9,22 @@ Control the Hydrogen editor workspace layout — panes, tabs, splits, and screen  All commands auto-detect auth, owner, and repo from `VSCODE_PROXY_URI`. No setup needed. +## Platforms++The same CLI talks to three Hydrogens. Where a surface differs, this guide labels it:++| Label | What it means |+|---|---|+| **Cloud Hydrogen** | `hydrogen.adom.inc` in a browser, workspace in a cloud container |+| **Windows Hydrogen** | the desktop app (1.0.x), workspace in WSL2 |+| **macOS Hydrogen** | the desktop app (0.1.4xx), workspace in a Lima VM |++"Desktop Hydrogen" means Windows **and** macOS. The desktop app hosts the editor in a+native webview, not a browser tab: there is no browser tab to surface, no hard-refresh,+and its local reverse proxy answers panel writes `200 {"ok":true}` without probing.++Not registered on desktop Hydrogen: the **Sandbox** panel (cloud only, see below).+ ## Quick Recipes  ```bash@@ -22,21 +38,19 @@ adom-cli hydrogen screenshot panel --panel-id <leaf-id> adom-cli hydrogen screenshot panel --tab-id <tab-id>  # Record screen with countdown (saved to ~/project/recordings/)+# Cloud + Windows Hydrogen only — macOS Hydrogen has no in-app recorder adom-cli hydrogen recording start --share tab --mic true --countdown 3 --reason "..." adom-cli hydrogen recording stop  # Get workspace layout (to find panel/tab IDs) adom-cli hydrogen workspace get -# Add a sandbox panel to the left of the current pane+# Add a web view panel to the left of the current pane adom-cli hydrogen workspace split --panel-id <leaf-id> --direction horizontal \-  --panel-type "adom/a1b2c3d4-5555-4000-a000-000000000050" --position before+  --panel-type "adom/a1b2c3d4-0031-4000-a000-000000000031" --position before  # Navigate a web view adom-cli hydrogen webview navigate --panel-id <leaf-id> "https://example.com"--# Run JS in a sandbox-adom-cli hydrogen sandbox eval --panel-id <leaf-id> 'document.body.innerHTML = "<h1>Hello</h1>"' ```  ## Commands@@ -182,22 +196,27 @@ When you have a viewer/dashboard tab that you create once and re-render many tim # First call: tab doesn't exist → creates it adom-cli hydrogen webview open-or-refresh \   --name "tscircuit viewer" \-  --url "https://kcknox-gallia-....adom.cloud/proxy/3000/" \+  --url "http://localhost:3000/" \   --panel-id <target-pane-id>  # Every subsequent call with the same --name: navigates the existing tab, # even if the user dragged it to a different pane. No duplicates. No --panel-id needed. adom-cli hydrogen webview open-or-refresh \   --name "tscircuit viewer" \-  --url "https://kcknox-gallia-....adom.cloud/proxy/3000/?cache-bust=$(date +%s)"+  --url "http://localhost:3000/?cache-bust=$(date +%s)" ```  Response includes `"action": "created"` or `"action": "refreshed"` so you know which path ran. If the tab was closed, the next call recreates it (requires `--panel-id` again). -### Say how to restart a page you serve yourself (0.7.9+)+### Say how to restart a page you serve yourself (0.7.9+) — Windows Hydrogen only++**Windows Hydrogen 1.0.430+ only.** Cloud Hydrogen and macOS Hydrogen have no+`/api/webview-origins` route: the flags below are accepted and ignored there, no+nudge is printed, and `_restart.recorded` comes back `false`. (macOS Hydrogen runs+the workspace in a Lima VM that survives sleep, so the failure mode does not arise.) -A page served from the workspace (`localhost`, `127.0.0.1`, `0.0.0.0`,-`[::1]`, `<port>.localhost`) dies when the laptop sleeps: WSL restarts the+On Windows Hydrogen a page served from the workspace (`localhost`, `127.0.0.1`,+`0.0.0.0`, `[::1]`, `<port>.localhost`) dies when the laptop sleeps: WSL restarts the workspace, code-server comes back, and any server an AI thread started by hand does not. The tab is then a white "can't reach this page" with nobody named to ask. Hydrogen cannot guess the command, so SAY IT when you open@@ -213,15 +232,15 @@ adom-cli hydrogen webview open-or-refresh \   --restart-cwd "$HOME/project/ntx-embedded" ``` -Hydrogen Desktop 1.0.430+ then, after a wake, either runs the command and+Windows Hydrogen 1.0.430+ then, after a wake, either runs the command and reloads the tab once the port answers, or covers the pane with a note naming your thread, and reloads by itself once the server is back (each repair has a switch in Settings > Recovery).  The outcome rides the response as `_restart`: `recorded: true` with the thread and command, or `recorded: false` with the reason, which is-`"this Hydrogen build has no /api/webview-origins route"` on cloud-Hydrogen and on older desktops. Best effort throughout: it never blocks or+`"this Hydrogen build has no /api/webview-origins route (cloud Hydrogen,+macOS Hydrogen, or Windows Hydrogen older than 1.0.430)"` everywhere else. Best effort throughout: it never blocks or fails the open. Omit the flags on a workspace URL and the CLI prints a one-line nudge on stderr (stdout stays JSON) and records `recorded: false`.@@ -230,16 +249,20 @@ A proxied URL (`https://<container>.adom.cloud/proxy/<port>/`) is not a workspace URL for this purpose: the cloud has no such route, so nothing is sent and nothing is printed. -### Navigate response classes — Hydrogen probes URLs before applying+### Navigate response classes (cloud Hydrogen) -`webview navigate` and `open-or-refresh` now return structured responses based on URL reachability:+**Cloud Hydrogen** probes URLs before applying and returns these structured responses.+**Desktop Hydrogen does not probe**: its local proxy broadcasts the event and answers+`200 {"ok":true}` unconditionally — no 204, no `warning`, no 403 — so the CLI's `_commit`+read-back is the only verification there. Localhost URLs are the *norm* on desktop+Hydrogen; do not rewrite them through a proxy path.  | Status | Meaning | `_hint` | Action | |---|---|---|---| | **204** | Clean success | "Navigated successfully." | Proceed | | **200 + `warning`** | Navigated, but page is broken (ECONNREFUSED, HTTP 5xx, DNS fail) | Tells you which port's server isn't running | Start the server and re-run — tab stays, no recreate needed | | **400** | Malformed URL or non-http/https scheme | "Check for typos, missing protocol" | Fix the URL, don't retry |-| **403** | SSRF blocked (localhost, 127.0.0.1, 10.x, 172.x, 192.168.x) | "Use the proxied URL: https://container.adom.cloud/proxy/PORT/" | Rewrite URL to use the proxy path |+| **403** | SSRF blocked (localhost, 127.0.0.1, 10.x, 172.x, 192.168.x) — **cloud Hydrogen only** | "Use the proxied URL: https://container.adom.cloud/proxy/PORT/" | Rewrite URL to use the proxy path. Never happens on desktop Hydrogen | | **404** | Wrong tab name | Lists all available tab names | Re-fetch tabs or fix the name |  The **soft-fail** case (200 + warning) is the most important for the AI: the response includes `warning.upstreamBody` with the actual error text (e.g., `"connect ECONNREFUSED 0.0.0.0:8830"`), so you can diagnose "dev server not started" without asking the user to look at the iframe.@@ -254,8 +277,9 @@ adom-cli hydrogen webview navigate --name "Bug Review" "https://example.com" adom-cli hydrogen webview navigate --panel-id <leaf-id> "https://example.com" adom-cli hydrogen webview navigate --tab-id <tab-id> "https://example.com" -# Refresh the current page-adom-cli hydrogen webview refresh --name "Bug Review"+# Refresh the current page: re-run open-or-refresh with the same name+# (there is no `webview refresh` verb)+adom-cli hydrogen webview open-or-refresh --name "Bug Review" --url "<same url>"  # Hide/show the address bar adom-cli hydrogen webview set-header --name "Bug Review" true@@ -264,7 +288,14 @@ adom-cli hydrogen webview set-header --name "Bug Review" true adom-cli hydrogen webview set-proxy --name "Bug Review" true ``` -## Sandbox panel control+## Sandbox panel control — cloud Hydrogen only++**The Sandbox panel is not registered in desktop Hydrogen** (Windows or macOS): those+builds register VS Code, Web View and External Webview only. The desktop proxy still+answers `PATCH /api/panels/sandbox/*` with a bare `{"ok":true}`, so adom-cli treats that+as "not supported here" and exits 1 rather than reporting a phantom success. On desktop,+open a webview tab pointed at your own page instead:+`adom-cli hydrogen webview open-or-refresh --name "<tab>" --url "http://localhost:<port>/"`.  All sandbox commands accept `--name`, `--panel-id`, or `--tab-id` for targeting. @@ -289,7 +320,7 @@ adom-cli hydrogen sandbox set-header --name "My Script" false - `queued` — auto-approve is off, user must approve in the panel - `rejected` — user rejected the queued code, exit 1 -Sandbox panel type UUID: `adom/a1b2c3d4-5555-4000-a000-000000000050`+Sandbox panel type UUID: `adom/a1b2c3d4-5555-4000-a000-000000000050` (cloud Hydrogen only)  ## Sharing & permissions @@ -319,13 +350,12 @@ adom-cli hydrogen screenshot panel --name "Schematic Editor" adom-cli hydrogen screenshot panel --panel-id <leaf-id> adom-cli hydrogen screenshot panel --tab-id <tab-id> -# Sandbox fallback (no sharing needed)-adom-cli hydrogen screenshot panel --panel-id <leaf-id> --method html2canvas- # Capture the entire workspace (all panels side by side) adom-cli hydrogen screenshot workspace -# Capture the entire screen (desktop, taskbar, other apps)+# Capture the entire screen (desktop, taskbar, other apps) — cloud Hydrogen.+# On desktop Hydrogen this is the browser getDisplayMedia path and `screen` is+# not in availableScopes; use the control API's `shot screen` wrapper instead. adom-cli hydrogen screenshot screen  # Check sharing status and available scopes@@ -336,9 +366,9 @@ Prints the file path on success (e.g. `screenshots/2026-04-08T22-51-15.png`).  | Scope | What it captures | Method | |-------|-----------------|--------|-| `panel` | A single panel's content | `element-capture` (default) or `html2canvas` (sandbox only) |+| `panel` | A single panel's content | `element-capture` (default); `html2canvas` only for sandbox panels, i.e. cloud Hydrogen | | `workspace` | All panels side by side | `element-capture` only |-| `screen` | Entire display including desktop | `element-capture` only |+| `screen` | Entire display including desktop | `element-capture` only. **Cloud Hydrogen**: needs screen sharing. **Desktop Hydrogen**: `availableScopes` is `["panel","workspace"]` and `sharing.displaySurface` is `null` — use the control-API `shot screen` wrapper for the whole screen |  **Unified flow:** Just call `screenshot` with an optional `--reason`. If sharing isn't active, the approval dialog opens automatically with that reason and the call blocks until the user approves (up to 90s) — then the screenshot is captured and returned. @@ -350,11 +380,18 @@ adom-cli hydrogen screenshot panel --name "Schematic Editor" --reason "Debugging **AI decision flow:** 1. Just call `screenshot` with `--reason` — one call handles everything 2. If already sharing, it captures immediately; if not, the dialog opens and the call waits-3. `html2canvas` works without sharing for sandbox panels only-4. Use `screenshot status` if you need to check current sharing state without capturing+3. `html2canvas` works without sharing for sandbox panels only (cloud Hydrogen)+4. Use `screenshot status` if you need to check current sharing state without capturing — read `availableScopes`, it is the truth for this platform  ## Screen Recording — capture video with audio +**Platform:** cloud Hydrogen and Windows Hydrogen. **macOS Hydrogen has no in-app+recorder** — the frontend routes every request to the native recorder, which is+compiled out on macOS, so `recording start` always returns+`{"error":"native recording is Windows-only"}`. On macOS use the editor's Recording+dropdown, `adom-bridge browser_record_start` for a pup browser tab, or+`adom-bridge desktop_record_start` for the whole desktop (see `hydrogen-recording-mac`).+ Files are saved automatically to `~/project/recordings/`.  **`recording start` requires FOUR flags. All four are mandatory** — this forces you to think through scope, audio, pacing, and intent every time:@@ -380,7 +417,9 @@ adom-cli hydrogen recording start --share tab --mic false --countdown 0 --reason adom-cli hydrogen recording stop ``` -Output is WebM (VP9 + Opus).+Container/codec is whatever the recorder picked — WebM (VP9 + Opus) in a browser,+mp4 (h264) on Windows Hydrogen's native recorder. Read the returned `filePath`+extension rather than assuming.  **Smart delta — the approval dialog only appears when something needs to change.** Hydrogen compares the requested `--share`/`--mic` to what's currently active: @@ -398,7 +437,7 @@ This means **15-take demo loops never re-prompt** as long as you keep the same s **If a recording is already active when you call `start` again, it auto-stops, saves, and uploads first** — the response includes a `previousRecording: { filePath, size }` field pointing to the saved file before the new recording begins.  **Choose `--share` based on what the user wants to record:**-- **`tab`** → captures the Hydrogen browser tab. Use for: panels, web views, sandbox demos, anything inside the editor.+- **`tab`** → captures the Hydrogen browser tab. Use for: panels, web views, sandbox demos, anything inside the editor. **On desktop Hydrogen there is no browser tab**, so `tab` is mapped to the whole screen — check `_receipt` in the output, and note that when `sharing.displaySurface` is `null` (the normal desktop case) the CLI's scope guard cannot verify anything. - **`screen`** → captures the entire display including desktop apps. Use for: KiCad/Fusion 360 walkthroughs, demos that switch between Hydrogen and native apps, anything outside the browser.  **Reason is critical.** The user may have 6 Claude sessions running. When the approval dialog (or countdown toast) pops up, the reason is their **only** signal of which session is asking. "Recording" or "demo" is useless. Be specific: "Re-take 3 of KiCad PCB layout demo".@@ -445,14 +484,14 @@ adom-cli hydrogen audio gain 1.0    # unity (reset) ## Captions — overlay text on the workspace  ```bash-# Default (center, medium, 3 seconds)+# Default (center, medium, auto-expires after 30s) adom-cli hydrogen caption show "Hello World"  # Large at top for 5 seconds adom-cli hydrogen caption show "Step 1: Calibrating" -d 5 -p top -s large -# Small at bottom, indefinite (stays until hidden)-adom-cli hydrogen caption show "Waiting for input..." -d 0 -p bottom -s small+# Small at bottom, persists until you hide it (NEGATIVE duration)+adom-cli hydrogen caption show "Waiting for input..." -d -1 -p bottom -s small  # Hide the current caption adom-cli hydrogen caption hide@@ -460,21 +499,22 @@ adom-cli hydrogen caption hide  | Option | Flag | Default | Values | |--------|------|---------|--------|-| Duration (seconds) | `-d` | 3 | Any number, 0 = indefinite |+| Duration (seconds) | `-d` | 30 (omit, or `0`) | Positive = that many seconds, hard cap 300 (5 min). Negative (e.g. `-1`) = persist until `caption hide` | | Position | `-p` | center | `top`, `center`, `bottom` | | Size | `-s` | medium | `small` (32px), `medium` (56px), `large` (96px) |  ## Tab alerts — blink a tab to get attention  ```bash-# Alert a tab (blinks until dismissed)-adom-cli hydrogen alert set <tab-id>+# Alert a tab by name (blinks until dismissed). Targeting is by FLAG:+# --name or --tab-id. A positional tab id is rejected.+adom-cli hydrogen alert set --name "Bug Review"  # Alert with auto-clear after 5 seconds-adom-cli hydrogen alert set <tab-id> -d 5+adom-cli hydrogen alert set --tab-id <tab-id> -d 5  # Clear a specific tab's alert-adom-cli hydrogen alert clear <tab-id>+adom-cli hydrogen alert clear --name "Bug Review"  # Clear all alerts adom-cli hydrogen alert clear@@ -502,14 +542,13 @@ adom-cli hydrogen nav toggle     # toggle between states ## Important  - **Never `PUT` or `DELETE` the `/current` workspace root.** `PUT /current` replaces the entire layout and breaks node IDs; `DELETE /current` tears down the editor session. Both are prohibited for AI use — past incidents have wiped user workspaces (VS Code + all panes) in a single call. Use the granular sub-paths only (`/current/tabs`, `/current/splits`, `/current/moves`, `/current/swaps`, `/current/panels/{id}`). If an operation isn't supported by those, it isn't supported for AI use — do not probe for additional methods.-- The Hydrogen editor must be open for these commands to work (not available via SSH)-- **Check browser connectivity + window mode before opening windows:** `adom-cli hydrogen probe` returns `{browser_connected, sse_connections, last_sse_event_at, window_mode}` in <300ms with no side effects. `window_mode` is `"webview"` (open as Hydrogen tab) or `"pup"` (open via Adom Desktop). Read it before opening any window — don't cache, so user toggles take effect immediately. If `"pup"` but Adom Desktop isn't reachable, fall back to webview and warn.-- **Get/set window mode:** `adom-cli hydrogen window-mode get` reads the preference; `adom-cli hydrogen window-mode set webview|pup` changes it (broadcasts live to any open browser tabs). Mostly used by the editor UI — CLIs just read from probe.-- **All mutation endpoints now honestly 409 when the browser is gone.** Hydrogen's E2 guard refuses writes against zombie SSE sessions — `add-tab`, `remove-tab`, `move-tab`, `split`, `swap`, `active-tab`, `close-panel`, `alert set/clear`, `caption show/hide`, `nav minimize/expand/toggle`, `sharing request/stop`, `recording start/stop`, `audio *`, `screenshot panel/workspace/screen` all return `409 Conflict` with `"No browser session is connected"` instead of silently writing ghosts. The CLI catches this and emits a structured `_hint`: ask the user to surface/click the Hydrogen tab — E3 auto-reconnect fires on `visibilitychange`/`focus` and re-registers within seconds. Hard-refresh is only needed as a fallback. Re-run `hydrogen probe` to confirm, then retry.-- **504 handling** is unchanged: still means "browser is connected but didn't respond within 120s" (commonly a dismissed approval dialog). Retry with a clearer `--reason`. The CLI now uses the new probe endpoint for diagnosis, not `screenshot status`.-- **Force-reload all browser tabs:** `adom-cli hydrogen reload` broadcasts an SSE reload event to every connected browser tab. Fire-and-forget (204). Use for: hot-reload after deploys, recovery from corrupted client state, forcing pickup of new feature flags. 409s if no browser is connected (with auto-retry via E3).+- These commands require a connected Hydrogen UI — confirm with `adom-cli hydrogen probe` before a batch of writes+- **Check UI connectivity + window mode before opening windows:** `adom-cli hydrogen probe` returns `{browser_connected, sse_connections, window_mode}` in <300ms with no side effects (cloud Hydrogen may add fields). `window_mode` is `"webview"` (open as a Hydrogen tab) or `"pup"` (open via Adom Bridge's pup (Puppeteer) bridge). Read it before opening any window — don't cache, so user toggles take effect immediately. If `"pup"` but Adom Bridge isn't reachable, the window-opening CLIs (such as `adom-parts-search`) fall back to webview and warn.+- **Get/set window mode:** `adom-cli hydrogen window-mode get` reads the preference; `adom-cli hydrogen window-mode set webview|pup` changes it (broadcasts live to any connected Hydrogen UI). Mostly used by the editor UI — CLIs just read from probe.+- **All mutation endpoints honestly 409 when no UI is connected.** Hydrogen refuses writes against a severed SSE session — `add-tab`, `remove-tab`, `move-tab`, `split`, `swap`, `active-tab`, `close-panel`, `alert set/clear`, `caption show/hide`, `nav minimize/expand/toggle`, `sharing request/stop`, `recording start/stop`, `audio *`, `screenshot panel/workspace/screen` all return `409 Conflict` with `"No browser session is connected"` instead of silently writing ghosts. The CLI catches this and emits a structured `_hint`: ask the user to bring the Hydrogen window to the front (desktop) or focus the Hydrogen browser tab (cloud); the UI re-registers within seconds. Re-run `hydrogen probe` to confirm, then retry.+- **504 handling** is unchanged: still means "a UI is connected but didn't respond within 120s" (commonly a dismissed approval dialog). Retry with a clearer `--reason`. The CLI now uses the new probe endpoint for diagnosis, not `screenshot status`.+- **Force-reload every connected Hydrogen UI:** `adom-cli hydrogen reload` broadcasts an SSE reload event. Fire-and-forget (2xx — cloud answers 204, the desktop proxy 200 `{ok:true}`). Use for: hot-reload after deploys, recovery from corrupted client state, forcing pickup of new feature flags. 409s if no UI is connected (with a short auto-retry while the UI reconnects). - **VS Code pane guard (v0.5.4+):** `workspace add-tab` and `webview open-or-refresh` automatically redirect away from the VS Code pane. If you pass a `--panel-id` that hosts VS Code, the CLI finds an alternative pane (or auto-splits to create one) and adds the `_vscode_guard` field to the response explaining the redirect. This means **you no longer need to manually avoid the VS Code pane** — the CLI enforces it. If every pane has VS Code (single-pane layout), it auto-splits horizontally to create a new pane.-- **Migration note:** Panel APIs (workspace + webview + sandbox) currently live in Hydrogen but will eventually move to Carbon. Keep implementations thin — don't build heavy abstractions on top of these endpoints.   ## Webview placement and wiki authentication (0.5.15)