Skip to content

feat: move VS Code behind app server - #196

Merged
oratis merged 24 commits into
mainfrom
codex/vscode-protocol-runtime
Aug 2, 2026
Merged

feat: move VS Code behind app server#196
oratis merged 24 commits into
mainfrom
codex/vscode-protocol-runtime

Conversation

@oratis

@oratis oratis commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • run the VS Code extension through the shared protocol client and an isolated app-server child process
  • preserve canonical threads, structured events, approvals, user input, interruption, and resume semantics in the editor
  • build and package a real extension/app-server VSIX while keeping provider and credential code out of the extension host

Validation

  • pnpm format:check
  • pnpm lint (one pre-existing warning)
  • pnpm typecheck
  • pnpm test (960 passed, 12 skipped)
  • pnpm build
  • pnpm docs:check
  • packaged VSIX: 8 files, 72.24 KB
  • syntax checked both bundles and verified the extension bundle contains no provider, credential resolver, API-key, or RuntimeHost implementation

Stack

Depends on #195.

@oratis
oratis changed the base branch from codex/lsp-protocol-client to main August 2, 2026 06:36
@oratis
oratis marked this pull request as ready for review August 2, 2026 06:43
@oratis

oratis commented Aug 2, 2026

Copy link
Copy Markdown
Owner Author

Review: approved ✅

Largest PR in the stack (+2633) and it completes the thin-client migration: desktop (#192), LSP (#195), and now VS Code all speak the same protocol to the same app-server.

What I checked

  • Provider and credential code stay out of the extension host, and the app-server runs as an isolated child process. VS Code extensions share a host process with every other installed extension — keeping credentials out of that address space is the right threat model, and it's a materially stronger position than the pre-Runtime safety: mandatory policy and real cancellation #181 state where this extension could skip the permission gate entirely.
  • Canonical threads, structured events, approvals, user input, interruption, and resume all preserved in the editor. This is the acceptance bar that matters: a thin client that loses interruption or resume is a downgrade users would feel immediately.
  • A real VSIX is built and packaged, not just typechecked. Extension packaging fails in ways compilation doesn't (missing files, wrong entry point, activation events), so exercising the real artifact is the only meaningful check — and ci: enforce app-server release gates #208 turns it into a gate.

Consuming the shared client from #194 rather than a bespoke implementation is what keeps this reviewable at this size — most of the line count is protocol wiring and tests, not new policy.

Validation: CI green; VS Code 12 tests pass locally at the stack tip.

@oratis
oratis merged commit 030868a into main Aug 2, 2026
5 checks passed
oratis added a commit that referenced this pull request Aug 2, 2026
…#214)

Reworks #166, which was correct in approach but is now incomplete and
carries stale docs.

`permissions.additionalDirectories` has been declared in the settings
schema and read by /permissions for display, but consumed for
enforcement nowhere — /add-dir only printed "recorded ... (effective in
M3)". Users could reasonably believe it did something.

Why the sandbox is the right boundary: the file tools (Read/Write/Edit/
Glob/Grep) already accept any absolute path, so there is no cwd
containment to widen. The only thing that actually restricts writes is
the OS sandbox wrapping Bash. Enforcing /add-dir therefore means adding
those directories to `filesystem.allowWrite`.

The part #166 could not have covered: it predates the app-server, and
wired only CLI REPL + headless. Since #192/#195/#196, desktop, VS Code
and LSP all run through apps/server, so that wiring would have enforced
the setting in the CLI and silently ignored it everywhere else — for a
security-relevant setting, partial enforcement is worse than none,
because it is indistinguishable from full enforcement at the UI. All 7
sandbox assembly sites across 4 files now route through the helper.

- core `withAdditionalWritableDirs(sandbox, dirs, cwd?)`: pure, never
  mutates input, no-op when the sandbox is disabled (never silently
  enables it), dedupes, and drops non-absolute entries rather than
  handing them to profile writers that require absolute paths
- /add-dir validates the path is an existing directory, stores it
  absolute (resolved against cwd), refuses duplicates, and lists the
  current set with no args
- BEHAVIOR_PARITY: only the /add-dir row changes. #166 rewrote the whole
  table with June-era content that would have regressed /btw, /voice,
  /tasks and /background back to unshipped. (Prettier reflows the table
  columns; `git diff -w` shows the 2 real lines.)

tsc -b --force, lint (--max-warnings=0), format:check, docs:check clean;
1048 tests pass (9 new helper + 6 new /add-dir); build clean.

Co-authored-by: t <t@t>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant