app
adom-vscode
Public Made by Adomby adom
Let Claude, Codex and Kimi drive VS Code inside your Adom container
← Commit history
Publish 1.1.11
13 files changed
+497−125
README.md+18SKILL.md+40−116bin/adom-vscodeinstall.sh+13package.json+12−2page.json+21−7skills/adom-vscode-container/SKILL.md+71skills/adom-vscode-exec/SKILL.md+53skills/adom-vscode-extensions/SKILL.md+60skills/adom-vscode-modes/SKILL.md+67skills/adom-vscode-queue/SKILL.md+55skills/adom-vscode-settings/SKILL.md+82uninstall.sh+5README.md+18@@ -184,6 +184,22 @@ Example: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project` 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 skill pack++The page ships a parent skill plus six sub-skills so any AI in the Adom+ecosystem can discover and drive every verb. `adom-wiki pkg install` (and+`adom-vscode install`) deploys all of them to `~/.claude/skills/`:++| Skill | Covers |+|---|---|+| `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-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 |+ ## Architecture ```@@ -204,3 +220,5 @@ See [COMMANDS.md](COMMANDS.md) for all VS Code commands usable with `adom-vscode One version number everywhere: the `VERSION` file, the extension, the CLI `--version`, and the wiki package all carry the same value (1.1.10 as of this release). v1.1.10 added: live config/theme/font verbs, streamed exec, the frontend event queue, container identity (hd/hw), api-key status/inject, extension query/update (incl. Claude/Codex/Kimi), port fallback + `port.json` discovery, and verb-roster feature detection on `/health`.++v1.1.11 added: the skill pack (parent + 6 sub-skills) installed by both the wiki package and `adom-vscode install`.
SKILL.md+40−116@@ -1,9 +1,9 @@ --- 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). Open files, reveal in Explorer sidebar, preview markdown, get/set any VS Code setting LIVE (config, theme, fonts, font sizes, no reload), run container shell commands (exec, streamed), push/pull events on the HD frontend queue, query container identity (hd vs hw), check/inject the Adom api key, list/query/update extensions (incl. Claude/Codex/Kimi), start Claude Code chats, switch UI modes (claudecode, claudetty, tty), show notifications, run any VS Code command. Trigger words: adom-vscode, open in vscode, reveal in explorer, file explorer, sidebar reveal, preview markdown, install extension, update extension, extension version, search extensions, claude new chat, vscode command, vscode mode, vscode notify, vscode setting, change theme, set font, font size, chat font, exec in container, event queue, queue push, queue pull, container type, hd or hw, api key status, refresh api key, port 8821."+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." --- -# adom-vscode, VS Code Control+# adom-vscode, VS Code Control (start here) > **Disambiguation, read first.** When the user says "open in > file explorer" / "reveal" / "show me where this file is" /@@ -25,6 +25,32 @@ description: "Control VS Code Server (code-server) from inside the Docker contai > `adom-desktop` for cases where the trigger is clearly Chrome / > browser / pup / shotlog tab. +## The mental model++A VS Code extension inside code-server runs an HTTP server on **127.0.0.1:8821**;+the `adom-vscode` CLI wraps those verbs with AI-oriented colored output. Everything+is plain HTTP too, so scripts and the HD/HW frontend hit the API directly.+`GET /health` returns the full verb roster (`verbs: [...]`) for feature detection.++If 8821 is taken the extension falls back to 8822..8831 (then an ephemeral port)+and writes the truth to `~/.local/share/adom-vscode/port.json`. The CLI resolves+the port automatically (`ADOM_VSCODE_PORT` env var, then port.json, then 8821);+any other caller should read that file when 8821 does not answer.++Binary: `~/.local/bin/adom-vscode` (also `/usr/local/bin/adom-vscode`).++## Skill map, the pack++| Skill | Read it for |+|---|---|+| **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-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 |+ ## CRITICAL: workspace scope is `/home/adom/project` The Hydrogen panel boots code-server with `?folder=/home/adom/project`.@@ -32,8 +58,6 @@ That is the workspace root, **VS Code can only see and operate on paths inside that folder.** Anything outside it is invisible to the Explorer sidebar and to most workspace-aware commands. -Concrete consequences when generating files for the user to review:- | Action | Outside `/home/adom/project` | Inside it | |-------------------------------------|------------------------------|-----------| | `adom-vscode open <file>` | Opens a loose tab (no Explorer link); the CLI returns `OK` because `vscode.open` accepts any path, but the user can't navigate to it | Works fully, tab opens AND the Explorer entry is highlightable |@@ -42,31 +66,17 @@ Concrete consequences when generating files for the user to review: **Rule for AI-generated artifacts (thumbnails, dumps, smoke outputs, intermediate files the user is going to look at):** put them inside-`/home/adom/project/...`, not in `/tmp/...`. A few good homes:+`/home/adom/project/...`, not in `/tmp/...`. Good homes: -- `/home/adom/project/<tool>/...`: colocated with the tool the- artifact relates to (e.g. `chip-fetcher/library/<MPN>/<MPN>-thumb.png`).-- `/home/adom/project/.smoke/<task>/`: temporary smoke outputs the- user is reviewing; `.smoke/` is gitignored at the repo root.+- `/home/adom/project/<tool>/...`: colocated with the tool the artifact relates to.+- `/home/adom/project/.smoke/<task>/`: temporary smoke outputs; `.smoke/` is gitignored. - `/home/adom/project/.scratch/`: quick throwaway exploration files. -**Symptom to watch for:** if you call `adom-vscode reveal /tmp/...` or-`adom-vscode open /tmp/foo.png` and the user reports "I can't see it"-or "your link doesn't do anything" or "show me the folder," the cause-is almost always workspace scoping. Move the artifact under-`/home/adom/project/`, then re-issue the reveal.--This applies equally to relative-path Markdown links surfaced in chat-(`[label](path)`), those resolve relative to the workspace root, so-absolute paths under `/home/adom/project/...` always click through;-relative paths must be relative to that root.--## About--CLI + VS Code extension for controlling code-server from Docker processes. The extension runs an HTTP server on port 8821; the CLI wraps those calls with AI-oriented colored output. Everything is also plain HTTP, so scripts and the HD/HW frontend can hit the verbs directly; `GET /health` lists the full verb roster for feature detection.--Binary: `/usr/local/bin/adom-vscode`-Extension port: **8821** (127.0.0.1 only). If 8821 is taken the extension falls back to 8822..8831 (then an ephemeral port) and writes the real port to `~/.local/share/adom-vscode/port.json`. The CLI resolves the port automatically (`ADOM_VSCODE_PORT` env var, then port.json, then 8821); other callers should read that file when 8821 does not answer.+**Symptom to watch for:** if you call `adom-vscode reveal /tmp/...` and the user+reports "I can't see it" or "your link doesn't do anything," the cause is almost+always workspace scoping. Move the artifact under `/home/adom/project/`, then+re-issue the reveal. Relative-path Markdown links in chat resolve against the+workspace root too; absolute `/home/adom/project/...` paths always click through. ## File operations ```bash@@ -75,87 +85,6 @@ adom-vscode reveal /path/to/folder/ # Reveal in Explorer sidebar adom-vscode preview /path/to/README.md # Markdown preview ``` -## Layout-```bash-adom-vscode sidebar show # Guaranteed show-adom-vscode sidebar hide # Guaranteed hide-adom-vscode sidebar toggle # Flip current state-adom-vscode panel show|hide|toggle # Bottom panel-adom-vscode terminal show|hide|toggle|new # Terminal-adom-vscode activity-bar show|hide|toggle # Left icon strip-```--## Settings: config, theme, fonts (all apply LIVE, no reload)--These use the native VS Code API (`ConfigurationTarget.Global`), so changes land immediately and active Claude/AI sessions survive. Prefer these over editing settings.json.--```bash-adom-vscode config get workbench.colorTheme # Any setting: effective + default/global/workspace layers-adom-vscode config set editor.fontSize 14 # Any setting, live-adom-vscode theme get # Active theme + every installed theme-adom-vscode theme set "Adom Dark" # Switch live-adom-vscode font get # All font settings + RESOLVED (truly rendered) families-adom-vscode font set --editor-family "Fira Code" --prose-family Inter-adom-vscode font-size get-adom-vscode font-size set --editor 14 --terminal 13 --prose 15 --prose-code 13-```--Font keys: editor `editor.fontFamily/fontSize`, terminal `terminal.integrated.fontSize`, chat prose `chat.fontFamily/fontSize`, chat code blocks `chat.editor.fontFamily/fontSize`. `font get` reports the resolved family the renderer actually shows (checked via `document.fonts.check` in the workbench); the configured stack often names fonts that aren't installed on the rendering side.--## Exec (run shell commands in the container)-```bash-adom-vscode exec "ls -la" --cwd /home/adom/project # Streams stdout/stderr live, exits with the command's code-adom-vscode exec "npm test" --timeout 600-adom-vscode exec "uname -a" --json # Buffered JSON result instead of streaming-```-Runs `bash -lc` as the workspace user inside the container (native, no wsl.exe). HTTP: `POST /exec` (buffered) or `POST /exec/stream` (SSE).--## Event queue (container process -> HD/HW frontend)--Any process can push events; the frontend pulls when it wants. Examples: a watcher noticing the api key expires soon pushes a login-refresh event; a long job pushes progress for a dialog. Queue survives window reloads.--```bash-adom-vscode queue push login --type refresh-needed --payload '{"expiresInHours":24}'-adom-vscode queue pull --topic login # Consume matching events-adom-vscode queue pull --peek # Read without consuming-adom-vscode queue status # Depth + per-topic counts-adom-vscode queue clear --topic progress-```--## Container identity + API key-```bash-adom-vscode container # kind: hd (local Hydrogen Desktop) or hw (Adom cloud), OS, kernel, carbon URL, proxy URI-adom-vscode apikey status # /var/run/adom/api-key: exists, size, age, sha256 fingerprint-adom-vscode apikey set --stdin # Inject a fresh key after a frontend login refresh (also: apikey set <value>)-```--## Extensions-```bash-adom-vscode extensions list # Installed extensions + claude/codex/kimi AI summary-adom-vscode extensions list --all # Include builtins-adom-vscode extensions status anthropic.claude-code --latest # Version, running state, pending update-adom-vscode extensions update anthropic.claude-code # Update one (activates on reload)-adom-vscode extensions update # Update all-adom-vscode extensions search "python" # Open Extensions sidebar with search-adom-vscode extensions install ms-python.python # Install by ID-```-AI assistant ids: claude `anthropic.claude-code`, codex `openai.chatgpt`, kimi `moonshot-ai.kimi-code`.--## Claude Code-```bash-adom-vscode claude new # New Claude Code conversation-```--## Modes-Full-screen focused experiences. Use `mode reset` to exit.-```bash-adom-vscode mode claudecode # Claude Code panel UI (graphical chat)-adom-vscode mode claudetty # Full-screen terminal + claude CLI-adom-vscode mode tty # Blank full-screen terminal-adom-vscode mode tty -c "echo hello" -n "Demo" # TTY with auto-command-adom-vscode mode reset # Exit any mode, restore default layout-```- ## Generic command (escape hatch) ```bash adom-vscode command workbench.action.reloadWindow@@ -172,21 +101,16 @@ adom-vscode notify "Failed" --level error ## Management ```bash-adom-vscode health # Check extension is running (version + actual port + verb roster)-adom-vscode install # Install everything: extension, skill, completions+adom-vscode health # Version + actual port + full verb roster+adom-vscode install # Install everything: extension, skills, completions adom-vscode reload # Reload VS Code window (warning: kills active Claude Code sessions) ``` -## URL auto-trigger-Add `?mode=X` to the VS Code URL to auto-enter a mode on page load:-- `?mode=claudecode`: Claude Code panel UI-- `?mode=claudetty`: terminal + claude CLI-- `?mode=tty`: blank terminal-- `?mode=tty&cmd=COMMAND`: terminal with auto-command- ## Output format - Success: `OK: <what happened>` (green) - Failure: `ERROR: <what went wrong>` (red) + `Hint: <next action>` (dim)+- Query verbs (`config get`, `theme get`, `font get`, `container`, `apikey status`,+ `queue pull/status`, `extensions list/status`) print pretty JSON. ## If extension not running ```bash
bin/adom-vscodeadded⋯ 1 unchanged line ⋯
install.sh+13@@ -41,6 +41,19 @@ case ":${PATH}:" in *) echo "Note: $HOME/.local/bin is not on PATH. Add: export PATH=\"\$HOME/.local/bin:\$PATH\"" ;; esac +# Install the skill pack from the tarball (offline-safe; the CLI install+# below refreshes each skill from the wiki when reachable).+SKILLS_DEST="$HOME/.claude/skills"+install_skill() { mkdir -p "$SKILLS_DEST/$1"; cp "$2" "$SKILLS_DEST/$1/SKILL.md"; }+install_skill adom-vscode "$HERE/SKILL.md"+install_skill adom-vscode-settings "$HERE/skills/adom-vscode-settings/SKILL.md"+install_skill adom-vscode-exec "$HERE/skills/adom-vscode-exec/SKILL.md"+install_skill adom-vscode-queue "$HERE/skills/adom-vscode-queue/SKILL.md"+install_skill adom-vscode-container "$HERE/skills/adom-vscode-container/SKILL.md"+install_skill adom-vscode-extensions "$HERE/skills/adom-vscode-extensions/SKILL.md"+install_skill adom-vscode-modes "$HERE/skills/adom-vscode-modes/SKILL.md"+echo "Installed the adom-vscode skill pack (parent + 6 sub-skills)."+ # The CLI handles the rest, including self-elevating to sudo for the # workbench.html patch (see inject_browser_scripts in cli/src/main.rs). "$BIN_DST" install
package.json+12−2@@ -1,6 +1,6 @@ { "slug": "adom-vscode",- "version": "1.1.10",+ "version": "1.1.11", "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",@@ -31,6 +31,16 @@ "install.sh", "uninstall.sh", "bin/**",- "screenshots/**"+ "screenshots/**",+ "skills/**"+ ],+ "confirmed_user_skills": [+ "adom-vscode",+ "adom-vscode-settings",+ "adom-vscode-exec",+ "adom-vscode-queue",+ "adom-vscode-container",+ "adom-vscode-extensions",+ "adom-vscode-modes" ] }
page.json+21−7@@ -4,7 +4,7 @@ "slug": "adom-vscode", "title": "adom-vscode", "brief": "Drive VS Code from your AI: a CLI + extension that lets Claude Code, Codex, Kimi, and the Hydrogen Desktop frontend open files, change settings/theme/fonts LIVE (no reload), run streamed container commands, pass events on a frontend queue, check container identity and the Adom api key, query/update extensions, and run any VS Code command via a local HTTP API. Pre-installed in every Adom container.",- "version": "1.1.10",+ "version": "1.1.11", "license": "PROPRIETARY", "visibility": "public", "hero": {@@ -13,13 +13,17 @@ "thumbnail": "screenshots/hero.png" }, "tags": [+ "automation",+ "claude", "cli",- "vscode", "code-server",+ "docker",+ "exec",+ "hydrogen-desktop", "ide",- "claude",- "automation",- "docker"+ "queue",+ "settings",+ "vscode" ], "discovery_triggers": [ "adom-vscode",@@ -114,11 +118,21 @@ "install.sh", "uninstall.sh", "bin/**",- "screenshots/**"+ "screenshots/**",+ "skills/**" ], "org": "adom", "author": { "name": "John Lauer", "email": "[email protected]"- }+ },+ "confirmed_user_skills": [+ "adom-vscode",+ "adom-vscode-settings",+ "adom-vscode-exec",+ "adom-vscode-queue",+ "adom-vscode-container",+ "adom-vscode-extensions",+ "adom-vscode-modes"+ ] }
skills/adom-vscode-container/SKILL.mdadded+71@@ -0,0 +1,71 @@+---+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."+---++Parent skill: **adom-vscode**++# adom-vscode-container, identity + api key + discovery++## Container identity++```bash+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: "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. HTTP: `GET /container`.++## API key (/var/run/adom/api-key)++```bash+adom-vscode apikey status # exists, readable, size, mtime, ageSeconds, sha256_8+adom-vscode apikey set --stdin < new-key.txt+adom-vscode apikey set <value>+```++- `status` never prints the key itself, only a sha256 fingerprint (first 8 hex),+ so it is safe to echo into logs and chat.+- `set` writes through passwordless sudo (the path is root-owned), creating+ `/var/run/adom` if needed, mode 644, trailing newline normalized. Use it when+ the frontend completes a login refresh and needs the container to pick up the+ new session key.+- Typical flow with the queue: watcher sees the key aging, pushes a+ `login/refresh-needed` event (see **adom-vscode-queue**); frontend refreshes+ the session and calls `apikey set`; watcher confirms via `apikey status`+ (fresh mtime + new fingerprint).++HTTP: `GET /apikey`, `POST /apikey {value}`.++## Port discovery (when 8821 is not the port)++The extension prefers **127.0.0.1:8821**. If busy it walks 8822..8831, then an+ephemeral port, and writes the truth to:++```+~/.local/share/adom-vscode/port.json+# { "port": N, "preferredPort": 8821, "pid": ..., "version": ..., "startedAt": ... }+```++- The CLI resolves automatically: `ADOM_VSCODE_PORT` env var > port.json > 8821.+- External services expecting 8821 should read port.json when 8821 refuses.+- The extension also drops an `adom-ports claim` breadcrumb when that CLI exists.++## Feature detection++```bash+adom-vscode health+```++`GET /health` returns `{version, port, preferredPort, portFile, verbs: [...]}`.+Gate on the `verbs` array (e.g. `exec.stream`, `queue.push`, `apikey.set`), not+on version strings. An extension that answers /health without a `verbs` field+predates 1.1.10 and needs a window reload or update.
skills/adom-vscode-exec/SKILL.mdadded+53@@ -0,0 +1,53 @@+---+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. 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 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++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).++## 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 /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 wsl.exe (the HD context)++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.++## 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`.
skills/adom-vscode-extensions/SKILL.mdadded+60@@ -0,0 +1,60 @@+---+name: adom-vscode-extensions+description: "Query and manage VS Code extensions in the Adom container: list installed with versions and running state, get one extension's detail plus whether a newer gallery version exists, update one or all, search, install. Includes the AI assistant summary (claude = anthropic.claude-code, codex = openai.chatgpt, kimi = moonshot-ai.kimi-code). Trigger words: is claude installed, claude extension version, codex extension, kimi extension, list extensions, extension version, update extension, extension update pending, install extension, search extensions, extension running, extension state, workbench extensions, open-vsx latest, update claude code extension."+---++Parent skill: **adom-vscode**++# adom-vscode-extensions, query and update extensions++## List and query++```bash+adom-vscode extensions list # non-builtin extensions + the AI summary+adom-vscode extensions list --all # include VS Code builtins+adom-vscode extensions status anthropic.claude-code # version + active state+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`.+- `--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+ there, NOT that it is current.++HTTP: `GET /extensions`, `GET /extensions?all=1`, `GET /extensions?id=<id>&latest=1`.++## Update++```bash+adom-vscode extensions update anthropic.claude-code # one extension+adom-vscode extensions update # all extensions+```++Updates download in the background; the NEW version only activates on a window+reload. So the honest report to a user is "update requested, activates on+reload", and `extensions status <id>` keeps showing the running (old) version+until then. Warn before reloading: `adom-vscode reload` kills active Claude+Code sessions.++HTTP: `POST /extensions/update {id?}` (omit `id` for all).++## Search and install++```bash+adom-vscode extensions search "python" # opens the Extensions sidebar with the query+adom-vscode extensions install ms-python.python # install by marketplace id+```++HTTP: `POST /extensions/search {query}`, `POST /extensions/install {id}`.++## Gotchas++- An extension can be installed but `active: false` (activates lazily). For the+ AI assistants, active = the assistant's panel/agent is actually live.+- Version directories accumulate on disk (`~/.local/share/code-server/extensions/`);+ the `version` reported by these verbs is the RUNNING one, trust it over `ls`.
skills/adom-vscode-modes/SKILL.mdadded+67@@ -0,0 +1,67 @@+---+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."+---++Parent skill: **adom-vscode**++# adom-vscode-modes, modes / layout / Claude / paste++## Modes (full-screen experiences)++```bash+adom-vscode mode claudecode # Claude Code panel UI (graphical chat)+adom-vscode mode claudetty # Full-screen terminal running the claude CLI+adom-vscode mode tty # Blank full-screen terminal+adom-vscode mode tty -c "htop" -n "Monitor" # TTY with auto-command + tab name+adom-vscode mode reset # Exit any mode, restore default layout+```++Modes hide the sidebar, activity bar and status bar for a focused screen. Always+offer `mode reset` as the way back. HTTP: `POST /mode/claudecode|claudetty|tty|reset`.++### URL auto-trigger++Append `?mode=X` to the VS Code URL to auto-enter a mode on page load, great for+onboarding links:++- `?mode=claudecode`, `?mode=claudetty`, `?mode=tty`, `?mode=tty&cmd=echo%20hello`++Example: `https://<slug>.adom.cloud/?mode=claudecode&folder=/home/adom/project`++## Layout++```bash+adom-vscode sidebar show|hide|toggle # Primary (left) sidebar+adom-vscode panel show|hide|toggle # Bottom panel (terminal, output)+adom-vscode terminal show|hide|toggle|new # Integrated terminal+adom-vscode activity-bar toggle # Left icon strip (toggle only)+```++## Claude Code++```bash+adom-vscode claude new # New Claude Code conversation+adom-vscode claude context # Open the live Claude Context viewer panel+adom-vscode claude context --json # Session stats as JSON: context %, cache, tools, compactions+```++The context viewer lists every ACTIVE Claude Code session in the container with+token usage, cache hit ratio, tool frequency, largest tool results, and+compaction history. HTTP: `GET /claude/context`, `POST /claude/new`.++## Paste-screenshot interceptor++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.++## Gotchas++- Mode switches close editors; do not enter a mode while the user has unsaved+ work without telling them.+- `activity-bar` only has a toggle in code-server (no explicit show/hide).+- `adom-vscode reload` restores extension updates and clears stale state, but+ kills every active Claude Code session; warn first.
skills/adom-vscode-queue/SKILL.mdadded+55@@ -0,0 +1,55 @@+---+name: adom-vscode-queue+description: "The shared event queue between container processes and the Hydrogen Desktop / Hydrogen Web frontend, hosted by the adom-vscode extension. Any process pushes events (login refresh needed, long-job progress, arbitrary payloads); the frontend pulls when it wants. Survives window reloads. Trigger words: event queue, queue push, queue pull, push event to frontend, notify hd frontend, frontend event, progress dialog event, api key expiring event, login refresh event, queue status, queue peek, queue topic, adom-vscode queue, POST /queue/push, pull events."+---++Parent skill: **adom-vscode**++# adom-vscode-queue, container-to-frontend events++A simple durable FIFO inside the extension. Producers are anything in the+container (a watcher, a build, an AI thread); the consumer is usually the HD/HW+frontend polling when it cares. Events survive VS Code window reloads+(persisted to `~/.local/share/adom-vscode/queue.json`), are capped at 1000+items, and can carry a per-item TTL.++## Verbs++```bash+adom-vscode queue push login --type refresh-needed --payload '{"expiresInHours":24}'+adom-vscode queue push progress --type job-progress --payload '{"job":"bake","pct":40}' --ttl 120+adom-vscode queue pull --topic login # consume matching events (removes them)+adom-vscode queue pull --peek # read WITHOUT consuming+adom-vscode queue pull --max 10 # cap a batch+adom-vscode queue status # depth + per-topic counts+adom-vscode queue clear --topic progress # drop one topic (or everything without --topic)+```++HTTP: `POST /queue/push {topic?, type?, payload?, ttlSec?}` returns `{id, depth}`;+`GET/POST /queue/pull {topic?, max?, peek?}` returns `{items, count, remaining}`;+`GET /queue/status`; `POST /queue/clear {topic?}`.++Each item: `{id, ts, topic, type, payload, ttlSec}`. Default topic is+`default`, default type is `event`. Expired items vanish on the next access.++## Patterns++- **Login refresh**: a container process notices the session key in+ `/var/run/adom/api-key` expires within a day, pushes+ `topic: login, type: refresh-needed`; the frontend pulls, shows the "needs a+ login refresh" banner, refreshes, then injects the new key (see+ **adom-vscode-container** for `apikey set`).+- **Progress dialog**: a long container job pushes `topic: progress` events with+ a TTL a bit above the push interval, so stale progress self-cleans if the+ frontend never pulls.+- **Peek before consume**: a frontend that only renders a badge should+ `--peek`; consume (`pull` without peek) only when the event is handled, so a+ crashed frontend does not eat events.++## Semantics worth knowing++- Pull REMOVES what it returns (unless `peek`). Two consumers splitting one+ topic will race; give each its own topic.+- Depth is bounded at 1000: oldest items drop first past the cap.+- The queue is per-container and in one extension host; a window reload reloads+ it from disk, so nothing is lost across reloads.
skills/adom-vscode-settings/SKILL.mdadded+82@@ -0,0 +1,82 @@+---+name: adom-vscode-settings+description: "Get/set ANY VS Code setting, the color theme, fonts, and font sizes LIVE from inside the container, with no window reload, so active Claude/AI sessions survive. Uses the native VS Code API (ConfigurationTarget.Global), the fix for settings.json merges that hang or need a workbench reload. Also reports the RESOLVED font family the renderer truly shows (document.fonts.check), not just the configured stack. Trigger words: change theme, set theme, vscode theme, dark theme, set font, change font, font size, editor font, terminal font size, chat font, prose font, vscode setting, config get, config set, workbench.colorTheme, editor.fontFamily, editor.fontSize, chat.fontFamily, live settings, no reload, which font is active, resolved font, font not applying, theme without reload."+---++Parent skill: **adom-vscode**++# adom-vscode-settings, live config / theme / fonts++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.++## Any setting++```bash+adom-vscode config get workbench.colorTheme # effective value + default/global/workspace layers+adom-vscode config set editor.fontSize 14 # values parse as JSON when possible, else string+adom-vscode config set workbench.statusBar.visible false+```++HTTP: `GET /config?key=<dotted.key>`, `POST /config {key, value}`.++## Theme++```bash+adom-vscode theme get # active + preferredDark/preferredLight + EVERY installed theme+adom-vscode theme set "Adom Dark" # switches live+```++`theme get` enumerates every theme contributed by installed extensions+(label, uiTheme, owning extension), so you can offer the user a real list.+`theme set` warns (but still applies) if the name is not among installed+themes; a wrong name silently falls back to the default look, so check the+`available` list when a set "didn't take".++HTTP: `GET /theme`, `POST /theme {theme}`.++## Fonts++```bash+adom-vscode font get # all font settings + RESOLVED (truly rendered) families+adom-vscode font set --editor-family "Fira Code" --prose-family Inter --editor-size 14+adom-vscode font-size get+adom-vscode font-size set --editor 14 --terminal 13 --prose 15 --prose-code 13+```++The key map (CLI flag -> settings key):++| Flag | Key | What it styles |+|---|---|---|+| `--editor-family` | `editor.fontFamily` | Code editor |+| `--editor-size` | `editor.fontSize` | Code editor |+| `--terminal-size` | `terminal.integrated.fontSize` | Integrated terminal |+| `--prose-family` | `chat.fontFamily` | Chat prose (Claude panel text) |+| `--prose-size` | `chat.fontSize` | Chat prose |+| `--prose-code-family` | `chat.editor.fontFamily` | Chat code blocks |+| `--prose-code-size` | `chat.editor.fontSize` | Chat code blocks |++HTTP: `GET /fonts`, `POST /fonts {editorFamily?, proseFamily?, proseCodeFamily?,+editorSize?, terminalSize?, proseSize?, proseCodeSize?}` (any subset).++## Resolved fonts, the part HD needs++The configured stack often names fonts that are NOT installed on the rendering+side (the user's browser or the HD webview), so reading the setting alone lies.+`font get` also returns `resolved`: the first family in each stack that the+renderer can truly draw, checked with `document.fonts.check` inside the+workbench (via the Adom sidebar webview). If the sidebar webview is not alive+the response says so (`resolved.via: null` plus a note) and only configured+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+ 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+ see when that is happening.
uninstall.sh+5@@ -23,3 +23,8 @@ fi COMP="${HOME}/.local/share/bash-completion/completions/adom-vscode" [ -f "$COMP" ] && rm -f "$COMP"++for s in adom-vscode adom-vscode-settings adom-vscode-exec adom-vscode-queue adom-vscode-container adom-vscode-extensions adom-vscode-modes; do+ rm -rf "$HOME/.claude/skills/$s"+done+echo "Removed the adom-vscode skill pack."