Download

adom-vscode — VS Code Extension + Rust CLI

Context

Docker processes (shotlog, gallia, Claude Code) need to control VS Code (code-server) programmatically — open files, reveal folders, search/install extensions, start new Claude Code chats. The Hydrogen workspace API only controls the outer shell; VS Code is an iframe running code-server with its own API. A VS Code extension inside code-server exposes a local HTTP server, and a Rust CLI wraps those calls for the AI.

Source lives in its own repo adom-inc/adom-vscode. Pre-built binary + VSIX attached to GitHub Releases. gallia/install.mjs downloads them — no Rust toolchain needed on user containers.

Architecture

Claude Code / scripts / shotlog
    ↓  runs CLI
adom-vscode open /foo/bar.png
    ↓  HTTP POST to localhost:8821
Adom VS Code Extension (inside code-server)
    ↓  vscode.* API
VS Code UI

File Structure

Repo: adom-inc/adom-vscode

/home/adom/project/adom-vscode/
├── extension/
│   ├── package.json                   — Extension manifest
│   ├── src/extension.ts               — HTTP server + route handlers
│   ├── tsconfig.json                  — TS config (IDE only, esbuild compiles)
│   └── .vscodeignore                  — Exclude src/ from VSIX
├── cli/
│   ├── Cargo.toml                     — Rust CLI
│   └── src/main.rs                    — CLI entry (clap, raw HTTP client)
├── SKILL.md                           — Claude Code skill (CLI usage, endpoints, modes)
├── COMMANDS.md                        — Full VS Code + extension command reference
├── ARCHITECTURE.md                    — This plan file, saved permanently
├── README.md                          — Project overview, links to ARCHITECTURE.md
├── build.sh                           — Local build + install (dev only)
└── .gitignore

Distribution (GitHub Releases on adom-inc/adom-vscode):

  • adom-vscode — single pre-built Linux x86_64 binary (embeds VSIX + SKILL.md via include_bytes!/include_str!)

Gallia integrationinstall.mjs downloads the one binary, then self-installs:

  • gh release download/usr/local/bin/adom-vscode
  • adom-vscode install-extension (extracts embedded VSIX, installs into code-server)
  • adom-vscode skills install (writes embedded SKILL.md to ~/.claude/skills/)

Extension (TypeScript)

Port: 8821 (127.0.0.1 only)

Endpoints

Method Path Body VS Code API
GET /health
POST /open {"path":"..."} showTextDocument(uri)
POST /reveal {"path":"..."} executeCommand('revealInExplorer')
POST /preview-markdown {"path":"..."} executeCommand('markdown.showPreview')
POST /extensions/search {"query":"..."} executeCommand('workbench.extensions.search')
POST /extensions/install {"id":"..."} executeCommand('workbench.extensions.installExtension')
POST /claude/new {} executeCommand('claude-vscode.newConversation')
POST /command {"command":"...","args":[]} executeCommand(cmd, ...args)
POST /notify {"message":"...","level":"info"} showInformationMessage()
POST /mode/claudecode {} See below — enters Claude Code-only mode
POST /mode/reset {} Restores default VS Code layout

Claude Code-only mode (POST /mode/claudecode)

Strips VS Code down to just a Claude Code chat. For onboarding new users.

The handler runs these VS Code commands in sequence:

  1. workbench.action.closeAllEditors — clear all tabs
  2. workbench.action.closeSidebar — hide file explorer
  3. workbench.action.closePanel — hide terminal/bottom panel
  4. workbench.action.toggleActivityBarVisibility — hide left icon strip (check if visible first via config)
  5. workbench.action.toggleStatusBarVisibility — hide bottom status bar
  6. claude-vscode.editor.open — open Claude Code in full-width editor tab

Result: clean full-screen AI chat, nothing else.

POST /mode/reset reverses it — shows activity bar, status bar, sidebar.

URL-based auto-trigger (?mode=claudecode)

Code-server persists all URL query params to ~/.local/share/code-server/coder.json under the query key. When a user visits https://slug.adom.cloud/?mode=claudecode, that file becomes:

{ "query": { "folder": "...", "mode": "claudecode" } }

On extension activation, read that file and check query.mode:

const coderSettings = JSON.parse(fs.readFileSync(
  path.join(os.homedir(), '.local/share/code-server/coder.json'), 'utf-8'
));
if (coderSettings.query?.mode === 'claudecode') {
  await enterClaudeCodeMode();
}

No temp files, no middleware, no proxy changes. Just the URL param and the extension.

Key details

  • activationEvents: ["*"] — starts with code-server
  • Node.js http module (built into extension host), zero runtime deps
  • CORS headers, EADDRINUSE retry, context.subscriptions cleanup
  • On activate: read ~/.local/share/code-server/coder.json for query.mode auto-trigger
  • Build: esbuild bundles to single out/extension.js (~3KB)
  • Package: npx @vscode/vsce package --no-dependencies

