Skip to content

Point the Claude Code and Codex VS Code extensions at Unity Gateway - #874

Open
GirishS2093 wants to merge 4 commits into
databricks:mainfrom
GirishS2093:pr/vscode-extensions
Open

GirishS2093 wants to merge 4 commits into
databricks:mainfrom
GirishS2093:pr/vscode-extensions

Conversation

@GirishS2093

@GirishS2093 GirishS2093 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Both extensions start their agent themselves rather than through ug claude / ug codex, so they never see ug's gateway settings and ask for an Anthropic or ChatGPT sign-in. Two commits:

Claude Code extension

  • New stdlib-only console script ug-claude-vscode, used as claudeCode.claudeProcessWrapper: it runs the Claude binary the extension passes and adds ug's --settings.
  • When ug configure sets up Claude Code, it finds every VS Code / Insiders profile with the extension (via globalStorage/storage.json and each profile's extensions.json) plus the VS Code Server's Machine settings, on Windows, macOS and Linux, and sets claudeProcessWrapper, disableLoginPrompt and (if unset) initialPermissionMode.
  • Leaves settings.json files with comments alone (prints the lines to add) and never replaces a wrapper that isn't ug's; --dry-run writes nothing; ug revert removes only what ug added.

Codex extension

  • The extension runs its own bundled Codex, which reads only Codex's config files. On Linux/macOS ug's /etc/codex/managed_config.toml already covers it; on Windows (and when that privileged write is skipped) nothing does.
  • When Codex is configured and any VS Code profile has openai.chatgpt, ug writes the keys it puts in the machine-wide file (model_provider, the admin's default model, [model_providers.Databricks]) into ~/.codex/config.toml, unless the machine-wide file already points at this gateway. This copy waits 30 s for ug auth-token (the extension's Codex starts it while starting itself; on Windows that took 8–9 s, so every request timed out at 5 s).
  • A foreign model_provider is left alone with a warning; --dry-run writes nothing; ug revert removes only those keys and restores a previous model.

Tests: tests/test_vscode.py, tests/test_vscode_wrapper.py, TestVSCodeExtension in test_agent_codex.py (18), CLI revert wiring. Checked on Windows 11 against real VS Code profiles, with the real Claude CLI through the wrapper (including the stream-JSON exchange the extension uses), and with the Codex extension's bundled Codex (0.155) through the gateway, confirmed in a live VS Code window; on WSL the extension's Linux Codex used /etc/codex/managed_config.toml.

Related: #808 writes Claude's gateway settings to ~/.claude/settings.json when the managed file can't be written, so the IDE extension keeps using the gateway. Worth agreeing which approach upstream wants for the Claude extension.

Integration tests: none (needs VS Code in CI). A configure-level journey with a fake VS Code profile directory as scenario input is possible if wanted.

Results: on its own on Windows 11, 76 VS Code/extension tests pass; on Linux lint passes and the unit suite matches main (2920 passed; the same 4 environmental user-agent failures).

Update, 11 Oct: rebased onto main (3754d13), plus two follow-up commits found while using the extensions with an admin-managed config:

  • Replace a Claude Code extension wrapper that no longer exists. ug still leaves a working foreign claudeCode.claudeProcessWrapper alone. But a wrapper whose file is gone (for example a hand-made one that was uninstalled) only makes the extension fail with "Claude Code native binary not found", so ug now takes that setting over, says so, and ug revert removes it instead of restoring the dead path.
  • Route the Codex extension through a provider or Unity Catalog schema. With a Model Provider Service (admin-managed or --provider) or a Unity Catalog schema, ug codex adds the routing header at launch and publishes that source's model list. The extension never launches through ug, so its config.toml copy had no routing header: with a managed Azure OpenAI provider its requests skipped the provider and failed, and its model list stayed on the previous source. The copy now carries the routing header, and ug configure publishes the routed model list too (a failure only warns). ug's own files still keep launch routing headers out.

ug-claude-vscode now starts Claude through ucode.os_compatibility.subprocess_cross_os.run, per main's new lint rule.

Results after the update (ruff check, ruff format --check, ty check src/, pytest --ignore=tests/test_e2e.py): on Linux (Ubuntu on WSL) lint ok, 4069 passed, 1 failed (the OpenCode user-agent e2e test, which fails on main here too). On Windows 11 together with #873: lint ok, 4009 passed, 2 failed (the OpenCode user-agent e2e test and one test unrelated to this PR); the extension tests also pass on Windows with this PR alone.

🤖 Generated with Claude Code

GirishS2093 and others added 4 commits October 11, 2026 13:10
The extension starts Claude from VS Code's own settings, not through `ug claude`,
so it never sees ~/.claude/ucode-settings.json and signs in to Anthropic. It can
launch Claude through a claudeCode.claudeProcessWrapper executable, so:
- Add a stdlib-only `ug-claude-vscode` console script that runs the Claude binary
  the extension passes, adding ug's --settings.
- When `ug configure` sets up Claude Code, find every VS Code / VS Code Insiders
  profile with the extension (plus the VS Code Server's Machine settings) on
  Windows, macOS and Linux, and set claudeProcessWrapper, disableLoginPrompt and,
  if unset, initialPermissionMode. settings.json files with comments and
  wrappers that aren't ug's are left alone (with the lines to add printed), and
  --dry-run writes nothing.
- `ug revert` removes only what ug added (recorded in
  ~/.ucode/vscode-claude-extension.json).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Codex extension runs its own bundled Codex, which reads only Codex's config files and
never the ucode.config.toml layer `ug codex` passes on the command line. On Linux and
macOS the machine-wide /etc/codex/managed_config.toml already carries ug's provider to it;
on Windows (and when that privileged write is skipped) nothing does, so it asked for a
ChatGPT sign-in.

When Codex is configured and any VS Code profile or the VS Code Server has the extension
(openai.chatgpt), write the keys ug puts in the machine-wide file (model_provider, the
admin's default model, [model_providers.Databricks]) into ~/.codex/config.toml, unless the
machine-wide file already points at this gateway:
- The copy waits 30 s for `ug auth-token`: the extension's Codex starts it while itself
  starting, and on Windows that took 8-9 s, so every request timed out at 5 s.
- The admin's default model is pinned; otherwise Codex starts on the catalog's first
  entry, which the gateway may reject.
- A foreign model_provider is left alone with a warning; identical hand-added keys are
  taken over; --dry-run writes nothing.
- `ug revert` removes only those keys and restores a previous model (recorded in
  ~/.ucode/vscode-codex-extension.json).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ug never replaces a claudeCode.claudeProcessWrapper that isn't its own. But when that
wrapper's file is gone (for example a hand-made one that was uninstalled), the extension only
fails with "Claude Code native binary not found", so take the setting over and say so. A
working foreign wrapper is still left alone, and `ug revert` removes the setting instead of
restoring the dead path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… schema

With a Model Provider Service (admin-managed or via --provider) or a Unity Catalog schema,
`ug codex` adds the routing header (Databricks-Model-Provider-Service / the parent-schema
header) at launch and publishes that source's model list. The extension never launches
through ug, so its config.toml copy had no routing header: its requests reached the gateway
as Databricks-hosted model requests and failed (seen with a managed Azure OpenAI provider),
and its model list stayed on the previous source.

The extension's copy now carries the routing header, and `ug configure` publishes the routed
model list (as `ug codex` does; a failure only warns). ug's own files still keep launch
routing headers out. Because the machine-wide managed_config.toml never has the header, a
routed setup writes the copy on Linux/macOS too.

Co-Authored-By: Claude Opus 5.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