Files
cdsr/q5vault/operations/extensions.md
Antigravity f52d7ba656 cdsr: wire the omp harness into the IDE as a native agent panel over ACP
Pin formulahendry.acp-client 0.2.0 (Open VSX, MIT, sha256-verified) and point
acp.agents at `omp acp`. OMP already ships an ACP v1 server, so no custom
extension and no marketplace exception were needed.

Verified in the running IDE: status bar `ACP: Oh My Pi`, session/list returns
real prior OMP sessions for the open folder, and a full prompt turn streams
text plus tool-call and plan cards.

Credentials never move: OMP authenticates from ~/.omp via its `agent` auth
method and the extension is given no key.
2026-08-20 17:25:06 +02:00

11 KiB

title, description, source, reviewed
title description source reviewed
🧩 Extensions Pinned Open VSX extension baseline, lock file semantics, install/audit commands, optional/excluded entries, and the LiteLLM AI provider wiring. verified deployment on the loca operator host, 2026-08-19; AI wiring verified in the running IDE 2026-08-20 2026-08-20

🧩 Extension baseline

Pinned baseline (seven entries)

id version platform reason
Continue.continue 2.1.0 linux-x64 Primary open-source AI agent/chat/edit/autocomplete extension.
Anthropic.claude-code 2.1.235 linux-x64 First-party Claude Code IDE integration.
formulahendry.acp-client 0.2.0 universal Generic Agent Client Protocol client; drives the local omp harness as a native agent panel.
ms-python.python 2026.4.0 universal Python language support expected in this environment.
ms-python.debugpy 2026.6.0 linux-x64 Explicit debugger dependency instead of relying on later bootstrap by the Python extension.
ms-toolsai.jupyter 2025.9.1 universal Notebook workflow support in the browser IDE.
ms-azuretools.vscode-containers 2.4.5 universal Current Container Tools extension; its README states it replaces the older Docker extension functionality.

