Download

name: hd-captions description: > Paint labeled caption text on screen for demos/walkthroughs — captions are CAPTURED BY RECORDINGS so they show up in the finished video. HD has TWO caption surfaces: (1) a WORKSPACE caption rendered inside the HD window via adom-cli hydrogen caption — THE default, identical on web-Hydrogen AND HD (text positional; -d duration in SECONDS not ms; 30s auto-expire by default, 5-min hard cap, newest-wins, hide to clear; a raw-HTTP POST .../current/caption fallback exists for scripts hitting HD's API directly), and (2) a full-DESKTOP overlay over ALL windows via adom-desktop desktop_caption — HD's built-in Win32 always-on-top, click-through overlay (duration in MILLISECONDS — opposite unit). Pick by what you're recording: workspace recording → workspace caption; whole-screen / other-apps (KiCad, browser) recording → desktop overlay. Covers both, the desktop-overlay args (text, id, position top/center/bottom/corners, normalized x/y, size/fontSize, duration, action: hide|force-clear) and the id rule (same id replaces, different ids coexist). Windows-only for the desktop overlay. Distinct from toasts (notifications) and TTS (audio). Trigger words — caption, on-screen caption, workspace caption, hydrogen caption, screen overlay, screen label, callout, annotate the screen, step label, put text on screen, overlay text, always on top text, click-through overlay, desktop caption, caption command, adom-cli hydrogen caption, walkthrough label, demo callout, status overlay, label the screen, point at the screen, hide caption, clear captions, step 3 callout, caption duration, caption seconds, caption auto-expire, caption stuck on screen, caption units, caption position, caption size, persist caption.

Hydrogen Desktop — On-Screen Captions

You can paint labeled caption text on screen for demos and walkthroughs — and because captions are real pixels, they're captured by recordings, so they end up in the finished video ("Step 3: approve the UAC dialog →").

Captions are visual on-screen narration — centered status / countdowns / "what I'm doing," great during demos and recordings. Distinct from:

  • toasts — corner pop-ups via POST /ui/toast (transient notifications, see hd-notifications); a caption is centered narration, a toast is a corner alert.
  • TTS audio narration (adom-tts) — pair a caption with TTS for a narrated walkthrough.
  • the native Win32 auth-overlay caption — a separate internal surface HD draws for login/auth flows; not something you trigger for demos. The two surfaces below are the ones you drive.

Two caption surfaces — pick by WHAT you're recording

HD has two caption surfaces. Choosing the right one is the key decision, because each is captured by a different kind of recording:

Surface Command Renders Captured by Use when
Workspace caption adom-cli hydrogen caption inside the HD workspace (webview overlay, web-Hydrogen style) a recording/screenshot of the HD window (panel/workspace) the demo is inside HD — captioning the workspace itself
Desktop overlay adom-desktop desktop_caption over the WHOLE desktop, above every window (Win32) a full-screen / desktop recording (native recording --share screen, AD desktop) the demo shows other apps (KiCad, Fusion, a browser) or the whole screen

Match the caption to the recording. A native screenshot panel / workspace Element-Capture sees the webview content, so it captures the workspace caption but NOT the desktop overlay (a separate OS window). A full-screen recording captures the desktop overlay (it's screen pixels). Pick wrong and your caption won't be in the video.

Quick rule: "caption the Hydrogen workspace" → adom-cli hydrogen caption; "caption over the whole screen / while I record KiCad / a corner status label" → adom-desktop desktop_caption (the only one with corners, ids, and x/y).

(1) Workspace caption — adom-cli hydrogen caption ⭐ THE DEFAULT

Reach for this FIRST. It's the same command on web Hydrogen and HD (adom-cli routes through HD's workspace-events server → SSE → the frontend captionStore), so it stays consistent across both — John's principle, same as screenshots. Renders centered inside the HD workspace webview. show takes the TEXT as a positional arg (NOT --text); the only flags are -d/--duration, -p/--position, -s/--size (no id, x/y, or fontSize — those are desktop-overlay-only). Subcommands: show / hide.

adom-cli hydrogen caption show "Step 1: open the board" -p center -s large     # 30s auto-expire
adom-cli hydrogen caption show "Step 2: run DRC" -d 60 -p center -s large       # hold 60 SECONDS
adom-cli hydrogen caption hide                                                  # clear now

⚠️⚠️ -d / duration is in SECONDS — NOT milliseconds ⚠️⚠️

THE gotcha. -d 30 = 30 seconds. -d 4000 = 66 MINUTES, not 4 seconds. (This bit the build thread — -d 4000 left a caption stuck on screen for over an hour.) If you're thinking in ms you're off by 1000×. You almost never need a big number — the 30s default already covers "leave it up while I do a thing." (Note: the desktop overlay in §2 uses milliseconds — the two surfaces differ; don't cross the units.)

Web-Hydrogen vs HD parity (checked live 2026-06-14): the command + the SECONDS unit + hide are identical on both (verified by firing adom-cli hydrogen caption in a cloud web-Hydrogen workspace — center/large rendered, -d 20 held visibly). BUT the sane lifecycle below (30s default / 300s cap / persist) is verified on HD v0.1.34+; web Hydrogen still returns the older terse _hint ("auto-hides after the specified duration") and may not enforce the 30s-default/300s-cap yet. So on web Hydrogen, don't assume a fat -d self-heals — pass a sane duration. (Web-Hydrogen backend sync is a Colby/carbon item.)

Lifecycle (HD v0.1.34+, verified live 2026-06-14 — sane, never abandoned)

  • No -d (or -d 0) → auto-expires after 30s. The right default — you do NOT need to hide it.
  • Positive -d <seconds> → holds that many seconds, HARD-CAPPED at 300s (5 min). A larger value still clears at 5 min, so a fat-fingered -d 4000 now self-heals.
  • Newest wins: showing another caption replaces the current one; hide clears immediately.
  • No "forever" via adom-cli — its -d is an unsigned int (rejects negatives) by design. This is a feature, not a gap: adom-cli is the same binary on web-Hydrogen and HD, so "no persist via adom-cli" keeps both consistent and bounded (no abandoned captions). A persist-until-hidden escape exists ONLY on the raw HTTP endpoint ({"duration":-1}, below) — rarely needed.
  • No caption status verb (yet). There's no way to query "is a caption up / how long left" from adom-cli — and with newest-wins + the 30s auto-expire you rarely need to. (A read-only caption status is a possible future verb, not a current one.)
  • -p position: top / center / bottom (NO corners — use the desktop overlay for those). -s size: small / medium / large.
  • Needs a live workspace/editor session (the server returns 409 if none).

Direct HTTP fallback — only for scripts already hitting HD's API

adom-cli is the consistent default; use HTTP only when a script talks to HD's API directly. It's the same caption, same lifecycle — adom-cli just wraps this path with the workspace owner/repo. The caption lives on the workspace-events server (ADOM_HYDROGEN_URL, the proxy) — NOT the control port:

# show — duration in SECONDS, identical body/lifecycle to adom-cli
curl -s -X POST "$ADOM_HYDROGEN_URL/api/workspaces/editor/<owner>/<repo>/current/caption" \
  -H 'Content-Type: application/json' \
  -d '{"text":"Step 1: open the board","duration":60,"position":"center","size":"large"}'
# hide
curl -s -X POST "$ADOM_HYDROGEN_URL/api/workspaces/editor/<owner>/<repo>/current/caption" \
  -d '{"hide":true}'
# persist until hidden (HTTP-ONLY escape — adom-cli can't send a negative):
#   -d '{"text":"Recording…","duration":-1}'

Body: {text, duration (SECONDS), position, size}; clear with {hide:true}. Returns the same _hint as adom-cli (verified live).

(2) Desktop overlay caption — adom-desktop desktop_caption

HD's built-in Win32 always-on-top, click-through overlay — floats over every window, doesn't steal focus or intercept clicks (the user works "through" it). The full-featured surface (ids, corners, x/y, force-clear). Windows-only (non-Windows no-ops).

Firing a caption

Source: src-tauri/crates/hd-app/src/caption.rs (handle_caption). The AD CLI verb is desktop_caption (the internal message type is caption; adom-desktop status lists the caption capability). Plain adom-desktop caption is NOT a verb — it errors.

adom-desktop desktop_caption '{"text":"Step 3: approve the UAC dialog →","position":"center","size":"large","duration":6000}'

Arguments

Arg Type Meaning
text string The caption text. Omit (with no action) to hide.
id string Caption identity. Same id → replaces that caption; different ids → coexist. Defaults to _default.
position string top, bottom (default), center, top-left, top-right, bottom-left, bottom-right.
x / y float Normalized 0.0–1.0 screen coordinates (clamped). Use for precise placement instead of a named position.
size string large / medium (default) / small.
fontSize int Explicit pixel font height (also accepts font_size). Overrides size.
duration int Milliseconds on screen (default 4000), then a short fade-out. ⚠️ NOTE: this surface is ms — the OPPOSITE of the §1 workspace caption, whose -d is SECONDS. 4000 here = 4s; 4000 there = 66 min.
action string hide (dismiss this id, or all if id empty) or force-clear (destroy all captions regardless of id).

The id rule (this is the powerful part)

Captions are keyed by id. Reuse an id to update a caption in place; use different ids to show several at once. That lets you run, e.g., a persistent status caption in a corner and a moving center callout simultaneously:

# persistent status in the corner
adom-desktop desktop_caption '{"id":"status","text":"Recording…","position":"top-right","size":"small","duration":60000}'

# step callouts in the center, each replacing the last (same id)
adom-desktop desktop_caption '{"id":"step","text":"Step 1: open the board","position":"center","duration":4000}'
adom-desktop desktop_caption '{"id":"step","text":"Step 2: run DRC","position":"center","duration":4000}'

# clear just the step callout
adom-desktop desktop_caption '{"id":"step","action":"hide"}'

# nuke everything
adom-desktop desktop_caption '{"action":"force-clear"}'

Patterns

  • Walkthrough / demo callouts — drop a center caption per step (same id so each replaces the last). Combine with a recording (see Related skills) so the callouts end up in the finished video. Pair with TTS for narration.
  • Status corner — a long-duration small caption in a corner (top-right), separate id, while you drive the rest of the screen.
  • Point at a thing — use normalized x/y to sit a label next to a button or dialog you're about to act on.
  • Cleanupaction:"hide" per id when a step is done; action:"force-clear" to wipe the screen of all captions at the end of a tour.
  • hd-recording — captions are captured into screen recordings; record a walkthrough with live callouts
  • hd-adom-desktop — AD carries the caption / desktop_caption verb to the host; verify the caption capability via adom-desktop status
  • adom-ttsaudio narration to pair with on-screen captions (captions are visual-only)