Back to home@looeton

dsh-plugin-proxy-env

DSH plugin: inject proxy environment variables at startup and self-check the whole proxy chain

Stars
0
Language
JavaScript
Created
Sep 10, 2026
Updated
Sep 10, 2026
GitHub repo

Introduction

dsh-plugin-proxy-env

DSH 插件:启动时自动注入代理环境变量,并自检整条代理链路。 A DeepSeek Harness plugin that injects proxy environment variables at startup and self-checks the whole proxy chain.

CI License: MIT Node dsh plugin

中文 · English


中文

这是什么

一个 DSH 插件,做两件事:

  1. 启动时注入代理变量——把 HTTP_PROXY / HTTPS_PROXY / NODE_USE_ENV_PROXY / NO_PROXY 写进 harness 主进程的环境,之后所有子进程(shell、git、npm、python)自动继承,不用再 setx + 重启。
  2. 自检——从本地端口一路查到端到端请求,把结论写进日志和报告文件;同时注册一个 proxy_env_check 工具,随时能再查一次。

为什么这样能生效

DSH 在派生子进程时process.env 构造子环境(dsh-subprocessscrubbedParentEnv(),它只剔除名字含 KEY/PASSWORD/SECRET/TOKEN 的和 DSH_* 的变量,代理变量是刻意保留的)。所以插件在加载阶段写一次 process.env,后面每一次 spawn 都带着它——比手工 setx 更即时,也不依赖启动方式。

注入哪些变量

变量作用
HTTP_PROXY / HTTPS_PROXY解析到的代理地址curl / git / python / Go 等自动读取
NODE_USE_ENV_PROXY1 Node 进程启动时即让内置 fetch 读取上面的变量
NO_PROXY默认 localhost,127.0.0.1,::1,api.deepseek.com回环必须排除,否则本地 GUI 请求会被塞进代理;模型 API 排除后,代理挂掉也不影响对话

已存在的同名变量默认不覆盖override: true 可强制)。

自检做什么

按「由近到远」的顺序,先报最上游的断点:

  1. 代理端口是否监听
  2. 端口是否应答 CONNECT(手工建隧道,不依赖 undici)
  3. DNS 是否返回真实地址(识别 198.18.0.0/15fdfe:dcba:9876::/64 的 fake-ip)
  4. 直连探针 + 走代理探针(TLS 隧道)
  5. 汇总结论:PASS / WARN / FAIL + 一条修复建议

结果写入 $DSH_HOME/proxy-env/report.json,agent 可以直接读取,不必调用工具。

安装

方式一:DSH Desktop 插件管理器(推荐)

设置 → 插件 → 安装,填入 dsh-plugin-proxy-env(发布到 npm 后可用)。

方式二:手动(从本仓库安装)

# 1) 进入当前 profile 目录
cd "$env:DSH_HOME\profiles\desktop"

# 2) 安装(本地路径、git 或 npm 均可)
pnpm add file:D:/path/to/dsh-plugin-proxy-env
#   或 pnpm add github:looeton/dsh-plugin-proxy-env

# 3) 把包名加进 package.json 的 dsh.profile.bundles
#    "dsh": { "profile": { "bundles": [ ..., "dsh-plugin-proxy-env" ] } }

# 4) 重启 DSH Desktop

方式三:先本地验证,不装进 profile