All seven come from config/extensions.lock.json (registry: https://open-vsx.org).

OMP as a native agent panel (ACP)

The omp harness is wired into the IDE over the Agent Client Protocol. No custom extension and no marketplace exception were needed: OMP already ships an ACP server and Open VSX already ships a generic ACP client.

  • agent side: omp acp runs Oh My Pi as an ACP server over stdio. Verified against the installed binary — initialize returns protocolVersion 1 and agentInfo {name: oh-my-pi, version: 17.4.0}, and a full session/new + session/prompt turn streams tool_call, plan, agent_message_chunk, usage_update, stopReason: end_turn
  • client side: formulahendry.acp-client 0.2.0, MIT, engines.vscode ^1.85.0. It declares no extensionKind, so it loads in the remote extension host where Node and child_process exist — a requirement, since the client spawns the agent as a child process
  • protocol versions differ but interoperate: the client bundles ACP SDK ^0.21.1, OMP pins 0.25.0, both negotiate wire version 1
  • configuration lives in data/user/User/settings.json:
"acp.agents": {
  "Oh My Pi": { "command": "/home/loca/.local/bin/omp", "args": ["acp"], "env": {} }
}

VS Code merges this object with the extension's own defaults, so the agent tree shows the shipped entries (Copilot, Claude Code, Gemini, Qwen and others, all of which would npx-fetch at runtime) plus Oh My Pi. Only Oh My Pi is a pinned local binary; treat the rest as unpinned and unsupported here.

Usage: activity bar → ACP Client → ACP: New Conversation → pick Oh My Pi. The status bar shows ACP: Oh My Pi when connected. The chat panel renders OMP's own session config as native controls (mode Default/Plan, model, thinking level), and the agents tree lists real prior OMP sessions for the open folder, because the client calls session/list and OMP answers from ~/.omp/agent/sessions.

Operational notes:

  • credentials never move. OMP authenticates itself from ~/.omp via its agent auth method; the extension is not given any key. This is why the ACP route was chosen over exposing OMP on a loopback port
  • the IDE runs as loca, which holds NOPASSWD: ALL. An OMP session in this panel is therefore root-equivalent, gated only by Authelia one_factor on cdsr.loca.zone. Leave the client's permission prompts enabled; its file and terminal handlers are not workspace-confined
  • OMP's own tools.approvalMode default is permissive and subagents are unconditionally so. Set it explicitly rather than inheriting it
  • one omp acp process serves multiple sessions, but stdio carries a single client, so the IDE panel and a CLI omp are separate processes. They share ~/.omp: session transcripts are per-directory with unique filenames and atomic rewrites, so that is safe, but memory and config are shared context, not isolation
  • OMP cannot be reached over MCP. It implements an MCP client only, so Continue's mcpServers cannot point at it; ACP is the only protocol bridge

Lock file mechanics

config/extensions.lock.json is the single source of truth. Each entry contains id, version, platform, vsix_url, sha256_url, reason, and mode (baseline or optional).

VSIX cache lives in tmp/extensions/ with filenames <id>-<version>@<platform>.vsix.

Install script (scripts/install-extensions.sh):

  • requires python3 (no jq on this host)
  • downloads VSIX + .sha256 into cache if not present
  • verifies sha256 before install
  • installs with code-server --config config/config.yaml --install-extension <abs .vsix> --force

Audit script (scripts/list-extension-versions.sh):

  • runs code-server --list-extensions --show-versions
  • compares against lock file
  • exits non-zero on MISSING or MISMATCH
  • --include-optional extends the check to mode: optional entries

Commands

# install baseline only
cd /home/loca/dev/code-server && ./scripts/install-extensions.sh

# install baseline + optional
./scripts/install-extensions.sh --include-optional

# audit baseline
./scripts/list-extension-versions.sh

# audit baseline + optional
./scripts/list-extension-versions.sh --include-optional

Transitively installed (expected, unpinned)

id version note
ms-python.vscode-python-envs 1.36.0 Python extension dependency
ms-toolsai.jupyter-keymap 1.1.2 Jupyter dependency
ms-toolsai.jupyter-renderers 1.3.0 Jupyter dependency
ms-toolsai.vscode-jupyter-cell-tags 0.1.9 Jupyter dependency
ms-toolsai.vscode-jupyter-slideshow 0.1.6 Jupyter dependency

These are not in the lock file and will vary; they are expected by-products of the baseline install.

Optional: Cody (enterprise only)

id version platform reason
sourcegraph.cody-ai 1.155.0 universal Useful only with a Cody Enterprise account; the Open VSX README states it is no longer available for non-enterprise users.

Opt-in:

./scripts/install-extensions.sh --include-optional

Exclusions (recorded in lock file)

id reason
TabNine.tabnine-vscode Open VSX listing marks it legacy and states it does not onboard new users.
GitHub.copilot Microsoft-marketplace-only AI tooling; code-server cannot rely on Microsoft marketplace terms or access.

Any Microsoft-marketplace-only AI extensions fall under the same exclusion.

Where extension configuration actually lives

Extension config is not under data/user/. The unit sets HOME=/home/loca, so extensions that resolve their own paths from $HOME write outside the project — see architecture/runtime-topology#state-outside-the-project.

  • Continue writes /home/loca/.continue/ — its real configuration and history, not data/user/
    • config.yaml — mode 600, holds provider settings; never commit it, never paste its contents into the wiki or project files
    • also config.ts, .continuerc.json, index/, sessions/, dev_data/, .utils/
  • version nuance for the pinned 2.1.0 build
    • it still contributes continue.remoteConfigServerUrl, continue.userToken and continue.remoteConfigSyncPeriod for shared/team config sync, sync period defaulting to 60 minutes
    • none of those three carries a deprecation message; the only deprecated setting is continue.telemetryEnabled, whose deprecation message points at Telemetry > Allow Anonymous Telemetry on the extension's User Settings page
    • so Continue configuration is not local-only in this build; this deployment simply leaves remote sync unconfigured
  • Claude Code reuses the operator's pre-existing /home/loca/.claude/ and /home/loca/.claude.json, shared with the host Claude Code CLI — it is not deployment-owned state and is not created by the extension install
  • backup targets: /home/loca/dev/code-server/ plus /home/loca/.continue/; the project directory alone misses Continue's config and chat sessions

AI provider wiring (LiteLLM gateway)

Continue is wired to the host LiteLLM gateway (lllm, loopback 127.0.0.1:52001) — no cloud provider sign-in is used. The gateway is reachable from the IDE because code-server and LiteLLM run on the same host.

  • credential: a dedicated LiteLLM virtual key with alias cdsr-ide, scoped to the three model groups below. The master key is never placed in a client config.
  • key file: /home/loca/dev/code-server/.ai-credentials (mode 600, gitignored, single line litellm_ide_key=). The value is also present in /home/loca/.continue/config.yaml (mode 600). Neither value belongs in this wiki, the repo, or a systemd unit.
  • client config: /home/loca/.continue/config.yaml, three models, all provider: openai against apiBase: http://127.0.0.1:52001/v1. Shape validated against the extension's own config-yaml-schema.json (name, model, provider required; roles enum accepts chat, edit, apply, autocomplete).
model upstream roles live state
free OpenRouter nvidia/nemotron-3.5-lightning:free chat, edit, apply, autocomplete working — verified chat round-trip in the Continue panel
oss-120b Groq openai/gpt-oss-120b chat, edit, apply reachable, but Groq free-tier caps 8000 tokens/minute and Continue's agent prompt is ~8.6k, so chat returns RateLimitError
fast Groq llama-3.1-8b-instant chat, edit, apply broken upstream — Groq decommissioned the model, every call returns 404 model_not_found. Defect belongs to the lllm stack config, not this one

Practical consequence: select free in the model picker. Repairing oss-120b/fast means editing dev/lllm/config/config.yaml (a different stack) — not a cdsr change.

Workspace Trust gate: a fresh browser profile opens /home/loca in Restricted Mode, which silently disables every third-party extension — no Continue or Claude Code icon in the activity bar and no Continue: commands in the palette. Fix: Command Palette → Workspaces: Manage Workspace Trust → Trust. Symptom is indistinguishable from a failed install, so check trust before re-installing anything.

Claude Code is deliberately NOT wired to LiteLLM. The gateway does expose an Anthropic-compatible /v1/messages passthrough, but the reference probe model (fast) fails for the upstream reason above, so the extension stays on its interactive /login (browser OAuth) against an Anthropic account. Session state lives in the operator-wide /home/loca/.claude/ and /home/loca/.claude.json, not in data/user/.

Cody (optional, only if enabled): sign in via the Cody panel; requires an Enterprise subscription.

"extensions.autoUpdate": "off" and "update.mode": "manual" are the deployed values in data/user/User/settings.json — code-server normalized the seeded false to the string "off" at first run, and "off" and false mean the same thing (auto-update disabled). Version drift only happens by updating config/extensions.lock.json and re-running the install script.