Skip to content

fix(desktop): macOS system proxy support and missing native dependency - #586

Merged
phodal merged 7 commits into
phodal:mainfrom
im47cn:fix/macos-desktop-connectivity
Jul 28, 2026
Merged

fix(desktop): macOS system proxy support and missing native dependency#586
phodal merged 7 commits into
phodal:mainfrom
im47cn:fix/macos-desktop-connectivity

Conversation

@im47cn

@im47cn im47cn commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes three desktop runtime issues discovered on macOS:

  • ACP agent registry fails to load behind system proxyreqwest only reads HTTP_PROXY/HTTPS_PROXY env vars and ignores macOS system proxy settings. Proxy software like Surge, ClashX, and V2Ray configure the proxy via networksetup (System Preferences), which reqwest never sees. Added build_http_client() that reads the system proxy via scutil --proxy and applies it to the reqwest client.

  • Agent install errors silently replaced with generic message — Tauri invoke returns errors as strings, but err instanceof Error was false, so real errors like "Failed to fetch registry: ..." were silently replaced with a generic message. Now preserves the actual error. Also switched the web-mode fallback from raw fetch to resolveApiPath per project conventions.

  • "Module not found: Can't resolve 'better-sqlite3'" — The native module was listed as optionalDependencies but not installed on some machines. Bumped version range to ^12.11.1 to pick up latest prebuilt binaries.

Commits

  1. fix(desktop): respect macOS system proxy for ACP registry fetch
  2. fix(deps): bump better-sqlite3 to ^12.11.1

Test plan

  • cargo check passes in apps/desktop/src-tauri
  • Vitest passes for agent-install-panel.test.tsx
  • Verified ACP registry loads behind Surge proxy (port 6152)
  • Verified better-sqlite3 loads after install

💘 Generated with Crush

Summary by CodeRabbit

  • Bug Fixes
    • Improved macOS agent registry lookup and binary downloads by honoring system proxy settings (including protocol-specific HTTP/HTTPS/SOCKS handling and NO_PROXY rules).
    • Refined installation/uninstallation error messaging with consistent, user-friendly formatting across web and Tauri modes.
  • Improvements
    • Improved web-mode registry URL resolution during agent installation.
    • Updated binary downloading and ACP installs to use caller-provided/proxy-aware HTTP clients, preserving networking configuration.
  • Tests
    • Updated/expanded agent install panel tests to mock HTTP interactions reliably and validate Tauri/web error rendering.

im47cn and others added 2 commits July 28, 2026 22:55
reqwest only reads HTTP_PROXY/HTTPS_PROXY env vars, ignoring macOS
system proxy settings (Surge, ClashX, V2Ray). This caused the desktop
app to fail loading the ACP agent registry behind a system proxy.

Read the proxy via `scutil --proxy` and apply it to the reqwest client.

Also preserve real error messages from Tauri invoke (string errors were
silently replaced with a generic "failed to load" message), and use
resolveApiPath instead of raw fetch in the web fallback path.

Co-authored-by: Crush (GLM 5.2) <crush@local>
The native module was not being installed as an optional dependency,
causing "Module not found: Can't resolve 'better-sqlite3'" at runtime.
Bump the version range to pick up the latest prebuilt binaries.

Co-authored-by: Crush (GLM 5.2) <crush@local>
@im47cn
im47cn requested a review from phodal as a code owner July 28, 2026 14:55
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 15447e3b-d1c9-4f11-a52d-19cf403244b7

📥 Commits

Reviewing files that changed from the base of the PR and between efb8641 and 0436b6d.

📒 Files selected for processing (1)
  • apps/desktop/src-tauri/src/system_proxy.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src-tauri/src/system_proxy.rs

📝 Walkthrough

Walkthrough

ACP registry and binary downloads now use proxy-aware HTTP clients, web-mode API paths are resolved through a helper, string errors are preserved in the UI, and tests cover these flows. The optional better-sqlite3 version is also updated.

Changes

ACP installation and proxy support

Layer / File(s) Summary
System proxy client construction
apps/desktop/src-tauri/Cargo.toml, apps/desktop/src-tauri/src/system_proxy.rs
Adds macOS proxy discovery, HTTPS/HTTP/SOCKS selection, IPv6 formatting, bypass rules, timeouts, and unit tests; enables reqwest SOCKS support.
Registry and binary download wiring
apps/desktop/src-tauri/src/lib.rs, crates/routa-core/src/acp/binary_manager.rs
Routes registry and binary archive downloads through caller-provided HTTP clients, including proxy configuration, and tests client header propagation.
Web request and error handling
src/client/components/agent-install-panel.tsx, src/client/components/__tests__/agent-install-panel.test.tsx
Uses resolveApiPath, centralizes error formatting, and updates web and Tauri runtime tests.

SQLite optional dependency

