Files
deepseek-harness/.agents/notes/implemented/process/2026-08-19-source-dsh-http-proxy-overlay.md
Coder ed152416d5
Some checks failed
CI / node 22.19 (push) Has been skipped
CI / node 26 (push) Has been skipped
CI / python 3.10 / keyless SDK (push) Has been skipped
CI / python runtime / release-shaped Linux x64 (push) Has been skipped
CI / windows node 24 / wine blocking (push) Has been skipped
CI / wine apt cache (push) Successful in 58s
CI / serial / linux (push) Has been skipped
Deploy documentation / build (push) Failing after 2m46s
Deploy documentation / deploy (push) Has been skipped
E2E (real DeepSeek API) / e2e (push) Failing after 1m18s
Sandbox / sandbox e2e (bwrap, ubuntu-latest) (push) Failing after 1m18s
Landlock Run / Matrix (push) Successful in 13s
Release (vendor) / Pack npm tarballs (push) Failing after 3m43s
Release (dsh) / Pack npm tarballs (push) Failing after 1m53s
Sandbox / sandbox e2e (landlock, ubuntu-24.04) (push) Failing after 1m51s
Release (vendor) / Publish to npm (push) Has been skipped
Release (dsh) / Publish to npm (push) Has been skipped
CI / node 24 / static (push) Has been cancelled
CI / node 24 / coverage (push) Has been cancelled
CI / node 24 / snapshots and artifacts (push) Has been cancelled
CI / windows node 24 / native complete (push) Has been cancelled
CI / serial / linux (self-hosted standby) (push) Has been cancelled
CI / serial / macos (push) Has been cancelled
CI / serial / windows (self-hosted standby) (push) Has been cancelled
CI / larger-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (16, windows, dsh-windows-2025-16core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (32, windows, dsh-windows-2025-32core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (4, windows, dsh-windows-2025-4core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (64, windows, dsh-windows-2025-64core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (8, windows, dsh-windows-2025-8core, production-site) (push) Has been cancelled
CI / larger-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, typecheck) (push) Has been cancelled
CI / larger-runner-benchmark (96, windows, dsh-windows-2025-96core, production-site) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, linux, dsh-ubuntu-24-04-16core, 16) (push) Has been cancelled
CI / consolidated-runner-benchmark (16, windows, dsh-windows-2025-16core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, linux, dsh-ubuntu-24-04-32core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (32, windows, dsh-windows-2025-32core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, linux, dsh-ubuntu-24-04-4core, 4) (push) Has been cancelled
CI / consolidated-runner-benchmark (4, windows, dsh-windows-2025-4core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, linux, dsh-ubuntu-24-04-64core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (64, windows, dsh-windows-2025-64core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, linux, dsh-ubuntu-24-04-8core, 8) (push) Has been cancelled
CI / consolidated-runner-benchmark (8, windows, dsh-windows-2025-8core, 2) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, linux, dsh-ubuntu-24-04-96core, 32) (push) Has been cancelled
CI / consolidated-runner-benchmark (96, windows, dsh-windows-2025-96core, 2) (push) Has been cancelled
CI / all checks passed (push) Has been cancelled
Sandbox / sandbox e2e (seatbelt, macos-latest) (push) Has been cancelled
Sandbox / sandbox e2e (landlock, ubuntu-24.04-arm) (push) Has been cancelled
Landlock Run / ${{ matrix.platform }} (push) Has been cancelled
Landlock Run / darwin (no platform package — degradation proof) (push) Has been cancelled
feat: add searxng web-search provider, openrouter cost balance UI, offline scripts; update source-launch and docs
2026-08-20 13:01:40 +07:00

4.1 KiB

Agent Note: Source dsh HTTP proxy overlay

Status: implemented

English | 中文

Problem

Machines whose ambient proxy is SOCKS can reach OpenRouter with curl and still fail pnpm dsh HTTPS fetches: Node, undici, and pi-ai accept http:// / https:// proxy URLs and reject socks5 / socks5h. Setting HTTPS_PROXY in the calling PowerShell or bash session also routes later shell commands through that HTTP proxy. Product .env files cannot supply HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, or NO_PROXY because those names are bootstrap-only. Assigning those names on process.env after Node has started does not rebind fetch: undici reads NODE_USE_ENV_PROXY and HTTPS_PROXY at process start. Node --env-file-if-exists also leaves inherited names in place, so a user-level HTTPS_PROXY=socks5h://… still wins.

Decision

The root dsh script runs scripts/run-source-dsh.ts as node --import tsx/esm scripts/run-source-dsh.ts. applySourceDshHttpProxy writes HTTP proxy variables onto a copy of process.env. When gitignored .dsh-http-proxy.env or DSH_HTTP_PROXY supplies an overlay and DSH_SOURCE_HTTP_PROXY_APPLIED is unset, the wrapper respawns the same Node argv with that environment so NODE_USE_ENV_PROXY=1 and the HTTP proxy URLs exist before fetch initializes. The marker prevents a second respawn. The calling shell is unchanged.

DSH_HTTP_PROXY, when set to a non-empty HTTP(S) URL, overwrites HTTP_PROXY / HTTPS_PROXY / ALL_PROXY (both cases) and sets NODE_USE_ENV_PROXY=1. When NO_PROXY and no_proxy are both unset, it sets them to localhost,127.0.0.1,::1. Otherwise the overlay file's parsed assignments are applied, then any remaining SOCKS value on those six names is replaced by the file's HTTP URL so an omitted ALL_PROXY cannot keep socks5h://. A socks5 or socks5h winning overlay fails before the CLI boots. Absent both sources, the inherited environment is unchanged and there is no respawn. The wrapper prints the applied HTTP URL once to stderr before respawn.

The installed apps/cli/lib/bin.js path is unchanged: it has no checkout overlay file.

Alternatives considered

Tell the user to export HTTPS_PROXY in the shell before pnpm dsh. That reaches OpenRouter, but the same variables remain on later commands in that session, including tools that should keep a SOCKS proxy.

Put proxy names in the invoking .env or $DSH_HOME/.env. Rejected by the configuration-source-ownership decision: bootstrap network variables may come only from the inherited process environment.

Assign NODE_USE_ENV_PROXY only inside the wrapper after Node has started. OpenRouter traffic uses fetch; Node binds the env-proxy dispatcher at process start, so a later process.env write does not change it.

Use Node --env-file-if-exists without respawning. That file does not replace names the parent already set, so an inherited socks5h:// HTTPS_PROXY still reaches fetch.

Consequences

Source pnpm dsh can use an HTTP overlay without mutating the calling shell. An inherited SOCKS HTTPS_PROXY is replaced in the respawned Node process, not in the shell. Contributors without DSH_HTTP_PROXY or .dsh-http-proxy.env see the previous inheritance behavior and no extra process. A SOCKS-only overlay fails loud instead of timing out against OpenRouter. The published bin still requires the caller to pass HTTP proxy variables when the host needs a proxy. --use-env-proxy is not on the command: Node 22.19 in CI rejects the flag.

Testing

scripts/apply-source-dsh-http-proxy.spec.ts covers no-overlay, DSH_HTTP_PROXY overwrite of SOCKS, file parse, file-versus-DSH_HTTP_PROXY precedence, SOCKS leftover on omitted names, SOCKS rejection, and the one-shot respawn marker. apps/cli/tests/source-launch.compat.spec.ts pins the root dsh command to scripts/run-source-dsh.ts and smokes that vector.