Skip to content

Conversation

@hannesrudolph
Copy link
Collaborator

@hannesrudolph hannesrudolph commented Jan 5, 2026

Summary

Closes #7042

Adds debug-mode proxy settings (debugProxy.enabled, debugProxy.serverUrl, debugProxy.tlsInsecure) and initializes a debug-only global proxy/TLS bypass so extension network traffic can be routed through an intercepting proxy during F5 runs.

image

Changes

  • Add debugProxy.enabled setting to explicitly enable/disable proxy routing
  • Add debugProxy.serverUrl setting with default http://127.0.0.1:8888
  • Add debugProxy.tlsInsecure setting to disable TLS verification for MITM proxy inspection
  • Settings organized alphabetically for logical display in VS Code Settings UI
  • Initialize proxy module early during activation
  • Implement proxy routing using global-agent plus an undici global dispatcher (and patch fetch in debug mode)
  • Ensure global-agent / undici are external in the extension bundle
  • Add unit tests for proxy behavior
  • Add translations for all supported languages

Testing

  1. Enable debugProxy.enabled in VS Code settings
  2. Start a local MITM proxy (e.g., mitmproxy, Charles, Proxyman) on http://127.0.0.1:8888
  3. If the proxy uses TLS interception, enable debugProxy.tlsInsecure
  4. Run the extension in debug mode (F5)
  5. Verify network requests are routed through the proxy

Important

Adds debug-mode proxy routing to the Roo Code extension, enabling network traffic to be routed through a proxy during development, with new settings, implementation in networkProxy.ts, and comprehensive tests.

  • Behavior:
    • Adds debugProxy.enabled, debugProxy.serverUrl, and debugProxy.tlsInsecure settings in package.json for proxy configuration.
    • Initializes proxy configuration early in activate() in extension.ts to route network traffic through a proxy in debug mode.
    • Uses global-agent and undici to handle proxy routing and TLS settings.
  • Implementation:
    • Implements initializeNetworkProxy() in networkProxy.ts to set up proxy based on settings.
    • Adds getProxyConfig(), isProxyEnabled(), and isDebugMode() functions in networkProxy.ts.
    • Configures global-agent and undici for proxy routing in networkProxy.ts.
  • Testing:
    • Adds unit tests in networkProxy.spec.ts to verify proxy configuration and behavior.
    • Mocks global-agent and vscode for testing purposes.
  • Misc:
    • Adds type declarations for global-agent in global-agent.d.ts.
    • Updates translations in multiple package.nls.*.json files for new settings descriptions.

This description was created by Ellipsis for 82ccf6c. You can customize this summary. It will automatically update as commits are pushed.

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. Enhancement New feature or request labels Jan 5, 2026
@roomote
Copy link
Contributor

roomote bot commented Jan 5, 2026

Oroocle Clock   See task on Roo Cloud

Re-review complete. No new issues found in the latest commit.

  • Redact proxy URL credentials from debug logs (avoid logging GLOBAL_AGENT_* values)
  • Avoid or scope the permanent globalThis.fetch patch in debug proxy mode
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

// Setting a dispatcher on our `undici` dependency does NOT affect that internal fetch.
// To ensure Roo Code's `fetch()` calls are proxied, patch global fetch in debug mode.
if (!fetchPatched) {
globalThis.fetch = undiciFetch as unknown as typeof fetch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configureUndiciProxy() permanently patches globalThis.fetch when a proxy is configured in debug mode. Because this module is initialized unconditionally on activation, this can affect unrelated debug-only behaviors and makes it hard to reason about fetch semantics in extension-host tests/debug sessions. Suggest gating the patch behind an explicit internal flag or only patching where Roo Code actually uses fetch (for example, wrap/centralize fetch usage) so the behavior change is scoped.

Fix it with Roo Code or mention @roomote and request a fix.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Jan 5, 2026
mockConfig.get.mockReturnValue("http://localhost:8080")
const context = createMockContext(vscode.ExtensionMode.Production)

expect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test uses expect(() => { void initializeNetworkProxy(...) }) to check that no error is thrown. Since initializeNetworkProxy is async, errors may be missed. Convert the test to async and use await expect(initializeNetworkProxy(...)).resolves.not.toThrow() to properly catch async errors.

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 6, 2026
loggingEnabled = config.isDebugMode || config.enabled || config.tlsInsecure
consoleLoggingEnabled = config.isDebugMode && !outputChannel

log(`Initializing network proxy module...`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much (if any) of this do you want to log when it is disabled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added early-exit at the top of initializeNetworkProxy() so when debug mode is disabled, we skip all work including logging. Zero overhead in production.

Copy link
Collaborator

@jr jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can extensionContext.extensionMode ever change in process's lifespan? If not, we might want to stop early in initializeNetworkProxy and not do anything at all unless we're in debug mode?

Address review feedback from jr:
- Check extensionMode at top of initializeNetworkProxy and return immediately
  if not in debug mode (extensionMode is immutable for process lifetime)
- Remove verbose logging when proxy is disabled
- Remove unnecessary typeof guard for onDidChangeConfiguration
- Remove redundant trailing comment
@hannesrudolph
Copy link
Collaborator Author

Re: @jr's review about early exit when not in debug mode:

Yes, extensionContext.extensionMode is immutable for the process lifetime. I've added an early-exit at lines 121-126:

// extensionMode is immutable for the process lifetime - exit early if not in debug mode.
// This avoids any overhead (listeners, logging, etc.) in production.
const isDebugMode = context.extensionMode === vscode.ExtensionMode.Development
if (!isDebugMode) {
    return
}

This ensures zero overhead (no listeners, no logging, nothing) in production builds.

@hannesrudolph hannesrudolph merged commit 503f402 into main Jan 6, 2026
10 checks passed
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Jan 6, 2026
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Jan 6, 2026
@hannesrudolph hannesrudolph deleted the feat/debug-proxy branch January 6, 2026 20:17
mini2s added a commit to zgsm-ai/costrict that referenced this pull request Jan 6, 2026