Layer / File(s) Summary
Optional dependency version
package.json
Updates better-sqlite3 from ^12.6.2 to ^12.11.1.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ACPInstall as install_acp_agent
  participant HttpClient as build_http_client
  participant SystemProxy as read_macos_system_proxy
  participant Registry as ACP_REGISTRY_URL
  participant BinaryManager as AcpBinaryManager
  ACPInstall->>HttpClient: Build configured client
  HttpClient->>SystemProxy: Read macOS proxy settings
  HttpClient-->>ACPInstall: Return reqwest client
  ACPInstall->>Registry: Fetch registry
  ACPInstall->>BinaryManager: Install binary with client
  BinaryManager->>Registry: Download archive with client
Loading

Suggested reviewers: phodal

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately covers the main desktop changes: macOS system proxy support and the native dependency fix.
Description check ✅ Passed The description covers the main changes, commit list, and test/verification results, though the template's Notes section is not filled out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/client/components/agent-install-panel.tsx`:
- Around line 202-203: Update the registry request in the surrounding refresh
flow to call desktopAwareFetch instead of fetch, while preserving the existing
resolveApiPath URL construction and refresh query behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d3881840-0f94-45ca-8aee-29a4eb73624f

📥 Commits

Reviewing files that changed from the base of the PR and between f6441f2 and 1c448fc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • apps/desktop/src-tauri/src/lib.rs
  • package.json
  • src/client/components/agent-install-panel.tsx

Comment thread src/client/components/agent-install-panel.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c448fc926

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
} catch (err) {
setError(err instanceof Error ? err.message : t.agents.failedToLoad);
const msg = err instanceof Error ? err.message : typeof err === "string" ? err : t.agents.failedToLoad;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve Tauri string errors in install handlers

The new string-preserving conversion only runs in fetchAgents; the Tauri install/uninstall handlers still catch install_acp_agent/uninstall_acp_agent rejections with the old err instanceof Error ? ... : t.agents.installFailed/uninstallFailed pattern. When a Tauri command returns Err(String) after the registry has loaded, such as a binary download failure or unsupported platform, the actual message is still replaced by the generic install error, so the desktop diagnostic fix remains ineffective for the install scenario it calls out. Reuse the same string fallback in those handlers.

Useful? React with 👍 / 👎.

Comment thread package.json
},
"optionalDependencies": {
"better-sqlite3": "^12.6.2",
"better-sqlite3": "^12.11.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Promote required sqlite dependency out of optionalDependencies

Keeping this package only under optionalDependencies means installs that omit optional deps, such as npm ci --omit=optional or environments where the optional native install is skipped, still won't have better-sqlite3, and the desktop/SQLite path can still throw the same “Ensure better-sqlite3 is installed” error. The lockfile's added root dependency entry is regenerated from package.json and is not a durable source of truth; if desktop requires the module, add it to dependencies instead of only bumping the optional entry.

Useful? React with 👍 / 👎.

Comment thread apps/desktop/src-tauri/src/lib.rs Outdated
// Fetch from CDN
let response = reqwest::get(ACP_REGISTRY_URL)
// Fetch from CDN (with macOS system proxy support)
let client = build_http_client()?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reuse the proxy-aware client for binary downloads

When installing a binary-distributed agent on macOS behind a system proxy, this proxy-aware client is only used for the registry request; the binary branch still calls AcpBinaryManager::install_binary, whose archive download uses a plain reqwest::get(url), so the actual agent binary bypasses the macOS proxy and fails after the registry has loaded. Pass the same proxy configuration into the binary download path as well.

Useful? React with 👍 / 👎.

Comment thread apps/desktop/src-tauri/src/lib.rs Outdated
}
}

// Fall back to HTTP proxy if HTTPS proxy is not configured

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle SOCKS-only macOS proxies

This fallback only checks HTTPS* and HTTP* entries from scutil --proxy; when macOS is configured with only a SOCKS proxy (SOCKSEnable/SOCKSProxy/SOCKSPort), read_macos_system_proxy() returns None and the registry request still goes direct. That leaves common SOCKS-only proxy setups unsupported by the new desktop proxy path, so parse the SOCKS fields as well and enable reqwest's SOCKS support for that URL.

Useful? React with 👍 / 👎.

Route registry requests through the desktop-aware fetch path, isolate and test macOS system proxy parsing, preserve Tauri string errors in tests, and keep the optional dependency lock metadata canonical.