node src/cli.mjs            # 独立自检,跟插件走同一套代码
node --test tests/*.test.mjs   # 52 个单元测试

配置项

通过 patch 行或 profile 的 cordis.patch.yml 传入:

- id: proxy-env
  config:
    proxyUrl: http://127.0.0.1:7897   # 留空则自动探测
    noProxy: localhost,127.0.0.1,::1,api.deepseek.com
    selfCheck: true
    tool: true
默认说明
enabletrue总开关
proxyUrl自动完整代理地址;留空则按 port → Windows 系统代理 → 已导出的环境变量顺序解析
host127.0.0.1本地代理主机
port0直接指定端口
noProxy见上NO_PROXY 内容
overridefalse是否覆盖已存在的同名变量
patchGlobalDispatchertrue动态 import undici,把全局 dispatcher 换成 EnvHttpProxyAgent,让运行时的 Node 请求也走代理
selfChecktrue启动时自检
writeReporttrue$DSH_HOME/proxy-env/report.json
tooltrue注册 proxy_env_check 工具
probeUrlhttps://www.google.com只有走代理才通的探针
directProbeUrlhttps://example.com直连探针
dnsHostexample.comfake-ip 检测域名
timeoutMs15000单个探针超时

提供的工具

工具参数返回
proxy_env_checkprobe_urlskip_network一行结论 + 完整链路文本

局限

  • 它管的是进程环境,不是 web_fetch。DSH 的 web_fetch 用固定 IP 的自定义 undici Agent(防 SSRF / DNS rebinding),刻意绕过全局 dispatcher,所以即使代理正常它也不会走代理——这是设计,不是本插件的缺陷。被墙站点请用能走云端的抓取工具,或让 agent 用 shell 里的 node / python 抓。
  • 注册表读取依赖 reg.exe,且用文件重定向而非管道(受限令牌沙箱里管道会 EPERM)。读不到时自动回退到已导出的 HTTPS_PROXY / HTTP_PROXY
  • 非 Windows 只走配置和环境变量,不读系统代理。
  • patchGlobalDispatcher 是运行时切换:它需要能解析到 undici,且版本要有 EnvHttpProxyAgent(唯一会遵守 NO_PROXY 的实现);不满足时跳过并在日志里说明。

相关项目

  • clash-verge-system-proxy —— 手工版完整指南(关 TUN、开系统代理、写变量、排错手册)
  • proxy-doctor —— 独立的 PowerShell 诊断工具,不装插件也能用

English

What this is

A DSH plugin that does two things:

  1. Injects proxy variables at startup — writes HTTP_PROXY / HTTPS_PROXY / NODE_USE_ENV_PROXY / NO_PROXY into the harness host process, so every child process (shell, git, npm, python) inherits them. No setx, no restart dance.
  2. Self-checks the chain — walks from the local port to a real request, logs a verdict, writes a report file, and registers a proxy_env_check tool for on-demand re-runs.

Why this works

DSH builds each child environment from process.env at spawn time (scrubbedParentEnv() in dsh-subprocess strips credential-shaped names and DSH_*, but keeps proxy variables on purpose). Writing process.env once during plugin load therefore covers every later spawn — immediately, and independent of how the app was launched.

What it injects

VariableValuePurpose
HTTP_PROXY / HTTPS_PROXYresolved proxy URLread by curl, git, python, Go, …
NODE_USE_ENV_PROXY1makes child Node processes honour the two above from bootstrap
NO_PROXYlocalhost,127.0.0.1,::1,api.deepseek.comloopback must be excluded or local GUI requests go through the proxy; the model API is excluded so a dead proxy cannot break chat

Existing values are left alone unless override: true.

What the self-check does

Nearest-first, so the report always names the earliest broken link:

  1. is the proxy port listening
  2. does it answer CONNECT (hand-built tunnel, no undici needed)
  3. does DNS return real addresses (detects 198.18.0.0/15 and fdfe:dcba:9876::/64 fake-ip)
  4. direct probe + through-proxy probe (TLS tunnel)
  5. one verdict — PASS / WARN / FAIL — plus one fix

The report lands in $DSH_HOME/proxy-env/report.json, readable by the agent without a tool call.

Install

Option 1 — DSH Desktop plugin manager (recommended): Settings → Plugins → Install, then dsh-plugin-proxy-env (available once published to npm).

Option 2 — manual, from this repository

cd "$env:DSH_HOME\profiles\desktop"
pnpm add file:D:/path/to/dsh-plugin-proxy-env   # or github:looeton/dsh-plugin-proxy-env
# add "dsh-plugin-proxy-env" to dsh.profile.bundles in package.json
# restart DSH Desktop

Option 3 — verify locally without installing

node src/cli.mjs            # standalone self-check, same code path
node --test tests/*.test.mjs   # 52 unit tests

Configuration

- id: proxy-env
  config:
    proxyUrl: http://127.0.0.1:7897   # empty = auto-detect
    noProxy: localhost,127.0.0.1,::1,api.deepseek.com
    selfCheck: true
    tool: true
KeyDefaultPurpose
enabletruemaster switch
proxyUrlautofull proxy URL; when empty the order is port → Windows system proxy → exported env var
host127.0.0.1local proxy host
port0explicit port
noProxysee aboveNO_PROXY contents
overridefalseoverwrite existing variables
patchGlobalDispatchertruedynamically import undici and switch the global dispatcher to EnvHttpProxyAgent, so runtime Node requests use the proxy too
selfChecktruerun the check at startup
writeReporttruewrite $DSH_HOME/proxy-env/report.json
tooltrueregister the proxy_env_check tool
probeUrlhttps://www.google.comonly reachable through the proxy
directProbeUrlhttps://example.comreachable directly
dnsHostexample.comhost used for the fake-ip check
timeoutMs15000per-probe timeout

The tool it registers

ToolArgumentsReturns
proxy_env_checkprobe_url, skip_networkone-line verdict plus the full chain report

Limitations

  • It covers process environment, not web_fetch. DSH's web_fetch pins connections with a custom undici Agent (SSRF / DNS-rebinding defence) and bypasses the global dispatcher by design, so it will not use the proxy even when everything else does. For blocked sites use a cloud-based page reader, or have the agent fetch with node / python from a shell.
  • Registry reading shells out to reg.exe, with stdout redirected to a temp file rather than a pipe (pipes fail with EPERM inside restricted-token sandboxes). When unreadable it falls back to an exported HTTPS_PROXY / HTTP_PROXY.
  • Non-Windows hosts use configuration and environment variables only.
  • patchGlobalDispatcher is a runtime switch: it needs undici to resolve and a version that ships EnvHttpProxyAgent (the only variant that honours NO_PROXY). Otherwise it is skipped and logged.

Related projects


Development

node --check src/*.mjs      # or: npm run check
npm test                    # or: node --test tests/*.test.mjs
node src/cli.mjs            # self-check against the current machine

License

MIT