Files
deepseek-harness/.agents/notes/implemented/process/2026-08-19-source-dsh-http-proxy-overlay.zh.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
Raw Permalink Blame History

Agent Note: Source dsh HTTP proxy overlay

Status: implemented

English | 中文

问题

环境中只有 SOCKS 代理的机器可以用 curl 访问 OpenRouter,但 pnpm dsh 的 HTTPS fetch 仍会失败:Node、undici 和 pi-ai 接受 http:// / https:// 代理 URL,并拒绝 socks5 / socks5h。在调用方的 PowerShell 或 bash 会话里设置 HTTPS_PROXY 也会让该会话中后续命令走这个 HTTP 代理。产品 .env 文件不能提供 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 或 NO_PROXY,因为这些名称只能来自进程启动环境。在 Node 启动之后再往 process.env 写入这些名称不会重新绑定 fetch:undici 在进程启动时读取 NODE_USE_ENV_PROXY 和 HTTPS_PROXY。Node --env-file-if-exists 同样不会替换已继承的名称,因此用户级的 HTTPS_PROXY=socks5h://… 仍然生效。

决策

根目录的 dsh 脚本以 node --import tsx/esm scripts/run-source-dsh.ts 运行 scripts/run-source-dsh.ts。applySourceDshHttpProxy 把 HTTP 代理变量写入 process.env 的副本。当被 gitignore 的 .dsh-http-proxy.env 或 DSH_HTTP_PROXY 提供覆盖层且未设置 DSH_SOURCE_HTTP_PROXY_APPLIED 时,包装层用该环境按相同的 Node argv 再拉起一次进程,以便在 fetch 初始化之前就存在 NODE_USE_ENV_PROXY=1 和 HTTP 代理 URL。该标记防止第二次再拉起。调用方 shell 不变。

当 DSH_HTTP_PROXY 设为非空的 HTTP(S) URL 时,它会覆盖 HTTP_PROXY / HTTPS_PROXY / ALL_PROXY(两种大小写)并设置 NODE_USE_ENV_PROXY=1。当 NO_PROXY 与 no_proxy 都未设置时,它将它们设为 localhost,127.0.0.1,::1。否则先应用覆盖文件中解析出的赋值,再把这六个名称上残留的 SOCKS 值换成文件中的 HTTP URL,以免漏写的 ALL_PROXY 仍指向 socks5h://。最终生效的覆盖层若为 socks5 或 socks5h,会在 CLI 启动前失败。两种来源都不存在时,继承的环境保持不变,也不会再拉起进程。包装层在再拉起之前会把生效的 HTTP URL 打印到 stderr 一次。

已安装的 apps/cli/lib/bin.js 路径不变:它没有检出级覆盖文件。

考虑过的备选方案

**让用户在运行 pnpm dsh 之前于 shell 中导出 HTTPS_PROXY。**这样可以访问 OpenRouter,但这些变量会留在该会话的后续命令上,包括本应继续使用 SOCKS 代理的工具。

**把代理名称放进调用目录的 .env 或 $DSH_HOME/.env。**被配置来源归属决策拒绝:网络启动变量只能来自继承的进程环境。

仅在包装层内、Node 启动之后赋值 NODE_USE_ENV_PROXY。 OpenRouter 流量走 fetch;Node 在进程启动时绑定 env-proxy dispatcher,随后再写 process.env 不会改变它。

**使用 Node --env-file-if-exists 且不再拉起进程。**该文件不会替换父进程已经设置的名称,因此继承来的 socks5h:// HTTPS_PROXY 仍会到达 fetch。

影响

源码路径的 pnpm dsh 可以使用 HTTP 覆盖层,而不修改调用方 shell。继承来的 SOCKS HTTPS_PROXY 会在再拉起的 Node 进程中被替换,而不是在 shell 中。没有 DSH_HTTP_PROXY 或 .dsh-http-proxy.env 的贡献者仍看到原来的继承行为,也不会多一个进程。仅有 SOCKS 的覆盖层会立即失败,而不是在访问 OpenRouter 时超时。已发布的 bin 在宿主需要代理时,仍要求调用方传入 HTTP 代理变量。命令行不加 --use-env-proxy:CI 中的 Node 22.19 会拒绝该 flag。

测试

scripts/apply-source-dsh-http-proxy.spec.ts 覆盖无覆盖层、DSH_HTTP_PROXY 覆盖 SOCKS、文件解析、文件与 DSH_HTTP_PROXY 的优先级、文件未写出的名称上残留的 SOCKS、SOCKS 拒绝,以及一次性再拉起标记。apps/cli/tests/source-launch.compat.spec.ts 将根目录 dsh 命令钉在 scripts/run-source-dsh.ts 上,并对该启动向量做冒烟测试。