Co-authored-by: Codex (GPT 5.5) <codex@openai.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4aea30ea2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +9 to +10
match read_macos_system_proxy().and_then(|proxy_url| reqwest::Proxy::all(proxy_url).ok()) {
Some(proxy) => builder.proxy(proxy),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve environment proxy precedence

When the desktop process has HTTP_PROXY/HTTPS_PROXY or NO_PROXY configured while macOS also reports a system proxy, adding an explicit proxy with ClientBuilder::proxy disables reqwest's automatic environment-proxy handling. This regresses the previous reqwest::get behavior by silently replacing the process-specific proxy or bypass rules with the macOS proxy; use the scutil result only as a fallback when no environment proxy applies, or explicitly carry the environment and no-proxy configuration into the client.

Useful? React with 👍 / 👎.

phodal and others added 2 commits July 29, 2026 00:02
Normalize string rejections from Tauri registry, install, and uninstall commands so actionable desktop failures are not replaced by generic UI messages.

Co-authored-by: Codex (GPT 5.5) <codex@openai.com>
Pass the desktop proxy-aware reqwest client into binary archive downloads and support SOCKS-only macOS system proxy configurations.

Co-authored-by: Codex (GPT 5.5) <codex@openai.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 04eebb8a4d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


/// Build an HTTP client that respects the macOS system proxy when configured.
pub(crate) fn build_http_client() -> Result<reqwest::Client, String> {
let builder = reqwest::Client::builder().timeout(Duration::from_secs(15));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Separate the binary-download timeout from registry requests

When a binary archive takes more than 15 seconds to connect and fully transfer—especially over the slower proxies this change targets—Reqwest applies this client timeout as a total deadline through completion of the response body. install_acp_agent now passes this same client to install_binary_with_client, so desktop installs abort after 15 seconds even though the web/server path and the previous reqwest::get path had no total timeout. Use separate clients or apply a connect/read timeout that does not cap the complete archive transfer.

AGENTS.md reference: AGENTS.md:L3-L8

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/routa-core/src/acp/binary_manager.rs (1)

35-44: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Remove the dead install_binary method.

install_binary still builds a bare reqwest::Client::new(), but there are no remaining callers of it in the codebase. Delete the legacy path rather than keeping a reachable entry point with no proxy support.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/routa-core/src/acp/binary_manager.rs` around lines 35 - 44, Remove the
unused public install_binary method from the binary manager, including its bare
reqwest::Client construction; retain install_binary_with_client as the supported
installation path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/routa-core/src/acp/binary_manager.rs`:
- Around line 35-44: Remove the unused public install_binary method from the
binary manager, including its bare reqwest::Client construction; retain
install_binary_with_client as the supported installation path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 37088e6d-d2f2-4849-b344-e02d67c315d9

📥 Commits

Reviewing files that changed from the base of the PR and between d4aea30 and 04eebb8.

📒 Files selected for processing (6)
  • apps/desktop/src-tauri/Cargo.toml
  • apps/desktop/src-tauri/src/lib.rs
  • apps/desktop/src-tauri/src/system_proxy.rs
  • crates/routa-core/src/acp/binary_manager.rs
  • src/client/components/__tests__/agent-install-panel.test.tsx
  • src/client/components/agent-install-panel.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src-tauri/src/lib.rs
  • apps/desktop/src-tauri/src/system_proxy.rs

Co-authored-by: Codex (GPT 5.5) <codex@openai.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src-tauri/src/system_proxy.rs`:
- Around line 33-36: Update the proxy construction flow around
read_macos_system_proxy and NoProxy::from_env to also honor macOS ExceptionsList
entries and ExcludeSimpleHostnames when selecting the proxy. Parse the system
settings, apply compatible exclusions or a custom proxy selector while
preserving existing environment-based exclusions, and add fixtures covering both
bypass cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a714c9f1-822f-41e1-8d75-756a4f245791

📥 Commits

Reviewing files that changed from the base of the PR and between 04eebb8 and efb8641.

📒 Files selected for processing (2)
  • apps/desktop/src-tauri/src/lib.rs
  • apps/desktop/src-tauri/src/system_proxy.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src-tauri/src/lib.rs

Comment thread apps/desktop/src-tauri/src/system_proxy.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: efb86412b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +112 to +115
https
.url("http")
.or_else(|| http.url("http"))
.or_else(|| socks.url("socks5h"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve protocol-specific macOS proxy selection

When macOS has only Web Proxy (HTTP) enabled while Secure Web Proxy (HTTPS) is disabled, this fallback still returns the HTTP configuration, and build_http_client installs it with Proxy::all; the always-HTTPS ACP registry request is therefore forced through a proxy that macOS explicitly does not select for HTTPS. This can make registry loading fail in that configuration, while distinct HTTP/HTTPS settings also route HTTP binary URLs through the wrong proxy. Keep the HTTP and HTTPS matchers scheme-specific rather than treating HTTP as a fallback for HTTPS.

Useful? React with 👍 / 👎.

Co-authored-by: Codex (GPT 5.5) <codex@openai.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0436b6df0d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"SOCKSEnable" => socks.enabled = value == "1",
"SOCKSProxy" => socks.host = Some(value.to_string()),
"SOCKSPort" => socks.port = value.parse().ok(),
_ => {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor automatic macOS proxy configurations

When macOS uses Automatic Proxy Configuration or auto-discovery instead of a static HTTP/HTTPS/SOCKS proxy, scutil --proxy reports fields such as ProxyAutoConfigEnable and ProxyAutoConfigURLString, but this match discards them. has_proxy() then remains false and both registry and binary requests fall back to a client that does not evaluate the PAC file, so these installations still connect directly and fail on networks where the PAC proxy is mandatory. Handle the automatic proxy fields or delegate routing to a PAC-aware system client.

Useful? React with 👍 / 👎.

@phodal
phodal merged commit 2c7293e into phodal:main Jul 28, 2026
24 of 27 checks passed
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.

2 participants