Right-click now opens the session menu under the cursor (the sidebar's context-menu pattern; the same header-supplied items back both the "..." dropdown and the context menu via injected menu primitives) and still never changes the active tab. Hovering a tab shows the sidebar's session tooltip — title, last-activity time, project, branch and PR status — after a delay, suppressed while a menu is open or a drag is in flight. Each tab carries the sidebar's status dot at its end (accent while the session runs, info-blue for unread), hidden while the hover controls overlay it. Tab titles fade out instead of ending in "...", and while the active tab is renaming its hover controls stay hidden so only the rename controls show.
6.5 KiB
VS Code Backend Modules
This document describes backend runtime modules used by the VS Code extension bridge (packages/vscode/src/bridge.ts).
Purpose
Keep bridge.ts as a thin orchestration layer that delegates message handling to cohesive domain runtimes while preserving API behavior.
Runtime modules
-
bridge.ts- Entry orchestration layer for bridge messages.
- Delegates to specialized runtimes in order and handles only unmatched fallthrough cases.
-
bridge-git-runtime.ts- Standard Git message handlers.
-
bridge-git-special-runtime.ts- Specialized Git flows (
pr-description,conflict-details) and generation helpers.
- Specialized Git flows (
-
bridge-git-process-runtime.ts- Git process execution and environment setup (
execGit), including SSH agent socket resolution.
- Git process execution and environment setup (
-
gitService.ts- Owns VS Code Git and worktree operations.
- Fast worktree creation reports bootstrap phases explicitly:
directory-created, thengit-readyafter Git population/upstream work, andsetup-readyafter setup commands. Existing worktrees without tracked bootstrap state fall back toready/setup-ready; shared webview consumers also accept legacy responses withoutphase. - Worktree removal waits for an active create/bootstrap task for the same directory so background Git and setup work cannot race deletion or restore stale bootstrap state.
- Worktree population enables Git
core.longpaths(local repo config plus-c core.longpaths=trueongit reset --hard) so deeply nested checkouts under the managed data-dir worktree root do not fail on Windows MAX_PATH with "Filename too long".
-
bridge-fs-runtime.ts- Bridge handlers for filesystem-related message routes.
- Uses shared FS helpers via injected dependencies.
-
bridge-fs-helpers-runtime.ts- Filesystem/path/search helper functions:
- path normalization and resolution
- directory listing
- file search
- file read path safety checks
- active-directory selection across multi-root workspaces
- dropped-file parsing and attachment reading
- models metadata fetch helper
- Read paths are authorized in the requested workspace path space before symlink resolution, matching the web runtime; directly requested outside-workspace paths remain denied.
- Filesystem/path/search helper functions:
The webview CSP permits blob: only for worker-src so shared UI parsers can run bounded local decompression off the main thread. Blob scripts remain disallowed by script-src.
The webview build emits each worker as one self-contained file. VS Code webviews cannot load workers directly from extension resource URLs or load module imports from inside a worker. The shared Shiki client therefore fetches the built worker, starts it from a blob: URL, and relies on the worker CSP allowance above.
-
bridge-localfs-proxy-runtime.ts- Local
/api/fs/readand/api/fs/rawproxy helpers and shared proxy utility helpers. - Workspace-contained Markdown gallery images use these local filesystem routes without calling the server grant route. Grant requests for OpenCode temporary-directory images return an explicit unsupported response instead of being forwarded to OpenCode.
- Local
-
bridge-proxy-runtime.ts- Proxy route handlers (
api:proxy,api:session:message) with injected helper dependencies. - SSE routes are intentionally excluded from the generic proxy and use
sseProxy.ts, whose upstream-only stall watchdog closes a quiet OpenCode stream so the webview can reconnect instead of trusting an open but silent response. - The webview allocates each SSE stream ID and installs its listener before requesting the upstream stream, so immediate OpenCode replay events cannot race the bridge start response.
- Proxy route handlers (
-
bridge-config-runtime.ts- Config and skills message handlers (
api:config/*). - Includes OpenCode resolution diagnostics parity handler used by shared UI (
/api/config/opencode-resolution). - OpenCode JSONC reads in
opencodeConfig.tsfail closed on a partial or non-objectjsonc-parsertree (INVALID_JSONC) so mutations cannot rewrite a$schema-only stub over an existing config. Comment-only files read as empty, while other content that yields no JSON value (YAML, plain text) fails closed. A broken layer is omitted from the merge and recorded onlayerErrors; valid sibling layers still load, including plugin list/read viagetPluginConfigSources. Writes still refuse to overwrite the broken file.
- Config and skills message handlers (
-
bridge-settings-runtime.ts- Settings read/write and OpenCode skills discovery via API for bridge consumers.
-
bridge-system-runtime.ts- System/editor/provider/quota/notification/update-check message handlers.
- Includes session activity snapshot bridge handler used by webview parity routes (
/api/session-activity). - Includes Zen utility model parity handler used by shared notification settings (
/api/zen/models). - Owns managed OpenCode upgrade status and mutation handlers, including capability reporting, upgrade serialization, and process restart after a successful upgrade.
- Provider handlers cover source lookup, disconnect (
DELETE /api/provider/:id/auth), and custom provider upsert (PUT /api/provider; create/update OpenAI-compatible config with explicitscopefor user/project/custom layers; requiresenvor stored auth; secrets via OpenCode auth API).
-
opencode-upgrade-runtime.ts- Owns managed-versus-external capability decisions, latest-version checks, serialized OpenCode self-upgrades, and restart-after-upgrade behavior.
-
bridge-permission-auto-accept-runtime.ts- Owns the persisted VS Code permission auto-accept policy and its GET/PUT bridge contract.
- Serializes reads and read-modify-write updates, persists a monotonic policy revision, and broadcasts the exact committed snapshot to every active OpenChamber webview. Permission replies remain foreground UI-owned because VS Code does not run the OpenChamber server runtime.
Shared webview message ordering
Message and part ordering is owned by packages/ui/src/sync/DOCUMENTATION.md. The VS Code webview consumes that shared sync implementation; bridge and proxy runtimes pass OpenCode records through without adding runtime-specific ordering.
Extension guideline
When adding new bridge route families:
- Prefer creating or extending a domain runtime module under
packages/vscode/src/bridge-*-runtime.ts. - Keep
bridge.tsfocused on delegation order and minimal fallthrough behavior. - Inject dependencies into runtimes instead of reaching into unrelated modules directly.