Rust CLI

Binary: adom-vscode

# File operations
adom-vscode open /path/to/file.png
adom-vscode reveal /path/to/folder/
adom-vscode preview /path/to/README.md

# Extensions
adom-vscode extensions search "python"
adom-vscode extensions install ms-python.python

# Claude Code
adom-vscode claude new

# UI modes
adom-vscode mode claudecode
adom-vscode mode reset

# Generic VS Code command (escape hatch)
adom-vscode command workbench.action.toggleSidebarVisibility
adom-vscode command workbench.action.reloadWindow

# Notifications
adom-vscode notify "Build complete!" --level info

# Skill management
adom-vscode skills install
adom-vscode skills list

# Extension management
adom-vscode install-extension          # writes embedded VSIX to /tmp, installs into code-server

# Health
adom-vscode health

AI-oriented output

OK: Opened /home/adom/project/README.md in VS Code tab.
OK: Revealed /home/adom/project/src/ in VS Code Explorer sidebar.
OK: Opened new Claude Code conversation in VS Code.

ERROR: Cannot connect to adom-vscode extension on port 8821.
Hint: The extension may need a window reload. Install with: bash /home/adom/project/adom-vscode/build.sh

Deps: clap, serde_json only. Raw TCP HTTP client (no reqwest).

Gallia Integration

install.mjs addition (~line 136, after adom-cli install)

// ── Install adom-vscode (binary + extension from GitHub Releases) ─────
console.log('\n1e. Installing adom-vscode...');
{
  try {
    execSync(
      'gh release download --repo adom-inc/adom-vscode --pattern "adom-vscode" --output /usr/local/bin/adom-vscode --clobber',
      { stdio: 'ignore' }
    );
    execSync('sudo chmod +x /usr/local/bin/adom-vscode', { stdio: 'ignore' });
    console.log('   ✓ adom-vscode CLI installed');
  } catch { console.log('   ⚠ Could not download adom-vscode CLI'); }

  // Self-install extension + skill (both embedded in binary)
  try {
    execSync('adom-vscode install-extension', { stdio: 'ignore' });
    console.log('   ✓ adom-vscode extension installed');
  } catch { console.log('   ⚠ Could not install adom-vscode extension'); }
  try {
    execSync('adom-vscode skills install', { stdio: 'ignore' });
    console.log('   ✓ adom-vscode skills installed');
  } catch { console.log('   ⚠ Could not install adom-vscode skills'); }
}

build.sh (dev only — for building locally before cutting a release)

  1. cd extension && npm install && npx esbuild ... && npx @vscode/vsce package
  2. Install VSIX into local code-server
  3. cd ../cli && cargo build --release && sudo cp target/release/adom-vscode /usr/local/bin/

Releasing

cd /home/adom/project/adom-vscode
bash build.sh
gh release create v0.1.0 \
  cli/target/release/adom-vscode \
  --repo adom-inc/adom-vscode \
  --title "v0.1.0" --notes "Initial release — single binary ships CLI + extension + skill"

Implementation Steps

  1. Create extension/ — package.json, tsconfig.json, .vscodeignore, src/extension.ts
  2. Build + package VSIX, install into code-server
  3. Reload VS Code window, verify curl http://127.0.0.1:8821/health
  4. Test each endpoint with curl
  5. Create cli/ — Cargo.toml, src/main.rs
  6. Build CLI, install to /usr/local/bin/
  7. Test: adom-vscode health, adom-vscode open /path/to/file
  8. Write SKILL.md + build.sh
  9. Add install.mjs hook
  10. Add row to main adom SKILL.md capabilities table
  11. Update shotlog filepath links to use adom-vscode open instead of code-server CLI directly

Verification

curl http://127.0.0.1:8821/health
adom-vscode open /home/adom/project/shotlog/data/test/shot-2026-03-28T13-43-30.png
adom-vscode reveal /home/adom/project/shotlog/data/test/
adom-vscode claude new
adom-vscode extensions search "python"
adom-vscode notify "Hello from adom-vscode!"

Critical Files

File Purpose
/home/adom/project/adom-vscode/extension/src/extension.ts HTTP server + VS Code API handlers
/home/adom/project/adom-vscode/extension/package.json Extension manifest
/home/adom/project/adom-vscode/cli/src/main.rs Rust CLI
/home/adom/project/adom-vscode/SKILL.md Claude Code skill (embedded in binary)
/home/adom/project/adom-vscode/ARCHITECTURE.md This plan file
/home/adom/project/adom-vscode/README.md Project overview
/home/adom/project/adom-vscode/build.sh Build + install script
/home/adom/gallia/install.mjs Add download hook (~line 136)