diff --git a/internal/sandbox/macos.go b/internal/sandbox/macos.go index b5d006e..da93c56 100644 --- a/internal/sandbox/macos.go +++ b/internal/sandbox/macos.go @@ -748,8 +748,11 @@ func WrapCommandMacOS(cfg *config.Config, command string, exposedPorts []int, da // ALL_PROXY=socks5h:// so proxy-aware apps (curl, git, etc.) resolve DNS // through the SOCKS5 proxy. The "h" suffix means "resolve hostname at proxy". // - // We only set ALL_PROXY (not HTTP_PROXY/HTTPS_PROXY) because apps like - // Bun/Node.js read HTTP_PROXY but don't support SOCKS5 protocol. + // Set ALL_PROXY and HTTP_PROXY/HTTPS_PROXY with socks5h:// so both + // SOCKS5-aware apps (curl, git) and HTTP-proxy-aware apps (opencode, + // Node.js tools) resolve DNS through the proxy. The "h" suffix means + // "resolve hostname at proxy side". Note: apps that read HTTP_PROXY + // but don't support SOCKS5 protocol (e.g., Bun) may fail to connect. // // sudo resets the environment, so we use `env` after sudo to re-inject // terminal vars (TERM, COLORTERM, etc.) needed for TUI apps. @@ -758,7 +761,22 @@ func WrapCommandMacOS(cfg *config.Config, command string, exposedPorts []int, da // Convert socks5:// → socks5h:// for hostname resolution through proxy. socks5hURL := strings.Replace(cfg.Network.ProxyURL, "socks5://", "socks5h://", 1) if socks5hURL != "" { - sandboxEnvs = append(sandboxEnvs, "ALL_PROXY="+socks5hURL, "all_proxy="+socks5hURL) + // ALL_PROXY uses socks5h:// (DNS resolved at proxy side) for + // SOCKS5-aware apps (curl, git). + // HTTP_PROXY/HTTPS_PROXY use http:// pointing to the GreyHaven + // HTTP CONNECT proxy (port 42051) for apps that only understand + // HTTP proxies (opencode, Node.js tools, etc.). The CONNECT + // proxy resolves DNS server-side. + proxyHost := "localhost" + if u, err := url.Parse(socks5hURL); err == nil && u.Hostname() != "" { + proxyHost = u.Hostname() + } + httpProxyURL := "http://" + proxyHost + ":42051" + sandboxEnvs = append(sandboxEnvs, + "ALL_PROXY="+socks5hURL, "all_proxy="+socks5hURL, + "HTTP_PROXY="+httpProxyURL, "http_proxy="+httpProxyURL, + "HTTPS_PROXY="+httpProxyURL, "https_proxy="+httpProxyURL, + ) } termEnvs := getTerminalEnvVars() parts = append(parts, "sudo", "-u", uid, "-g", daemonSession.SandboxGroup, "env")