adom-vscode-macos
Public Made by Adomby adom
macOS Hydrogen line of adom-vscode: the same CLI + VS Code extension (same extension id, same :8821 API) built natively for the arm64 Linux workspace Hydrogen runs on a Mac, minus the AI title bar (Hydrogen's agent bar and AI accounts popup own the title bar there). Installs over adom/adom-vscode; Hydrogen keeps this line registered. Upstream: adom-inc/adom-vscode.
name: adom-vscode-exec description: "Run shell commands inside the Adom container through the adom-vscode extension, streamed live (SSE) or buffered, as the workspace user via a login shell. LOCAL-WORKSPACE ONLY (kind:hd — WSL2 on Windows, the Hydrogen workspace machine on macOS): cloud (hw) containers refuse exec (exec_disabled_on_cloud), check /health verbs first. THE native replacement for routing workspace commands through an out-of-band host spawn (wsl.exe on Windows, limactl/nsenter on macOS). Trigger words: exec disabled, exec_disabled_on_cloud, exec in container, run command in container, adom-vscode exec, stream exec, streamed output, exec stream, container shell, run npm test in container, long running command, exec timeout, exec cwd, no wsl.exe, wsl exec replacement, POST /exec, SSE exec."
Parent skill: adom-vscode
adom-vscode-exec, run container commands natively
LOCAL-WORKSPACE ONLY (security policy). exec runs only where
containerreportskind: hd— the WSL2 workspace on Windows and the systemd-nspawn workspace machine on macOS. Cloud (hw) containers refuse both exec verbs witherrorCode: exec_disabled_on_cloud(HTTP 403), and /health omitsexec/exec.streamfrom its verb roster there, so feature-detect before offering exec. Rationale: adom-vscode is a core install for every Adom user, and an arbitrary-shell verb on an internet-facing cloud container is an unnecessary exposure; local workspaces sit behind the user's own firewall. On a cloud container, run commands in your own terminal/session instead. Debug escape hatch:ADOM_VSCODE_ALLOW_EXEC=1set in the EXTENSION HOST env by the platform (a remote caller cannot set it).The 403 body carries its own
error,kindandhint— read those. It does NOT mean the extension is missing, so do not answer a 403 by reinstalling and reloading the window (that kills live AI sessions and cannot fix a policy gate).
Commands run as the workspace user (adom) via bash -lc inside the container,
spawned by the extension host itself. LOGIN shell matters: tools like
adom-bridge need the workspace env from /etc/profile.d/ (hd-env.sh on
Windows, hydrogen-env.sh on macOS), and a bare -c shell runs them env-less
(they fail with nothing on stdout).
CLI
adom-vscode exec "ls -la" --cwd /home/adom/project # streams stdout/stderr live
adom-vscode exec "npm test" --timeout 600 # long jobs: raise the timeout (seconds)
adom-vscode exec "uname -a" --json # buffered: waits, prints one JSON result
- Streaming is the default: stdout goes to your stdout, stderr to stderr, and
the CLI exits with the remote command's exit code, so
&&chains work. --json(buffered) returns{ok, exitCode, timedOut, stdout, stderr}with output capped at 64 KB per stream; use streaming for anything chatty.- Timeouts: streaming default 300s (max 3600), buffered default 120s (max 1800).
A timed-out command is SIGKILLed and reported (
timedOut: true, exit 124 on the CLI when the remote code is unknown).
HTTP
POST /exec {command, cwd?, timeoutSec?}buffered.POST /fs/write {path, base64 | text, mkdir?}writes a file as the workspace user (atomic, parent directories created); the way to land bytes in the container without piping through a shell. Same HD-local policy as exec;fs.writeappears in/healthverbs when allowed.GET /statsreturns kernel counters (memory, CPU ticks, OOM-kill count, load, uptime) in one read, for meters and health without a probe.POST /exec/stream {command, cwd?, timeoutSec?}Server-Sent Events:start, thenstdout/stderrevents (datais a JSON-encoded chunk), thenexit {exitCode, timedOut}. Closing the connection kills the child, so a frontend that navigates away does not leak processes.
Why not an out-of-band host spawn
Windows: Hydrogen's legacy path spawned wsl.exe -d Adom-Workspace -u adom -- bash -lc <cmd> on the Windows host behind a global serial lock. That path caused
nearly every "wsl.exe is flaky / it wedged" incident: E_UNEXPECTED,
management-plane wedges, and everything queued behind one lock, with no VS Code
API access.
macOS: the equivalent is limactl shell / nsenter into the nspawn machine,
or Hydrogen control's POST 127.0.0.1:47084/workspace/exec — same story: another
process boundary, no VS Code API, and a per-call setup cost.
Either way: once the editor is up, prefer extension exec for EVERYTHING (on the
extension's real port — see port.json, not a hard-coded 8821). Keep the host
spawn only for the bootstrap phase (machine import, code-server start) before
this API exists.
Gotchas
- The exec verbs are for CONTAINER work. To run a VS Code command (palette
action), use
adom-vscode command <id>instead. ok:trueon the buffered form means the process ran; checkexitCode.- Feature-detect with
GET /health:verbscontainsexecandexec.stream.
---
name: adom-vscode-exec
description: "Run shell commands inside the Adom container through the adom-vscode extension, streamed live (SSE) or buffered, as the workspace user via a login shell. LOCAL-WORKSPACE ONLY (kind:hd — WSL2 on Windows, the Hydrogen workspace machine on macOS): cloud (hw) containers refuse exec (exec_disabled_on_cloud), check /health verbs first. THE native replacement for routing workspace commands through an out-of-band host spawn (wsl.exe on Windows, limactl/nsenter on macOS). Trigger words: exec disabled, exec_disabled_on_cloud, exec in container, run command in container, adom-vscode exec, stream exec, streamed output, exec stream, container shell, run npm test in container, long running command, exec timeout, exec cwd, no wsl.exe, wsl exec replacement, POST /exec, SSE exec."
---
Parent skill: **adom-vscode**
# adom-vscode-exec, run container commands natively
> **LOCAL-WORKSPACE ONLY (security policy).** exec runs only where `container`
> reports `kind: hd` — the WSL2 workspace on **Windows** and the systemd-nspawn
> workspace machine on **macOS**. Cloud (hw) containers refuse both exec verbs
> with `errorCode: exec_disabled_on_cloud` (HTTP 403), and /health omits `exec` /
> `exec.stream` from its verb roster there, so feature-detect before offering
> exec. Rationale: adom-vscode is a core install for every Adom user, and an
> arbitrary-shell verb on an internet-facing cloud container is an unnecessary
> exposure; local workspaces sit behind the user's own firewall. On a cloud
> container, run commands in your own terminal/session instead. Debug escape
> hatch: `ADOM_VSCODE_ALLOW_EXEC=1` set in the EXTENSION HOST env by the platform
> (a remote caller cannot set it).
>
> The 403 body carries its own `error`, `kind` and `hint` — read those. It does
> NOT mean the extension is missing, so do not answer a 403 by reinstalling and
> reloading the window (that kills live AI sessions and cannot fix a policy gate).
Commands run as the workspace user (`adom`) via `bash -lc` inside the container,
spawned by the extension host itself. LOGIN shell matters: tools like
adom-bridge need the workspace env from `/etc/profile.d/` (`hd-env.sh` on
Windows, `hydrogen-env.sh` on macOS), and a bare `-c` shell runs them env-less
(they fail with nothing on stdout).
## CLI
```bash
adom-vscode exec "ls -la" --cwd /home/adom/project # streams stdout/stderr live
adom-vscode exec "npm test" --timeout 600 # long jobs: raise the timeout (seconds)
adom-vscode exec "uname -a" --json # buffered: waits, prints one JSON result
```
- Streaming is the default: stdout goes to your stdout, stderr to stderr, and
the CLI **exits with the remote command's exit code**, so `&&` chains work.
- `--json` (buffered) returns `{ok, exitCode, timedOut, stdout, stderr}` with
output capped at 64 KB per stream; use streaming for anything chatty.
- Timeouts: streaming default 300s (max 3600), buffered default 120s (max 1800).
A timed-out command is SIGKILLed and reported (`timedOut: true`, exit 124 on
the CLI when the remote code is unknown).
## HTTP
- `POST /exec {command, cwd?, timeoutSec?}` buffered.
- `POST /fs/write {path, base64 | text, mkdir?}` writes a file as the workspace user (atomic, parent directories created); the way to land bytes in the container without piping through a shell. Same HD-local policy as exec; `fs.write` appears in `/health` verbs when allowed.
- `GET /stats` returns kernel counters (memory, CPU ticks, OOM-kill count, load, uptime) in one read, for meters and health without a probe.
- `POST /exec/stream {command, cwd?, timeoutSec?}` Server-Sent Events:
`start`, then `stdout` / `stderr` events (`data` is a JSON-encoded chunk),
then `exit {exitCode, timedOut}`. Closing the connection kills the child, so
a frontend that navigates away does not leak processes.
## Why not an out-of-band host spawn
**Windows:** Hydrogen's legacy path spawned `wsl.exe -d Adom-Workspace -u adom --
bash -lc <cmd>` on the Windows host behind a global serial lock. That path caused
nearly every "wsl.exe is flaky / it wedged" incident: E_UNEXPECTED,
management-plane wedges, and everything queued behind one lock, with no VS Code
API access.
**macOS:** the equivalent is `limactl shell` / `nsenter` into the nspawn machine,
or Hydrogen control's `POST 127.0.0.1:47084/workspace/exec` — same story: another
process boundary, no VS Code API, and a per-call setup cost.
Either way: once the editor is up, prefer extension exec for EVERYTHING (on the
extension's real port — see `port.json`, not a hard-coded 8821). Keep the host
spawn only for the bootstrap phase (machine import, code-server start) before
this API exists.
## Gotchas
- The exec verbs are for CONTAINER work. To run a VS Code command (palette
action), use `adom-vscode command <id>` instead.
- `ok:true` on the buffered form means the process ran; check `exitCode`.
- Feature-detect with `GET /health`: `verbs` contains `exec` and `exec.stream`.