Commit graph

2 commits

Author SHA1 Message Date
JD Davis
1aa701adaa
fix(vscode): persist compatible Claude modes and route Copilot CAPI (#2986)
## Description

Fixes #2492, #2028, and #2827.

Claude daemon workers consume project settings rather than reliably
inheriting wrapper environment state, while the Claude VS Code webview
cannot render deferred-tool response blocks. Separately, recent Copilot
Chat versions use the whole CAPI override for generation; the legacy
proxy override alone only sends model discovery through Headroom.

This PR carries both integrations through to the actual consumers
instead of only changing their launch-time surface configuration.

## Type of Change

- [x] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
- [ ] Build / CI

## Changes Made

- Persist the resolved Claude ENABLE_TOOL_SEARCH value into project
settings for daemon workers and restore it transactionally after wrap
exits.
- Use compatibility-safe Foundry and Claude VS Code defaults while
preserving explicit user choices.
- Configure both Copilot overrideProxyUrl and overrideCapiUrl in the
reversible managed VS Code settings block.
- Route Copilot unprefixed POST /chat/completions and HTTP /responses
requests through the real compression handlers.
- Keep /responses out of the Codex WebSocket aliases because Copilot and
Codex use different WebSocket wire protocols.
- Extend wrap E2E assertions for both the Claude webview mode and
Copilot CAPI routing.

## Testing

- [x] 127 combined Claude, Copilot, route-integration, and MCP
dependency-contract tests pass.
- [x] Ruff check passes on all changed Python files.
- [x] Ruff format check passes.
- [x] Python compilation and git diff --check pass.

## Runtime Safety

Standalone Claude CLI defaults remain unchanged. Explicit Claude
tool-search values retain precedence, and project settings are restored
through the existing cleanup path. Copilot model/session helper
endpoints continue through generic passthrough, while only validated
HTTP generation paths receive explicit compression routes. Existing
Codex WebSocket behavior is unchanged.

## Review Readiness

- [x] Current main and MCP v1 compatibility retained
- [x] Worker-facing Claude persistence covered
- [x] Reversible Copilot and Claude settings behavior covered
- [x] Copilot generation routes covered at registration and proxy
integration layers
- [x] Ready for review
2026-08-13 15:06:41 -05:00
JD Davis
13a310a00d
feat(claude): support Claude Code in VS Code (#2752)
## Description Add first-class Headroom support for the official Claude
Code extension in VS Code. The new wrapper starts the local proxy,
configures the Claude Code user settings consumed by the embedded
extension process, preserves authentication and model selection, and
provides a conflict-safe reversible unwrap lifecycle. Closes # ## Type
of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [x]
New feature (non-breaking change that adds functionality) - [ ] Breaking
change (fix or feature that would cause existing functionality to
change) - [x] Documentation update - [ ] Performance improvement - [ ]
Code refactoring (no functional changes) ## Changes Made - Add `headroom
wrap vscode-claude` and `headroom unwrap vscode-claude`. - Configure
project-scoped `ANTHROPIC_BASE_URL` plus `ENABLE_TOOL_SEARCH=true` in
Claude Code user settings while preserving existing values. - Respect
`CLAUDE_CONFIG_DIR`, macOS/Linux home paths, Windows `USERPROFILE`,
custom `--settings-file`, and `--no-configure`. - Add durable
Headroom-owned restore state and refuse malformed settings or
conflicting user edits. - Add unit, CLI, and Docker-harness e2e coverage
for configuration, real proxy forwarding, and restoration. - Document
setup, remote development, undo, and troubleshooting. ## Testing - [x]
Unit tests pass (`pytest`) - [x] Linting passes (`ruff check .`) - [x]
Type checking passes (`mypy headroom`) - [x] New tests added for new
functionality - [x] Manual testing performed ### Test Output ```text $
UV_NO_SYNC=1 uv run pytest -q
tests/test_provider_claude_vscode_config.py
tests/test_cli/test_wrap_vscode_claude.py
tests/test_cli/test_wrap_vscode.py
tests/test_cli/test_wrap_claude_base_url.py
tests/test_provider_copilot_vscode_config.py tests/test_copilot_auth.py
160 passed in 0.45s $ UV_NO_SYNC=1 uv run ruff check . All checks
passed! $ UV_NO_SYNC=1 uv run mypy headroom Success: no issues found in
512 source files $ npm run build # from docs/ Compiled successfully;
generated 155 static pages ``` ## Real Behavior Proof - Environment:
macOS, Python 3.13 editable install, isolated temporary HOME and Claude
settings, local mock Anthropic Messages upstream. - Exact command /
steps: invoked the new `verify_vscode_claude_wrap` e2e function, which
launched real `headroom wrap vscode-claude`, waited for proxy readiness,
POSTed an Anthropic `/v1/messages` request through the generated
project-scoped URL, stopped the wrapper, then ran `headroom unwrap
vscode-claude`. - Observed result: HTTP 200 with the mock Claude
response through Headroom; generated settings retained unrelated values
and enabled tool deferral; unwrap restored the original Claude settings.
- Not tested: real Anthropic account traffic or the full Docker image
locally because Docker Desktop was unavailable. The same e2e function is
wired into the existing Docker wrap CI job. ## Review Readiness - [x] I
have performed a self-review - [x] This PR is ready for human review ##
Checklist - [x] My code follows the project style guidelines - [x] I
have performed a self-review of my code - [x] I have commented my code,
particularly in hard-to-understand areas - [x] I have made corresponding
changes to the documentation - [x] My changes generate no new warnings -
[x] I have added tests that prove my fix is effective or that my feature
works - [x] New and existing unit tests pass locally with my changes -
[x] I did **not** edit `CHANGELOG.md` — it is generated by
release-please from my Conventional Commit PR title (a CI guard enforces
this) ## Screenshots (if applicable) Not applicable; this adds CLI
configuration and proxy routing without changing VS Code UI. ##
Additional Notes The wrapper deliberately leaves the endpoint configured
when stopped so requests fail closed instead of silently bypassing
Headroom. `headroom unwrap vscode-claude` restores the exact prior
managed values and preserves unrelated settings.

---------

Co-authored-by: JD Davis <jd@jds-macbook-air.tail2a279.ts.net>
2026-08-03 20:14:13 -07:00