← Commit history
README.md+35−27
@@ -1,10 +1,10 @@ # adom-vscode -Adom VS Code Extension for Adom's Docker containers running Coder's code-server.+Adom VS Code Extension for Adom workspaces running Coder's code-server — a cloud container (Docker), or the Hydrogen workspace machine on Windows (WSL2) and macOS (a systemd-nspawn machine in a Lima VM). -A single Rust binary that ships a VS Code extension + CLI for controlling code-server from any process in the Docker container. AI agents (Claude Code, Codex, Kimi) and scripts use this to open files, manage extensions, control the layout, change settings live, run container commands, and pass events to the Hydrogen Desktop / Hydrogen Web frontend. The binary embeds everything: the VSIX, bash completions, and the paste-screenshot interceptor, so `adom-vscode install` sets up the entire thing.+A single Rust binary that ships a VS Code extension + CLI for controlling code-server from any process inside the Adom workspace. AI agents (Claude Code, Codex, Kimi, Antigravity) and scripts use this to open files, manage extensions, control the layout, change settings live, run workspace commands, and pass events to the Hydrogen Desktop / Hydrogen Web frontend. The binary embeds the VSIX, the bash completions and the AI title-bar script, so `adom-vscode install` sets up the entire thing. -Since v1.1.0 the extension is also the native replacement for host-side `wsl.exe` plumbing: settings apply live through the VS Code API (no window reload, no dropped Claude sessions), and shell commands run inside the container via `/exec` instead of an external `wsl.exe` spawn.+Since v1.1.0 the extension is also the native replacement for host-side workspace plumbing: settings apply live through the VS Code API (no window reload, no dropped Claude sessions), and shell commands run inside the workspace via `/exec` instead of an out-of-band host spawn (`wsl.exe` on Windows; `limactl`/`nsenter` or the Hydrogen control API's `POST /workspace/exec` on macOS).  ## What it does @@ -14,27 +14,24 @@ Since v1.1.0 the extension is also the native replacement for host-side `wsl.exe - **Settings, live**: get/set any VS Code setting, theme, fonts, font sizes. Changes apply immediately via `ConfigurationTarget.Global` (no reload, active AI sessions survive) - **Exec**: run shell commands in the container as the workspace user, streamed (SSE) or buffered - **Event queue**: any container process pushes events; the HD/HW frontend pulls them when it wants (login-refresh needed, long-job progress, anything)-- **Container identity**: query whether this is an `hd` (local Hydrogen Desktop) or `hw` (Adom cloud) container, OS, kernel, key env vars+- **Workspace identity**: query whether this is an `hd` (local Hydrogen workspace — WSL2 on Windows, the workspace machine on macOS) or `hw` (Adom cloud) container, OS, kernel, key env vars - **API key**: check the health of `/var/run/adom/api-key` and inject a fresh key after a frontend login refresh-- **Extensions**: list installed extensions (with Claude/Codex/Kimi summary), query one extension's version + running state + pending update, update one or all, search, install+- **Extensions**: list installed extensions (with a Claude/Codex/Kimi/Antigravity summary), query one extension's version + running state + pending update, update one or all, search, install - **Start** new Claude Code conversations - **Modes**: switch VS Code into different full-screen experiences (`claudecode`, `claudetty`, `tty`) - **Control layout**: sidebar, panel, terminal, activity bar (show/hide/toggle) - **Run** any VS Code command (generic escape hatch) - **Activity bar icon**: Adom icon with accordion sidebar showing every verb, AI prompts, and modes-- **Paste image into terminal**: Ctrl+V an image while focused in a code-server terminal uploads to `/tmp/shots/` and pastes the file path (so the CLI Claude Code can ingest it)  ## Install  ```bash # The wiki package is the only channel (the GitHub releases stopped at v1.0.6). It ships the-# binary (embedded VSIX + completions + paste-screenshot interceptor), the skills, and runs+# binary (embedded VSIX + completions + AI title-bar script), the skills, and runs # `adom-vscode install` for you. Hydrogen's bootstrap depends on it, so every Adom user has it. adom-wiki pkg install adom/adom-vscode      # or: adom-wiki pkg update adom/adom-vscode ``` -Or via gallia: `node install.mjs` downloads the binary and runs `adom-vscode install`.- ## Port discovery  The extension serves its HTTP API on **127.0.0.1:8821**. If 8821 is already taken it walks 8822..8831, then takes an ephemeral port, and writes the truth to:@@ -43,7 +40,7 @@ The extension serves its HTTP API on **127.0.0.1:8821**. If 8821 is already take ~/.local/share/adom-vscode/port.json    # { "port": N, "preferredPort": 8821, "pid": ..., "version": ..., "startedAt": ... } ``` -External services that expect the well-known port should read that file when 8821 does not answer. The CLI already does (resolution order: `ADOM_VSCODE_PORT` env var, then `port.json`, then 8821). The extension also drops an `adom-ports claim` breadcrumb when that CLI is present, and `GET /health` reports both `port` (actual) and `preferredPort`.+External services that expect the well-known port should read that file when 8821 does not answer. The CLI already does (resolution order: `ADOM_VSCODE_PORT` env var, then `port.json`, then 8821). `GET /health` reports both `port` (actual) and `preferredPort`.  ## HTTP API (the verb surface) @@ -61,9 +58,9 @@ Everything the CLI does is a plain HTTP call, so HD, HW, and any script can hit | theme.set | `POST /theme` `{theme}` | Switch color theme live | | fonts.get | `GET /fonts` | All font settings (editor, terminal, chat prose `chat.fontFamily`, chat code `chat.editor.fontFamily`) plus the RESOLVED families the renderer actually shows (via `document.fonts.check`) | | fonts.set | `POST /fonts` `{editorFamily?, proseFamily?, proseCodeFamily?, editorSize?, terminalSize?, proseSize?, proseCodeSize?}` | Set any subset live |-| exec | `POST /exec` `{command, cwd?, timeoutSec?}` | Buffered: run `bash -lc` as the workspace user, return `{exitCode, stdout, stderr, timedOut}`. HD-local only; cloud (hw) refuses with `exec_disabled_on_cloud` |-| exec.stream | `POST /exec/stream` `{command, cwd?, timeoutSec?}` | Streaming: SSE events `start`, `stdout`, `stderr`, `exit {exitCode, timedOut}`. HD-local only, same policy |-| fs.write | `POST /fs/write` `{path, base64 \| text, mkdir?}` | Write a file as the workspace user, atomically (temp file plus rename); `path` is absolute under the home directory or relative to `~/project`. Returns `{ok, path, bytes}`. HD-local only, same policy as exec. Hydrogen Desktop lands screenshots and recordings through this instead of spawning wsl.exe |+| exec | `POST /exec` `{command, cwd?, timeoutSec?}` | Buffered: run `bash -lc` as the workspace user, return `{exitCode, stdout, stderr, timedOut}`. local-workspace only (`kind:hd`): the WSL2 workspace on Windows and the Hydrogen workspace machine on macOS. A cloud (hw) container refuses with `exec_disabled_on_cloud` |+| exec.stream | `POST /exec/stream` `{command, cwd?, timeoutSec?}` | Streaming: SSE events `start`, `stdout`, `stderr`, `exit {exitCode, timedOut}`. local-workspace only, same policy |+| fs.write | `POST /fs/write` `{path, base64 \| text, mkdir?}` | Write a file as the workspace user, atomically (temp file plus rename); `path` is absolute under the home directory or relative to `~/project`. Returns `{ok, path, bytes}`. local-workspace only, same policy as exec. Hydrogen Desktop lands screenshots and recordings through this instead of spawning wsl.exe | | stats | `GET /stats` | Kernel counters in one read: memory (total, available, swap), cumulative CPU ticks, core count, the OOM-kill count, load average, uptime. Hydrogen Desktop's meter and its OOM notice read this instead of running a probe through wsl.exe | | queue.push | `POST /queue/push` `{topic?, type?, payload?, ttlSec?}` | Push an event for the frontend; returns `{id, depth}` | | queue.pull | `GET/POST /queue/pull` `{topic?, max?, peek?}` | Pull (consume) events; `peek` reads without consuming |@@ -72,7 +69,7 @@ Everything the CLI does is a plain HTTP call, so HD, HW, and any script can hit | container.info | `GET /container` | `kind: hd\|hw\|unknown`, cloud flag, OS, kernel, hostname, carbon URL, VS Code proxy URI, detection markers | | apikey.status | `GET /apikey` | `/var/run/adom/api-key`: exists, readable, size, age, sha256 fingerprint | | apikey.set | `POST /apikey` `{value}` | Write a fresh key (root-owned path, goes through passwordless sudo) |-| extensions.list | `GET /extensions` (`?all=1` incl. builtins, `?id=x&latest=1` for one + gallery check) | Installed extensions + `ai` summary for claude/codex/kimi |+| extensions.list | `GET /extensions` (`?all=1` incl. builtins, `?id=x&latest=1` for one + gallery check) | Installed extensions + `ai` summary for claude/codex/kimi/antigravity | | extensions.update | `POST /extensions/update` `{id?}` | Update one extension, or all when `id` omitted | | extensions.search | `POST /extensions/search` `{query}` | Open Extensions sidebar with a query | | extensions.install | `POST /extensions/install` `{id}` | Install by marketplace id |@@ -116,7 +113,7 @@ adom-vscode preview /path/to/README.md    # Markdown preview adom-vscode config get workbench.colorTheme adom-vscode config set editor.fontSize 14 adom-vscode theme get                     # active + available themes-adom-vscode theme set "Adom Dark"+adom-vscode theme set "Adom Studio Dark"   # see `theme get` for the installed labels adom-vscode font get                      # all font settings + resolved families adom-vscode font set --editor-size 14 --prose-family Inter adom-vscode font-size get@@ -135,18 +132,26 @@ adom-vscode queue status adom-vscode queue clear --topic progress  # Container identity + API key-adom-vscode container                     # hd or hw, OS, env, markers+adom-vscode container                     # kind (hd/hw/unknown), OS, env, markers, execAllowed adom-vscode apikey status adom-vscode apikey set --stdin < new-key.txt  # Extensions-adom-vscode extensions list               # + claude/codex/kimi AI summary+adom-vscode extensions list               # + claude/codex/kimi/antigravity AI summary adom-vscode extensions status anthropic.claude-code --latest adom-vscode extensions update anthropic.claude-code adom-vscode extensions update             # update all adom-vscode extensions search "python" adom-vscode extensions install ms-python.python +# AI threads and tabs+adom-vscode ai providers                            # installed? command? icon shown?+adom-vscode ai new '{"type":"codex"}'               # a Codex thread in the active group+adom-vscode ai new '{"type":"claude","group":2}'    # in editor group 2 (1-based)+adom-vscode ai icons '{"icons":["claude","codex"]}' # the title-bar icon checklist+adom-vscode tabs list                               # tab census: label, kind, group, resource+adom-vscode tabs close '{"label":"Claude Code"}'    # close by label, kind or resource_contains+ # Layout, modes, misc adom-vscode claude new                    # New Claude Code chat adom-vscode sidebar toggle                # Toggle sidebar@@ -182,11 +187,13 @@ Add `?mode=X` to any VS Code URL to auto-enter a mode on page load. Perfect for | `?mode=tty` | Blank full-screen terminal | | `?mode=tty&cmd=echo%20hello` | TTY with auto-command | -Example: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project`+Examples:+- Cloud: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project`+- Hydrogen workspace (Windows/macOS), where code-server is served locally: `http://127.0.0.1:7380/?mode=claudecode&folder=/home/adom/project` -## Paste-screenshot interceptor+## Paste-screenshot interceptor — REMOVED (2026-09-03) -When you press Ctrl+V with an image on the clipboard while focused in a code-server terminal (e.g. running CLI Claude Code), the interceptor uploads the image to the extension at `POST /paste-screenshot`, which saves it to `/tmp/shots/` (deduplicated via SHA-256) and writes the file path back to the terminal so the CLI can ingest it. Without this, code-server returns an empty string for clipboard.readText() when the clipboard holds only an image, so the paste does nothing.+The Ctrl+V-an-image-into-a-terminal interceptor is gone: the Claude CLI handles image paste on its own. `adom-vscode install` still *strips* a previously injected block from `workbench.html`, which is the last thing this tool can ask sudo for, and only on a machine patched before 1.1.x. The one block it writes today is `browser/ai-titlebar.js` (AI thread icons in the title bar).  ## Activity bar @@ -198,7 +205,7 @@ The extension adds an Adom icon to the VS Code activity bar. Click it to open a - **AI Prompts**: sample prompts to paste into Claude Code chat - **Settings & Theme**: live config/theme/font control - **Exec & Queue**: container exec and the frontend event queue-- **Container & Keys**: hd/hw identity and api-key health+- **Workspace & Keys**: hd/hw identity and api-key health - **Extensions**: list/status/update, incl. the AI assistants  ## The skill pack@@ -211,11 +218,11 @@ ecosystem can discover and drive every verb. `adom-vscode install` (and |---|---| | `adom-vscode` (parent) | Mental model, file ops, workspace scoping, port discovery, management | | `adom-vscode-settings` | Live config/theme/font get+set, resolved font families |-| `adom-vscode-exec` | Streamed + buffered container exec, timeouts, the no-wsl.exe rationale |+| `adom-vscode-exec` | Streamed + buffered workspace exec, timeouts, the in-workspace-instead-of-host-spawn rationale | | `adom-vscode-queue` | The container-to-frontend event queue, topics/TTL/peek, patterns | | `adom-vscode-container` | hd/hw identity, api-key status/inject, port discovery, /health feature detection |-| `adom-vscode-extensions` | Extension list/status/update, the Claude/Codex/Kimi AI summary |-| `adom-vscode-modes` | Full-screen modes, layout verbs, URL auto-triggers, paste-screenshot |+| `adom-vscode-extensions` | Extension list/status/update, the AI-assistant summary, the AI thread icons |+| `adom-vscode-modes` | Full-screen modes, layout verbs, URL auto-triggers |  ## Architecture @@ -229,7 +236,7 @@ Adom VS Code Extension (inside code-server) VS Code UI + container shell ``` -See [ARCHITECTURE.md](ARCHITECTURE.md) for the full design document.+See [ARCHITECTURE.md](ARCHITECTURE.md) — a HISTORICAL March 2026 design document, not current: it predates the wiki-registry install channel, the port fallback and most of today's verb surface. This README and `GET /health` are the current truth. See [COMMANDS.md](COMMANDS.md) for all VS Code commands usable with `adom-vscode command <id>`.  ## Development@@ -260,7 +267,7 @@ v1.1.10 added: live config/theme/font verbs, streamed exec, the frontend event q  v1.1.11 added: the skill pack (parent + 6 sub-skills) installed by both `adom-vscode install` and the wiki package. -v1.1.12: exec verbs are HD-local only (disabled on cloud hw containers, errorCode exec_disabled_on_cloud); /health reports execAllowed and omits exec verbs where disabled.+v1.1.12: exec verbs are local-workspace only (disabled on cloud hw containers, errorCode exec_disabled_on_cloud); /health reports execAllowed and omits exec verbs where disabled.  v1.1.13: extension-dir GC on every install (prunes stale version dirs VS Code's startup GC never reaps on long-lived windows; keeps current, live-process, and running-server versions), and install now pushes a system/update-pending queue event so the frontend can reload at a safe moment. \nv1.1.15: version realignment and the issue #642 fix (platform-scoped extensions --latest with allPlatforms matrix, --platform flag, honest 'already current' update).@@ -276,6 +283,8 @@ v1.1.20: /command returns errorCode command_not_found (HTTP 400) with did-you-me  v1.1.21: event-driven tab census + Claude session identity (John 2026-09-03: never poll the iframes again). GET /tabs and the SSE stream GET /tabs/events publish the extension host's own tabGroups census on every change; POST /claude/session-start ingests the Claude SessionStart hook (id + transcript path, before the jsonl is flushed) and GET /claude/sessions lists it; POST /claude/open-session opens an existing conversation by id and confirms the bind (retagging sdk-cli transcripts, which the Claude extension otherwise declines). Capability markers in /health: tabs.list, tabs.events, claude.open-session, claude.session-start, claude.sessions. +v1.1.93 (Kyle Bergstedt, PRs #2 and #3): the local-workspace detector is no longer WSL2-only — `/etc/profile.d/hydrogen-env.sh` and `ADOM_HYDROGEN_MACHINE` count as `kind:"hd"` alongside `hd-env.sh` and the WSL kernel, so the macOS Hydrogen workspace machine (systemd-nspawn inside Lima) stops reporting `kind:"unknown"` and stops refusing exec/fs.write; both new markers are ignored when `VSCODE_PROXY_URI` is `.adom.cloud`, and `markers` gains `hydrogenEnvSh`/`hydrogenMachine`. CLI: `ai providers|new|icons` and `tabs list|close` subcommands exist (routes and skill had them, the clap enum did not); a policy 403 prints the server's own error/hint instead of "install, then reload", and `exec --json` exits non-zero on `ok:false`. The Codex Sessions side bar matches VS Code's own list density (editor tokens, keyboard access). Docs: platform wording corrected (Windows: labels with the macOS path beside), dead wiki host replaced.+ v1.1.82: the usage widgets live on 27011 and 27012, well away from the 8000s where apps land (John 2026-09-15); a widget is a side panel and must never take a port an app wants.  v1.1.80: a failed poll keeps the last numbers dimmed and retries in 5, 15 and 45 seconds before the normal interval, instead of "no data" for three minutes.@@ -323,7 +332,6 @@ v1.1.60: ships two Hydrogen title-bar widgets as a hydrogen-widget.json facet (a v1.1.59: GET /stats also names the most recent out-of-memory victim (process, pid, rss) when the kernel log is readable, so Hydrogen Desktop can say what Linux killed. Read at most once per kill.  v1.1.58: POST /fs/write (atomic file write as the workspace user) and GET /stats (memory, CPU ticks, OOM-kill count, load) so Hydrogen Desktop never spawns wsl.exe to land a screenshot or read its meter (adom/hydrogen#50, #76). Capability markers fs.write and stats in the /health roster; fs.write is hidden on cloud containers like exec.- v1.1.57: a slow first Claude open (cold start after an extension-host restart, ~30 s) is no longer reported as a failure: 60 s budgets on New AI thread end to end, a toast at 6 s saying it is still starting, a 30 s tab wait.  v1.1.56: the Codex warm-up no longer starts on its own (this extension also runs in Hydrogen Web, where recovery is not its business); Hydrogen Desktop asks for it with POST /codex/warm when a restarted extension host appears and its Recovery switch is on. The adom-vscode.codexWarmOnReload setting is gone.
SKILL.md+12−11
@@ -1,6 +1,6 @@ --- name: adom-vscode-description: "Control VS Code Server (code-server) from inside the Docker container. THIS is the wrapper for the VS Code FILE EXPLORER sidebar, editor tabs, markdown preview, etc., when the user says 'reveal in file explorer' or 'open in vscode' they mean this CLI, NOT adom-desktop (which controls Chrome browser windows). START-HERE skill of the adom-vscode pack: file ops, workspace scoping, port discovery, and the map to the sub-skills covering live settings (adom-vscode-settings), container exec (adom-vscode-exec), the frontend event queue (adom-vscode-queue), container identity + api key (adom-vscode-container), extension management (adom-vscode-extensions), and modes/layout (adom-vscode-modes). Trigger words: adom-vscode, open in vscode, reveal in explorer, file explorer, sidebar reveal, preview markdown, vscode command, vscode api, port 8821, code-server control, drive vscode, vscode verbs."+description: "Control VS Code Server (code-server) from inside an Adom workspace (a cloud container, or the Hydrogen workspace machine on Windows/macOS). THIS is the wrapper for the VS Code FILE EXPLORER sidebar, editor tabs, markdown preview, etc., when the user says 'reveal in file explorer' or 'open in vscode' they mean this CLI, NOT adom-bridge (which controls Chrome browser windows via pup_*). START-HERE skill of the adom-vscode pack: file ops, workspace scoping, port discovery, and the map to the sub-skills covering live settings (adom-vscode-settings), container exec (adom-vscode-exec), the frontend event queue (adom-vscode-queue), container identity + api key (adom-vscode-container), extension management (adom-vscode-extensions), and modes/layout (adom-vscode-modes). Trigger words: adom-vscode, open in vscode, reveal in explorer, file explorer, sidebar reveal, preview markdown, vscode command, vscode api, port 8821, port 8822, code-server control, drive vscode, vscode verbs." ---  # adom-vscode, VS Code Control (start here)@@ -9,20 +9,21 @@ description: "Control VS Code Server (code-server) from inside the Docker contai > file explorer" / "reveal" / "show me where this file is" / > "click to open in vscode" they almost always mean the > **VS Code Server's sidebar Explorer** (the panel inside this-> Docker container's running VS Code instance). That's THIS+> workspace's running VS Code instance). That's THIS > CLI: `adom-vscode reveal <path>`. >-> **Do NOT** reach for `adom-desktop` for that, `adom-desktop`-> controls puppeteer / Chrome browser windows, not VS Code.+> **Do NOT** reach for `adom-bridge` for that, `adom-bridge`+> (formerly `adom-desktop`) controls puppeteer / Chrome browser+> windows via the `pup_*` verbs, not VS Code. > > **Do NOT** use the desktop `code` CLI either, it is not on-> PATH in code-server containers (`which code` returns nothing).+> PATH in code-server workspaces (`which code` returns nothing). > The wrapper that talks to the running code-server's REST API-> on port 8821 is this binary.+> (port 8821, or whatever `port.json` says) is this binary. > > If the user mentions "vscode", "explorer", or wants to see a > file in the editor, default to `adom-vscode`. Save-> `adom-desktop` for cases where the trigger is clearly Chrome /+> `adom-bridge` for cases where the trigger is clearly Chrome / > browser / pup / shotlog tab.  ## The mental model@@ -45,11 +46,11 @@ Binary: `~/.local/bin/adom-vscode` (also `/usr/local/bin/adom-vscode`). |---|---| | **adom-vscode** (this file) | Mental model, file ops, workspace scoping, port discovery, management | | **adom-vscode-settings** | Get/set ANY setting, theme, fonts, font sizes, all LIVE with no reload; resolved (truly rendered) font families |-| **adom-vscode-exec** | Run shell commands in the container, streamed (SSE) or buffered; the no-wsl.exe rationale |+| **adom-vscode-exec** | Run shell commands in the workspace, streamed (SSE) or buffered; why it beats an out-of-band host spawn | | **adom-vscode-queue** | The container-to-frontend event queue: push/pull/status/clear, topics, TTL, persistence |-| **adom-vscode-container** | Container identity (hd vs hw), api-key status/inject, port discovery details, /health feature detection |-| **adom-vscode-extensions** | List/query/update extensions, incl. the Claude/Codex/Kimi AI assistants |-| **adom-vscode-modes** | Full-screen modes (claudecode/claudetty/tty), layout verbs, URL auto-triggers, paste-screenshot |+| **adom-vscode-container** | Workspace identity (hd = local Hydrogen workspace on Windows/macOS, hw = cloud), api-key status/inject, port discovery details, /health feature detection |+| **adom-vscode-extensions** | List/query/update extensions, the AI assistants (Claude/Codex/Kimi/Antigravity), the AI thread icons, `ai`/`tabs` verbs |+| **adom-vscode-modes** | Full-screen modes (claudecode/claudetty/tty), layout verbs, URL auto-triggers |  ## CRITICAL: workspace scope is `/home/adom/project` 
VERSION+1−1
@@ -1 +1 @@-1.1.92+1.1.93
bin/adom-vscode
⋯ 1 unchanged line ⋯
bin/hydrogen-widget-claude-usage

  
bin/hydrogen-widget-codex-usage

  
bin/hydrogen-widget-lib.py

  
bin/hydrogen-widget-marks.py

  
install.sh

  
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-vscode",-  "version": "1.1.92",+  "version": "1.1.93",   "type": "app",   "description": "CLI + VS Code extension that lets AI assistants and the Hydrogen Desktop frontend drive VS Code from inside an Adom container: open files, live get/set of any setting/theme/font (no reload), native streamed exec, a frontend event queue, container identity (hd/hw), api-key status/inject, extension query/update, modes, paste screenshots, and any VS Code command via a local HTTP API on port 8821 (with port-file fallback discovery).",   "license": "PROPRIETARY",
page.json+2−2
@@ -4,7 +4,7 @@   "slug": "adom-vscode",   "title": "adom-vscode",   "brief": "Let Claude, Codex and Kimi drive VS Code inside your Adom container",-  "version": "1.1.92",+  "version": "1.1.93",   "license": "PROPRIETARY",   "visibility": "public",   "hero": {@@ -141,4 +141,4 @@     "adom-vscode-extensions",     "adom-vscode-modes"   ]-}\ No newline at end of file+}
skills/adom-vscode-container/SKILL.md+18−5
@@ -1,6 +1,6 @@ --- name: adom-vscode-container-description: "Identify the Adom container (hd = local Hydrogen Desktop WSL2 workspace, hw = Adom cloud container), check and inject the Adom api key at /var/run/adom/api-key, discover the extension's real port when 8821 is taken, and feature-detect verbs via GET /health. Trigger words: container type, hd or hw, what kind of container, am I in hydrogen desktop, cloud container, container identity, api key status, is the api key good, refresh api key, inject api key, /var/run/adom/api-key, session key expiring, port discovery, port.json, ADOM_VSCODE_PORT, health verbs, feature detect, carbon url, vscode proxy uri."+description: "Identify the Adom workspace (hd = local Hydrogen workspace — WSL2 on Windows, the systemd-nspawn workspace machine on macOS; hw = Adom cloud container), check and inject the Adom api key at /var/run/adom/api-key, discover the extension's real port when 8821 is taken, and feature-detect verbs via GET /health. Trigger words: container type, hd or hw, what kind of container, am I in hydrogen desktop, cloud container, container identity, api key status, is the api key good, refresh api key, inject api key, /var/run/adom/api-key, session key expiring, port discovery, port.json, ADOM_VSCODE_PORT, health verbs, feature detect, carbon url, vscode proxy uri." ---  Parent skill: **adom-vscode**@@ -15,14 +15,22 @@ adom-vscode container  Returns `kind` plus the raw evidence so callers can gate precisely: -- `kind: "hd"`: local Hydrogen Desktop workspace. Markers: `/etc/profile.d/hd-env.sh`-  exists, or a WSL kernel (`microsoft` in `uname -r`).-- `kind: "hw"`: Adom cloud container. Marker: `VSCODE_PROXY_URI` contains `.adom.cloud`.+- `kind: "hd"`: local Hydrogen workspace — the union of the per-platform markers:+  - **Windows** (WSL2): `/etc/profile.d/hd-env.sh` exists (`markers.hdEnvSh`), or a+    WSL kernel — `microsoft`/`wsl` in `uname -r` (`markers.wslKernel`).+  - **macOS** (Lima VM + systemd-nspawn machine): `/etc/profile.d/hydrogen-env.sh`+    exists (`markers.hydrogenEnvSh`), or `ADOM_HYDROGEN_MACHINE` is set in the+    extension-host env (`markers.hydrogenMachine`). Neither Windows marker is present+    there — the kernel is a plain generic Linux kernel — which is why the machine used+    to report `kind:"unknown"` and refuse exec (fixed 2026-09-17).+- `kind: "hw"`: Adom cloud container. Marker: `VSCODE_PROXY_URI` contains `.adom.cloud`+  (`markers.cloudProxy`). The two macOS markers are ignored when this one is set, so a+  cloud container can never be widened into `hd` by an env var. - `kind: "unknown"`: none of the markers matched (report the markers, don't guess).  Also included: `hostname`, `os` (from /etc/os-release), `kernel`, `arch`, `workspaceUser`, and `env.carbonUrl` (`ADOM_CARBON_URL`), `env.hydrogenUrl`,-`env.vscodeProxyUri`, plus the `markers` object itself and `execAllowed` (whether the exec verbs are enabled here; they are HD-local only). HTTP: `GET /container`.+`env.vscodeProxyUri`, plus `env.hydrogenMachine` (`ADOM_HYDROGEN_MACHINE`), the `markers` object itself and `execAllowed` (whether the exec verbs are enabled here; they are local-workspace only, `kind:hd`). HTTP: `GET /container`.  ## API key (/var/run/adom/api-key) @@ -59,6 +67,11 @@ ephemeral port, and writes the truth to:  - The CLI resolves automatically: `ADOM_VSCODE_PORT` env var > port.json > 8821. - External services expecting 8821 should read port.json when 8821 refuses.+- This is not hypothetical: on the macOS workspace machine the live extension has been+  on **8822** (`preferredPort: 8821`) since a detached host took 8821. Read `port.json`;+  never hard-code 8821. Anything that silences or forwards the port (a+  `remote.portsAttributes` entry, a port-hint registration) must cover the whole+  8821-8831 fallback range, not just 8821. - The extension also drops an `adom-ports claim` breadcrumb when that CLI exists.  ## Feature detection
skills/adom-vscode-exec/SKILL.md+34−20
@@ -1,27 +1,33 @@ --- 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. HD-LOCAL ONLY: cloud (hw) containers refuse exec (exec_disabled_on_cloud), check /health verbs first. THE native replacement for routing container commands through host-side wsl.exe (which wedges, serializes behind a global lock, and flakes with E_UNEXPECTED). 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."+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 -> **HD-LOCAL ONLY (security policy).** exec runs only on local Hydrogen Desktop-> workspaces (`container` reports `kind: hd`). 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; HD 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).+> **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-desktop need the workspace env from `/etc/profile.d/`, and a bare `-c`-shell runs them env-less (they fail with nothing on stdout).+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 @@ -49,14 +55,22 @@ adom-vscode exec "uname -a" --json                   # buffered: waits, prints o   then `exit {exitCode, timedOut}`. Closing the connection kills the child, so   a frontend that navigates away does not leak processes. -## Why not wsl.exe (the HD context)+## Why not an out-of-band host spawn -HD'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. Once the-editor is up, prefer :8821 exec for EVERYTHING; keep wsl.exe only for the-bootstrap phase (distro import, code-server start) before this API exists.+**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 
skills/adom-vscode-extensions/SKILL.md+4−2
@@ -19,8 +19,10 @@ adom-vscode extensions status anthropic.claude-code --latest   # + gallery check - `list` returns `{count, ai, extensions}`. Each entry: `{id, displayName,   version, active, builtin, path}`. `active` is whether the extension host has   activated it (running), not merely installed.-- The `ai` object maps the three assistants directly, `null` when absent:-  claude `anthropic.claude-code`, codex `openai.chatgpt`, kimi `moonshot-ai.kimi-code`.+- The `ai` object maps the AI assistants directly, `null` when absent: claude+  `anthropic.claude-code`, codex `openai.chatgpt`, kimi `moonshot-ai.kimi-code`,+  antigravity `google.google-antigravity`. `GET /ai/providers` is the authoritative+  list (it also reports each provider's command, surfaces and CLI). - `--latest` queries the Open VSX gallery (code-server's registry) and returns   `latestVersion` + `updateAvailable`. Best-effort with a 3s cap: `latestVersion:   null` means the gallery was unreachable or the extension is not published
skills/adom-vscode-modes/SKILL.md+10−8
@@ -1,6 +1,6 @@ --- name: adom-vscode-modes-description: "Full-screen VS Code modes (claudecode = Claude panel UI, claudetty = terminal + claude CLI, tty = generic terminal with optional auto-command), layout control (sidebar, bottom panel, terminal, activity bar), URL auto-triggers (?mode=...), Claude Code chat verbs, and the Ctrl+V paste-screenshot interceptor. Trigger words: claude code mode, claudecode, claudetty, tty mode, full screen terminal, mode reset, vscode mode, toggle sidebar, toggle panel, new terminal, activity bar, hide sidebar, show terminal, new claude chat, claude context viewer, paste screenshot, ctrl+v image, mode url, ?mode=claudecode, onboarding link."+description: "Full-screen VS Code modes (claudecode = Claude panel UI, claudetty = terminal + claude CLI, tty = generic terminal with optional auto-command), layout control (sidebar, bottom panel, terminal, activity bar), URL auto-triggers (?mode=...), and Claude Code chat verbs. Trigger words: claude code mode, claudecode, claudetty, tty mode, full screen terminal, mode reset, vscode mode, toggle sidebar, toggle panel, new terminal, activity bar, hide sidebar, show terminal, new claude chat, claude context viewer, mode url, ?mode=claudecode, onboarding link." ---  Parent skill: **adom-vscode**@@ -27,7 +27,9 @@ onboarding links:  - `?mode=claudecode`, `?mode=claudetty`, `?mode=tty`, `?mode=tty&cmd=echo%20hello` -Example: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project`+Examples:+- Cloud: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project`+- Hydrogen workspace (Windows/macOS), where code-server is served locally: `http://127.0.0.1:7380/?mode=claudecode&folder=/home/adom/project`  ## Layout @@ -71,13 +73,13 @@ echoed launch line, tab closes on exit; marker terminal.tui.shell); command types into an interactive shell and stays echoed at the top, `GET /terminal/tui/list`, `POST /terminal/tui/dispose {id?|name?}`. -## Paste-screenshot interceptor+## Paste-screenshot interceptor — REMOVED (2026-09-03) -Ctrl+V with an image on the clipboard, while focused in a code-server terminal,-uploads the image to `POST /paste-screenshot`; it lands in `/tmp/shots/`-(sha256-deduplicated, pruned after 20 files / 1 hour) and the file path is-typed into the terminal so a CLI Claude session can read it. Without this,-code-server's clipboard.readText() returns empty for image-only clipboards.+Gone: the Claude CLI handles image paste itself, so there is no+`POST /paste-screenshot` route and nothing writes to `/tmp/shots/`. `adom-vscode+install` only *strips* the old injected block from `workbench.html` on machines+that were patched before. Do not tell a user to Ctrl+V an image into a terminal+expecting a file path; hand the CLI the path directly.  ## Gotchas 
skills/adom-vscode-settings/SKILL.md+11−3
@@ -11,7 +11,9 @@ Every verb here applies through `vscode.workspace.getConfiguration().update(key, value, ConfigurationTarget.Global)`, which lands **immediately**: no window reload, no settings.json file merge, and active Claude Code sessions survive. Prefer these over editing `~/.local/share/code-server/User/settings.json` by-hand, and NEVER route a settings change through host-side wsl.exe.+hand, and NEVER route a settings change through an out-of-band host spawn+(`wsl.exe` on Windows, `limactl`/`nsenter` or `POST 127.0.0.1:47084/workspace/exec`+on macOS).  ## Any setting @@ -27,7 +29,13 @@ HTTP: `GET /config?key=<dotted.key>`, `POST /config {key, value}`.  ```bash adom-vscode theme get                 # active + preferredDark/preferredLight + EVERY installed theme-adom-vscode theme set "Adom Dark"     # switches live+adom-vscode theme set "Adom Studio Dark"   # switches live. Installed Adom labels:+                                           # Adom Studio, Adom Studio Dark,+                                           # Adom Studio Dark (Brighter Text),+                                           # Adom Kickstand, Adom Slate.+                                           # An unknown label answers known:false and+                                           # leaves the editor on the default (white) theme —+                                           # always read `theme get` for the real list first. ```  `theme get` enumerates every theme contributed by installed extensions@@ -75,7 +83,7 @@ values are returned; the check works again once the Adom sidebar has been opened ## Gotchas  - Font/theme changes by these verbs need NO reload. If a user reports a settings-  change "didn't apply", suspect the old wsl.exe/settings.json path or a wrong+  change "didn't apply", suspect the old host-spawn/settings.json path or a wrong   key name, not these verbs. - `config set` writes the Global (User) layer. A workspace-layer override   (`.vscode/settings.json`) still wins; `config get` shows all layers so you can