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.
153 lines
11 KiB
Markdown
153 lines
11 KiB
Markdown
---
|
|
title: 🧩 Extensions
|
|
description: Pinned Open VSX extension baseline, lock file semantics, install/audit commands, optional/excluded entries, and the LiteLLM AI provider wiring.
|
|
source: verified deployment on the loca operator host, 2026-08-19; AI wiring verified in the running IDE 2026-08-20
|
|
reviewed: 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`:
|
|
|
|
```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
|
|
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
./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. |