Hydrogen Desktop Bootstrap (apps + skills)
Public Made by Adomby adom
Layer Hydrogen Desktop's workspace onto a standard Adom workstation.
name: hd-demo-recording description: > THE recipe for recording a demo video of Hydrogen Desktop: screen-record an AI prompt being TYPED (visible human-jitter typing) into a Claude tab plus the AI's resulting output, then speed the footage 10x to 30x in video-post and lay an adom-tts voiceover on top, so a viewer sees exactly what using an app in HD feels like. Covers the whole pipeline end to end: driving HD's control API (in-workspace OR from a remote container via adom-desktop hd_api), the high-fps native recorder, multi-tab multi-prompt demos, getting the mp4 out (streamed binary, never base64), and the post-production handoff. Trigger words: demo video, record a demo, hd demo, demo recording, record the typing, screen record hd, record ai prompt, app demo, demo pipeline, speedup demo, tts overlay demo, show what the app feels like, hd-demo-recording.
hd-demo-recording: record an HD demo video, end to end
The canonical Adom demo: the viewer watches an AI prompt get TYPED into Hydrogen Desktop, watches the AI do the work, and hears a narrator explain it, all in a tight sped-up clip. This skill is the full pipeline. It exists because every piece is easy to get slightly wrong and the pieces live in four different tools.
The shape of every demo:
- Start HD's native high-fps recorder (no picker, no sharing banner).
- Type the prompt into a Claude tab with VISIBLE typing (the sexy part) and submit.
- Let the AI's output stream on camera.
- Stop the recorder, collect the mp4.
- Post-production: speed up 10x to 30x (video-post), overlay adom-tts narration.
Step 0: pick your calling transport
Everything below is HD control-API calls. Two contexts:
Inside the HD workspace (the WSL distro): the live base URL is in a file, never an env var:
CTRL=$(cat ~/.adom/hd-control-url)
curl -s -X POST "$CTRL/claude/inject" -H 'Content-Type: application/json' -d '{...}'
From a remote container (hw, cloud): go through the adom-desktop relay's pass-through verb. Never curl through the relay (quoting gets mangled) and never hunt for the port (hd_api auto-discovers it):
adom-desktop hd_api '{"method":"POST","path":"/claude/inject","body":{...}}'
hd_* verbs auto-route to the desktop running HD; desktop_* and pull_file need
--target <desktop name> when more than one desktop is on the relay.
Step 1: preflight (30 seconds, saves the take)
GET /healthanswers with servicehydrogen-desktop-control(not the SPA).GET /capture/availability: nothing else is recording; it also tells you which screenshot method coexists with a recording (CDPPOST /screenshot, not the SSE path).GET /recording/native/sources: confirm the exact window name to capture.GET /claude/auth-check: Claude is signed in (a demo of a sign-in wall is not a demo).
Step 2: start the recorder
POST /recording/native/start
{"source":"self","cursor":true,"codec":"h264","maxSeconds":300,"reason":"demo take cap"}
source:"self"is THE way to record HD (alias:"hd"). Never guess HD's window title: it carries the version and dev stamps, and title-guessing has recorded the WRONG app before (an Edge window titled "Claude").window:<substr>matches other apps' windows;"screen"records the whole primary monitor.- WGC per-window capture: high fps, background-safe, no picker, no "you are sharing your screen" banner.
- Overriding
maxSeconds(default 600) REQUIRES areasonstring, it shows in the UI toast if the cap fires. Omit both if the default cap is fine. codec:"h264"for web-playable output (h265 is smaller but not web-playable).mic:trueonly if you want live narration in the raw take; the usual pipeline adds TTS narration in post instead.- Wait about 1 second after start so the first frames show the clean starting state.
- Verify the take is ALIVE:
GET /recording/native/statuswhile recording showsframesclimbing within about 2 seconds. If it stays 0, the take is dead (target minimized or wrong window): stop now and fix, do not record 90 seconds of nothing. A 0-frame take errors at stop (500) instead of pretending success.
Step 3: type the prompt(s) on camera
One call per prompt opens a NEW Claude tab, waits for its compose box, types with human jitter, and submits:
POST /claude/new-chat-and-send
{"text":"<the demo prompt>","typed":true,"submit":true,"delay_ms":35}
typed:trueis the visible typing (aboutdelay_msper char with 50 percent jitter).typed:falsepastes instantly: fine for seeding, boring on camera.- The call BLOCKS until typing completes: perfect for sequencing. If a relay call
times out on a long prompt, the typing still finishes on HD's side. Do NOT re-fire.
Confirm with
GET /claude/conversation-state(turns went up), then continue. Keep prompts short enough to type in under about 20 seconds. - Single-prompt demo into the CURRENT tab instead:
POST /claude/injectwith the same body shape.
Multi-prompt demos (the 5-tabs pattern): repeat the call once per prompt (each opens its own tab), then flip through the finished answers on camera with the BACKGROUND tab switch:
POST /claude/tabs/activate {"index":0} // 0-based; or {"label":"substring"}
Verify each switch took with GET /claude/tabs (active:true moved). Pause a few
seconds per tab so the sped-up video gives each answer screen time.
GET /claude/conversations gives per-tab context_ids if you want to seed specific
tabs deterministically (/claude/inject with context_index).
Step 4: stop and collect the mp4
POST /recording/native/stop
The response carries file (relative), fileAbsolute (path INSIDE the WSL distro),
fileWindows (the \\wsl$\... UNC path), and frames. If your transport hiccups
and you lose the stop response, GET /recording/native/status when idle returns
lastOutput with the same paths, the take is recoverable.
- In the workspace:
fileAbsoluteis directly readable; you are done. - Remote container: pull it as STREAMED BINARY, 1 MiB chunks, sha256-verified. Never base64 an mp4 through an exec channel:
adom-desktop --target <desktop> pull_file '{"filePaths":["<fileWindows value>"],"saveTo":"<dir>"}'
Step 5: post-production
- Speedup: the
video-postskill owns this. The house style is 10x for demos where the output matters, 30x for long AI work sessions. Keep the typing segment readable (video-post can ramp: normal speed on the typing, fast on the waiting). - Narration: synthesize with
adom-tts say(it pronounces Adom terms correctly and caches repeats), then video-post mixes it as the audio track. Write narration that explains what the viewer is SEEING at each sped-up moment. - Recording choreography (captions, panel staging, what makes a take clean) lives
in the
demo-recordingskill; read it for anything fancier than a single-window take.
Known hazards
- An HD restart kills the take AND the demo tabs. The recorder dies with the HD process (the unfinalized temp mp4 is lost) and reopened Claude tabs reset. Do not run a demo while anyone (including another AI thread) is rebuilding/relaunching HD on the same machine; if a take mysteriously vanished, check whether HD restarted mid-run (window title timestamp or /buildinfo).
- Tab state reads (
GET /claude/tabs) are DOM reads: labels can be briefly empty while the editor reloads. PreferGET /claude/conversationsfor stable context_ids + titles. - Screenshot of the Claude panel:
POST /screenshot {target:"claude"}captures the editor surface containing it (the panel is a nested webview with no own CDP target).
Safety and cleanup (non-negotiable)
- These endpoints are disruptive tier and their responses carry a
_safetyblock: you are typing into the user's REAL Claude panel (each submitted prompt SPENDS a real turn; a 5-prompt demo spends 5) and recording their REAL screen. That is the point of a demo, but only do it for a demo the user asked for. - ALWAYS stop a recording you started, even when a step fails: stop first, then
report.
GET /recording/native/statustells you if one is live. - NEVER call
/claude/tabs/close-allto clean up: it closes the user's own tabs too. There is no per-tab close; leave demo tabs open and tell the user they exist. - Delete junk takes you pulled; do not litter recordings/ with failed attempts.
Related
hd-api (transport + safety tiers), hd-recording (recorder endpoint reference), demo-recording (choreography), video-post (speedup + publish), adom-tts (narration).
---
name: hd-demo-recording
description: >
THE recipe for recording a demo video of Hydrogen Desktop: screen-record an AI prompt
being TYPED (visible human-jitter typing) into a Claude tab plus the AI's resulting
output, then speed the footage 10x to 30x in video-post and lay an adom-tts voiceover
on top, so a viewer sees exactly what using an app in HD feels like. Covers the whole
pipeline end to end: driving HD's control API (in-workspace OR from a remote container
via adom-desktop hd_api), the high-fps native recorder, multi-tab multi-prompt demos,
getting the mp4 out (streamed binary, never base64), and the post-production handoff.
Trigger words: demo video, record a demo, hd demo, demo recording, record the typing,
screen record hd, record ai prompt, app demo, demo pipeline, speedup demo, tts overlay
demo, show what the app feels like, hd-demo-recording.
---
# hd-demo-recording: record an HD demo video, end to end
The canonical Adom demo: the viewer watches an AI prompt get TYPED into Hydrogen
Desktop, watches the AI do the work, and hears a narrator explain it, all in a tight
sped-up clip. This skill is the full pipeline. It exists because every piece is easy
to get slightly wrong and the pieces live in four different tools.
The shape of every demo:
1. Start HD's native high-fps recorder (no picker, no sharing banner).
2. Type the prompt into a Claude tab with VISIBLE typing (the sexy part) and submit.
3. Let the AI's output stream on camera.
4. Stop the recorder, collect the mp4.
5. Post-production: speed up 10x to 30x (video-post), overlay adom-tts narration.
## Step 0: pick your calling transport
Everything below is HD control-API calls. Two contexts:
**Inside the HD workspace** (the WSL distro): the live base URL is in a file, never an
env var:
```bash
CTRL=$(cat ~/.adom/hd-control-url)
curl -s -X POST "$CTRL/claude/inject" -H 'Content-Type: application/json' -d '{...}'
```
**From a remote container** (hw, cloud): go through the adom-desktop relay's
pass-through verb. Never curl through the relay (quoting gets mangled) and never hunt
for the port (hd_api auto-discovers it):
```bash
adom-desktop hd_api '{"method":"POST","path":"/claude/inject","body":{...}}'
```
`hd_*` verbs auto-route to the desktop running HD; `desktop_*` and `pull_file` need
`--target <desktop name>` when more than one desktop is on the relay.
## Step 1: preflight (30 seconds, saves the take)
- `GET /health` answers with service `hydrogen-desktop-control` (not the SPA).
- `GET /capture/availability`: nothing else is recording; it also tells you which
screenshot method coexists with a recording (CDP `POST /screenshot`, not the SSE path).
- `GET /recording/native/sources`: confirm the exact window name to capture.
- `GET /claude/auth-check`: Claude is signed in (a demo of a sign-in wall is not a demo).
## Step 2: start the recorder
```json
POST /recording/native/start
{"source":"self","cursor":true,"codec":"h264","maxSeconds":300,"reason":"demo take cap"}
```
- **`source:"self"` is THE way to record HD** (alias: `"hd"`). Never guess HD's window
title: it carries the version and dev stamps, and title-guessing has recorded the
WRONG app before (an Edge window titled "Claude"). `window:<substr>` matches other
apps' windows; `"screen"` records the whole primary monitor.
- WGC per-window capture: high fps, background-safe, no picker, no "you are sharing
your screen" banner.
- Overriding `maxSeconds` (default 600) REQUIRES a `reason` string, it shows in the
UI toast if the cap fires. Omit both if the default cap is fine.
- `codec:"h264"` for web-playable output (h265 is smaller but not web-playable).
- `mic:true` only if you want live narration in the raw take; the usual pipeline adds
TTS narration in post instead.
- Wait about 1 second after start so the first frames show the clean starting state.
- **Verify the take is ALIVE**: `GET /recording/native/status` while recording shows
`frames` climbing within about 2 seconds. If it stays 0, the take is dead (target
minimized or wrong window): stop now and fix, do not record 90 seconds of nothing.
A 0-frame take errors at stop (500) instead of pretending success.
## Step 3: type the prompt(s) on camera
One call per prompt opens a NEW Claude tab, waits for its compose box, types with
human jitter, and submits:
```json
POST /claude/new-chat-and-send
{"text":"<the demo prompt>","typed":true,"submit":true,"delay_ms":35}
```
- `typed:true` is the visible typing (about `delay_ms` per char with 50 percent
jitter). `typed:false` pastes instantly: fine for seeding, boring on camera.
- The call BLOCKS until typing completes: perfect for sequencing. If a relay call
times out on a long prompt, the typing still finishes on HD's side. Do NOT re-fire.
Confirm with `GET /claude/conversation-state` (turns went up), then continue.
Keep prompts short enough to type in under about 20 seconds.
- Single-prompt demo into the CURRENT tab instead: `POST /claude/inject` with the
same body shape.
**Multi-prompt demos** (the 5-tabs pattern): repeat the call once per prompt (each
opens its own tab), then flip through the finished answers on camera with the
BACKGROUND tab switch:
```json
POST /claude/tabs/activate {"index":0} // 0-based; or {"label":"substring"}
```
Verify each switch took with `GET /claude/tabs` (`active:true` moved). Pause a few
seconds per tab so the sped-up video gives each answer screen time.
`GET /claude/conversations` gives per-tab context_ids if you want to seed specific
tabs deterministically (`/claude/inject` with `context_index`).
## Step 4: stop and collect the mp4
```json
POST /recording/native/stop
```
The response carries `file` (relative), `fileAbsolute` (path INSIDE the WSL distro),
`fileWindows` (the `\\wsl$\...` UNC path), and `frames`. If your transport hiccups
and you lose the stop response, `GET /recording/native/status` when idle returns
`lastOutput` with the same paths, the take is recoverable.
- **In the workspace**: `fileAbsolute` is directly readable; you are done.
- **Remote container**: pull it as STREAMED BINARY, 1 MiB chunks, sha256-verified.
Never base64 an mp4 through an exec channel:
```bash
adom-desktop --target <desktop> pull_file '{"filePaths":["<fileWindows value>"],"saveTo":"<dir>"}'
```
## Step 5: post-production
- **Speedup**: the `video-post` skill owns this. The house style is 10x for demos
where the output matters, 30x for long AI work sessions. Keep the typing segment
readable (video-post can ramp: normal speed on the typing, fast on the waiting).
- **Narration**: synthesize with `adom-tts say` (it pronounces Adom terms correctly
and caches repeats), then video-post mixes it as the audio track. Write narration
that explains what the viewer is SEEING at each sped-up moment.
- **Recording choreography** (captions, panel staging, what makes a take clean) lives
in the `demo-recording` skill; read it for anything fancier than a single-window take.
## Known hazards
- **An HD restart kills the take AND the demo tabs.** The recorder dies with the HD
process (the unfinalized temp mp4 is lost) and reopened Claude tabs reset. Do not
run a demo while anyone (including another AI thread) is rebuilding/relaunching HD
on the same machine; if a take mysteriously vanished, check whether HD restarted
mid-run (window title timestamp or /buildinfo).
- Tab state reads (`GET /claude/tabs`) are DOM reads: labels can be briefly empty
while the editor reloads. Prefer `GET /claude/conversations` for stable
context_ids + titles.
- Screenshot of the Claude panel: `POST /screenshot {target:"claude"}` captures the
editor surface containing it (the panel is a nested webview with no own CDP target).
## Safety and cleanup (non-negotiable)
- These endpoints are disruptive tier and their responses carry a `_safety` block:
you are typing into the user's REAL Claude panel (each submitted prompt SPENDS a
real turn; a 5-prompt demo spends 5) and recording their REAL screen. That is the
point of a demo, but only do it for a demo the user asked for.
- ALWAYS stop a recording you started, even when a step fails: stop first, then
report. `GET /recording/native/status` tells you if one is live.
- NEVER call `/claude/tabs/close-all` to clean up: it closes the user's own tabs
too. There is no per-tab close; leave demo tabs open and tell the user they exist.
- Delete junk takes you pulled; do not litter recordings/ with failed attempts.
## Related
[[hd-api]] (transport + safety tiers), [[hd-recording]] (recorder endpoint reference),
demo-recording (choreography), video-post (speedup + publish), adom-tts (narration).