Releases: crhan/proxyctl
v0.5.12
Fixed
proxyctl env不再把no_proxy_extra中的裸 IPv6 CIDR 写入NO_PROXY。
这避免 Python/httpx 工具把类似fd7a:115c::/48的条目误解析为带非法端口的
URL;域名、IPv4 CIDR 和默认本地绕过项保持不变。
Changed
proxyctl trace的[4/4] 实际连接改为按链路聚合并给出明确结论。
旧版逐条平铺活跃连接、且只取其中一条与规则预测对比,在改规则后的过渡态
(新连接走代理、旧连接仍复用原链路并存)下会自相矛盾地误报"预测出口 X,
实际出口 Y"。新版把相同链路的连接合并计数、累加流量,按"链路是否命中预测
出口"分类,并区分三种结论:全部命中(与规则一致)/ 全部未命中(规则可能
未生效或被前置规则截胡)/ 新旧并存(旧连接在建连时已定死链路,会随超时
自然断开,刷新后即全部走预测出口)。判定改用"预测组名是否出现在链路中"的
集合判定,消除旧版"出口"一词在告警行(取链路入口组)与详情行(取末端节点)
指代不一致的歧义。[4/4]连接采集改为 host 精确匹配优先。 仅在拿不到 host(典型 fake-ip
模式)时才回退按destinationIP匹配,避免 Cloudflare 等共享 IP 把同 IP
其他站点的连接误算进当前域名。
v0.5.11
Fixed
proxyctl trace的规则预测现在尊重no-resolve标志。
域名经 HTTP 代理 / fake-ip 连接时,带no-resolve的 IP 规则(如
IP-CIDR,100.64.0.0/10,DIRECT,no-resolve)会被引擎跳过;[2/4] 规则匹配
不再误报命中这类规则,预测出口与[4/4]实际链路一致。命中其他规则时,
会提示有哪些no-resolveIP 规则因当前连接为域名而被跳过。
v0.5.10
Fixed
proxyctl check连通性面板的via列现在按可见宽度对齐。
彩色状态码和ok/200/401这类不同长度状态不再导致via列左右漂移。proxyctl check连通性via列不再普遍显示?。 v0.5.9 引入的
反查是在curl测试结束之后才查 mihomo/connections,而短连接
curl 一退出连接就从连接表移除,几乎抓不到自己刚发的请求 —— 只有恰好
有外部进程在持续访问同一 host(如 Claude Code 长连api.anthropic.com)
时才会被"蹭"到显示出来。本版改为在 curl 测试进行中并发轮询
/connections,趁连接还活着抓到真实链路;抓不到时回退到既有的外部
连接探测;都没找到时显示via —(em dash 友好占位)而非via ?。- 内置
connectivity-basic插件不再 hardcode 个人代理组名claude。
原先anthropictarget 写死了expected_proxy="claude",且出口探测里
写死了OutboundProbe(name="claude", …),导致没有claude组的用户
跑check会被误判expected claude, got …且出口 IP 段多一行无意义
的claude。命名组校验和命名出口探测属本机特例,请在
~/.config/proxyctl/plugins/的用户插件里追加。 proxyctl check出口 IP 不再出现同名direct行重复。 旧的去重
key 把url也算进比较,内置插件的https://myip.ipip.net和用户
插件的http://myip.ipip.net仅协议不同就漏了去重 → 同一出口显示
两行。本版按(name, mode)折叠:同名同模式视为同一出口行,后加载的
用户插件覆盖内置同名探测(本机特例优先),显示顺序保持稳定。proxyctl audit现在能识别任意命名代理组下的DOMAIN-SUFFIX规则。
_load_rules原本只把outbound ∈ {direct, proxy, claude}三个名字
归类,其它命名组(如residential-tw/jp-streaming等)的规则被
完全忽略 → audit 统计偏低、推荐误报。本版改为"非direct、非
block/reject即视为代理类",任何命名代理组的规则都正确进入
proxy_suffixes。
Changed
_connectivity_line_value("proxy")默认值从"?"改为"—"(em dash),
仅影响check连通性表via列反查失败时的占位字符。JSON 字段
data.stages.connectivity[].line在该场景下从字符串"?"变为"—";
消费方判断"是否有真实链路"建议改用route_chain非空,而不要 string-match
这个占位。
v0.5.9
Added
proxyctl connections支持位置参数关键字 + 跨字段智能匹配。
现在可直接写proxyctl connections codex 443,等价于
--query codex --query 443。每个关键字独立判定命中维度:纯数字关键字
对target_port/source_port/pid做精确比较,文本关键字对
target_host/destination_ip/app/process/command做大小写
不敏感子串匹配;多关键字之间取 AND,每个关键字必须至少命中一个维度。
JSON 输出在每条命中行新增match_reasons: {keyword: [dimensions]}字段,
显示是哪个关键字命中了哪些维度(当本次调用没有任何关键字时,该字段不会
出现在 row dict 上——消费方应按 "key may be absent" 处理)。人类视图启用
ANSI 高亮(黄底黑字)标出命中子串,并在 0 行命中时打印关键字 + 尝试过的
维度提示(仅在本次提供了关键字时打印;仅有--app等结构化过滤而无关键字
时不会打这个提示)。LocalConnection.to_dict()的 JSON 输出新增command字段,把
ps -o command=抓到的完整命令行一并暴露,方便位置参数关键字按命令行匹配,
也便于消费方调试。proxyctl connections --verbose在人类视图展开 socket 明细。
默认 human 视图只渲染目的站点汇总(数量、路由、链路、持有进程计数);加上
--verbose后会在每个目的站点下逐条展开 socket 明细:完整进程路径、命令行、
Mihomo rule / rule_payload / chains / upload / download / start / route_kind,
以及本次位置参数关键字的命中维度(命中: kw=dim1+dim2)。JSON 输出不受
此 flag 影响,明细一直在proxy_owner_connections[]里。proxyctl connections人类视图的上传/下载/开始时间改用人类单位。
上传/下载字节数现在显示为8.0 KiB/1.5 MiB等二进制单位,而不再是
原始字节数;开始时间在 ISO 8601 时间戳后追加相对时长,如
2026-05-23T17:20:27.854916+08:00 (5m20s 前),方便快速判断连接生命周期。
解析失败时回退到原始时间戳,不掩盖原数据。proxyctl connections --verbose自动读取 traffic store 历史数据。
开启--verbose后,命令会去~/.cache/proxyctl/traffic_events.ndjson
(或traffic_store_dir指向的位置)加载proxyctl traffic sample/watch
采样积累的事件流,按 host 索引后挂到每条 socket 上。每个 socket 明细下方
会展开历史块:累计上传/下载、首次/末次见到的时间(含相对时长)、
历史连接数、出现过的进程列表。build_report输出顶层新增history_status
字段记录是否加载成功、读取到几条事件,便于 JSON 消费方判断;human 视图
在 traffic events 为空时一次性提示用户先跑proxyctl traffic watch。proxyctl check连通性面板新增实际路由显示。 proxy 模式的 URL 探测
会从本地 Mihomo/connections读取该站点实际命中的链路,并在人类输出中
显示为via <group> → <leaf>;直连探测显示via direct,DNS/TCP 探测
显示via -,拿不到活跃连接时显示via ?。JSON 输出中的每个
connectivity row 同步新增line和route_chain字段。proxyctl check内置连通性基线新增 OpenAI API 探测。
默认站点现在包含openai(https://api.openai.com/v1/models),并将
anthropic从根路径改为https://api.anthropic.com/v1/models,让 AI
API 健康检查更接近真实调用路径;4xx 仍按“链路已通”处理。
Changed
proxyctl connections --query语义升级(行为变化)。 之前--query
是把多个值在process + target + contexts拼成的大串上做 OR 子串匹配;
现在与位置参数共用 AND + 跨字段独立判定逻辑。多值场景下结果可能比旧版本
更窄(旧 OR → 新 AND),但单值场景下匹配范围反而更宽(不再依赖字段被拼接
的顺序)。脚本里使用--query的用户请确认这一语义变化。proxyctl check连通性成功行统一使用via ...表达。
成功命中期望代理组时,人类输出不再同时显示线路 <leaf>和via ...;
所有连通性行统一保留via <route>。只有期望组不匹配时才追加错误说明。proxyctl check会去重内置插件与用户插件提供的完全相同探测项。
当旧用户插件仍声明与内置插件相同的 connectivity target 或 outbound probe
时,人类输出不再重复显示同一站点或同一出口 IP;不同 URL 或不同 mode 的
同名自定义探测项仍会保留。
Fixed
proxyctl check的 URL 连通性探测改用 HTTP/1.1,避免 Discord 一类站点
因 HTTP/2 协商异常被误报为 timeout。 当curl返回 HTTP code000
时,人类输出现在会显示 stderr 中的简短错误原因;没有 stderr 时仍显示
timeout。
v0.5.8
Fixed
proxyctl check的出口 IP 归属地补全不再依赖被测代理线路。
第 4 阶段会直连查询已探测到的 IP 归属地,避免claude出口失败时影响
direct或proxy的归属地显示。
Changed
- 出口 IP 归属地补全现在并发执行。
proxy/claude/direct
的归属地查询互不阻塞,单个出口查询慢或失败不会拖慢其他出口的显示。
v0.5.7
Changed
proxyctl check现在会显示 mihomo 规则实际引用的代理组。 像
claude这类不挂在默认proxy组下面、但被DOMAIN-SUFFIX,...,claude
规则命中的业务组,会和proxy一起出现在代理组检查段,方便维护者从同一个
视图确认规则、组和节点状态。proxyctl check现在会验证 Anthropic 连通性及 Claude 线路命中。
连通性阶段新增anthropic检查,并在请求后通过本地 mihomo/connections
确认链路末端为claude。- 出口 IP 探测现在覆盖
proxy、claude、direct三类出口。 第 4 阶段
会同时显示默认代理出口、Claude 规则出口和直连出口,方便确认分流是否生效。
v0.5.6
Added
- 新增
proxyctl traffic线路/软件流量统计。snapshot读取 Mihomo
/connections的upload/download并按线路、链路、软件或路由聚合;
sample/watch可把连接计数器增量写入本地缓存;report --since 1h
可按已记录增量生成历史窗口报表。watch在人类输出模式下会每次采样实时打印
进度行。命令复用connections的--host/
--chain/--route/--preset/--agent过滤。首次采样只建立基线,
不回填此前已经产生的字节,避免把活跃连接当前计数误算成历史累计。
Fixed
proxyctl connections现在能显示 macOS Network/System Extension
接管后的 Mihomo 连接 owner 与实际代理链路。 当 OpenAI / ChatGPT 等
连接被本机网络扩展接管时,lsof只能看到扩展进程而不是原始 App。
本版在 macOS 上补充netstat -anv反向归因,JSON 新增
proxy_owner_connections[],包含 socket owner、是否为系统扩展、
Mihomoroute_kind/chains/routed_via_proxy,并新增
proxy_owner_groups[]按rulePayload/ host / IP 聚合目的地。如果同一
目的组出现不同chains或 route kind,会输出warning=mixed_chains
/mixed_route_kind和 summary 里的
inconsistent_proxy_owner_group_count,从而能判断连接是否经过 Mihomo、
最终是proxy还是direct路由,以及同一组线路是否一致。proxyctl connections默认输出全量目的站点,并新增多维过滤。
无参数时不再默认限制 Codex / Claude / ChatGPT;需要 AI 视角时使用
--preset ai。新增--host按 host / rulePayload / IP 过滤,--preset
使用预设(ai/openai/anthropic/coding等),--agent按工具
过滤(codex/claude/chatgpt/openclaw等),--chain/
--line按 Mihomo 链路节点过滤,--route按 route kind 过滤
(proxy/direct/reject/unknown,同时接受中文别名),
--query/--filter做全文过滤。不同维度之间取 AND,同一维度内多个值取 OR。
--app Codex/--app Claude保持向后兼容,分别匹配 App 与 CLI 两类上下文。proxyctl connections的人类输出改用目的站点汇总。 默认输出只按
目的站点展示数量、候选 App / CLI、路由和链路;每个目的站点下会统计
持有进程连接数,例如com.antgroup.asp(pid=47283):8,系统扩展也按普通
进程展示。人类输出里的上下文显示为Claude App/Claude CLI等可读
名称,并使用多行布局展示候选、链路、主机和持有进程,避免长字段挤在
同一行;--json里的proxy_owner_connections[]仍保留逐条 socket 明细。
v0.5.5
Fixed
proxyctl check的 selector/fallback 代理组现在显示全部子组与
真节点成员,不再只显示now那一个子组。 v0.5.3 / v0.5.4 的"精简
显示"为了避免节点重复,把now之外的兄弟子组 summary 行和混在
子组里的真节点成员(如local-13659)都跳过了,导致典型claude → [residential-sg, residential-us, local-13659]这种结构里用户只能看到
当前命中的那一个子组,连"还有哪些可选线路"都不知道。本版恢复全部
子组 summary 可见 + 真节点成员可见,但仍只对now子组展开叶子
节点列表(保留 v0.5.3 跨组去重(详见上方)行为),单组从 ~50 行
精简到 5-7 行的目标不变。
Added
- 新增
proxyctl connections只读诊断命令。 该命令读取本机
lsof/ss/ps连接信息,并在 mihomo 后端下用本地
/connectionsAPI 按metadata.sourcePort关联连接详情。默认过滤
Codex / Claude / ChatGPT,--app <name>可重复指定应用过滤,--all
查看所有进程;--json输出 envelope v2,包含进程、PID、fd、本地源端口、
是否连接到proxy_port、mihomo host/destination/rule/rulePayload/chains/
upload/download/start,以及 unmatched 原因。非 mihomo 后端或本地 API 不可用
时降级输出本机连接并标注 unmatched。
v0.5.4
Fixed
-
doctor在 Linux + proxy 模式下不再误报dns_ok失败。 旧逻辑
_dns_points_to_loopback()简单粗暴读/etc/resolv.conf看是否含
127.0.0.1,但 Ubuntu / Debian 标准是 systemd-resolved 在127.0.0.53:53
起 stub resolver,永远不会匹配 → 永远判 ✗ → doctor 给出next: proxyctl fix
的错误建议,且 fix 的 plan 显示 macOS 风格的networksetup步骤(实际
cmd_fix Linux 路径根本不跑这些)。本版 doctor 改用 mode-aware
_dns_check_ok(mode):proxy 模式直接返回 True(流量走 HTTP/SOCKS 代理,
mihomo 不在 :53 监听,系统 DNS 用 systemd-resolved/DHCP 默认即可),
tun / mixed / 未知模式保留旧的回环判定。doctor 人类输出 dns_ok 描述行
按 mode 切换:(proxy 模式无需 DNS 劫持)或(系统 DNS 含 127.0.0.1)。 -
fix --dry-run在 Linux 不再输出 macOS 风格的 DNS 改写步骤。
_plan_fix按平台分支:Linux 只输出 1 步http_put(Clash API 热重载),
与cmd_fix实际 Linux 路径对齐;macOS 保留三步(DNS reset + cache
flush + reload)。之前 Linux 用户 dry-run 会被 plan 误导以为 fix 要改
系统 DNS。
Compatibility
data.dns_ok字段类型不变(仍是 bool);但 proxy 模式下该字段含义
从"系统 DNS 是否含 127.0.0.1"变为"DNS 配置对当前 mode 是否健康"。
agent 消费data.dns_ok的逻辑无需调整。data.plan[].action枚举不变;Linux 平台 fix plan 步数从 3 降到 1。
v0.5.3
Fixed
proxy_group.mostly_dead规则不再对 selector-of-selectors 误报。
v0.5.0 规则按"直接成员 delay==0"计数,对 mihomo 主流订阅结构
(GLOBAL → 一堆分流子组 + DIRECT/REJECT,其中分流子组通常无 latency
history)会把"没测过延迟的子组"算成 dead,触发假阳 warn。本版改为
穿透 selector / URLTest / Fallback / LoadBalance / Smart 子组到真叶子
节点(去重)后统计;伪节点(DIRECT/REJECT/Pass/Compatible)排除;
循环引用安全。evidence.total_count现在反映叶子节点数。autostart.version_mismatch不再对同一 binary 自比误报。 0.5.2 修了
cli.get_engine_version的v前缀 strip,但autostart.inspect_runtime
里独立解析的autostart_version字段没同步 strip,导致即使 plist 与 PATH
指向同一个 mihomo 二进制,v1.19.25 != 1.19.25字面比较仍触发 advisory。
同时显示文案出现vv1.19.25双前缀。本版两处统一 strip + 同 binary 路径
直接跳过版本对比(同一文件无版本差异)。autostart_versionevidence 字段不再带v前缀,与path_version
对齐,agent 可稳定比较。
Added
-
proxyctl bench跨组去重重复线路 + 穿透 selector 子组到叶子。
之前 bench 只在直接成员层去重,对 GLOBAL → 13 个分流子组的结构会把
子组当节点测(返回组的 now 节点延迟);多个组共享同一子组时叶子被重复
探测 N 次。本版用同款_collect_leaves穿透;伪节点(DIRECT/REJECT)
排除;跨组全局去重。- 人类模式:测速行加
(去重省 N 次)提示 --jsonsummary 新增raw_count(去重前各组叶子和)+
dedup_saved(省下的次数)字段- 实测
proxyctl bench GLOBAL "💬 OpenAi"从 48+ 次探测降到 24 次
- 人类模式:测速行加
-
proxyctl check集成proxy_group.mostly_dead判定。doctor 早就
会报"GLOBAL 组 15/15 节点全挂",但check之前只展示组明细、不参与
fail 判定,agent 看check --json拿到ok=true却感觉不对。本版 check
在 [2/4] 代理组阶段后调用与 doctor 同款的suggest_rules.proxy_group_rules
规则,任何组 ≥70% 节点 delay==0 即:- 人类模式打印红色
✗ GROUP: dead/total 节点不可达 (pct%)行 - exit code 变 1
data.stages.dead_groups[]输出每组结构化事实envelope.hints聚合proxy groups mostly dead: GLOBAL(15/15) — try \proxyctl bench``
- 人类模式打印红色
Added — Agent 提示
- agent-guide 新增
Config Tracking段 + 新 explain topic
config-tracking:建议 agent 在用户机器首次见到~/.config/proxyctl/
无.git时提示用户初始化 git 仓库追踪配置变化,含推荐.gitignore
排除 secret 与高频抖动文件(subscription-source.env/
subscription.json/.lock.*/.ipgeo-*/*.bak)。proxyctl 自己
不做版本控制,跟"不拉订阅"是同一类边界——版本控制是用户/agent 职责。
Changed
-
proxyctl checkexit code 在组挂时变 1(之前永远 0)。--json
输出envelope.ok=false。data.stages.dead_groups[]字段新增。
agent 已消费data.stages.*的需注意此 stage 新增。 -
proxyctl check[2/4] 代理组输出大幅精简。 之前 selector 会把
顶层成员行 + 每个子组的全部节点都列一遍,多个组共享同一子组时节点
列表打 N 遍(n=组数)。本版:- selector / fallback 当 now 指向子组时,跳过顶层成员行(避免与子组
重叠的节点列表重复打印) - 只展开 now 指向的那一个子组(其他子组不展开)
- 跨组去重:已展示过节点列表的子组再次出现时只打摘要行 +
(详见上方) - 实测用户机器从 ~50 行降到 11 行
仅人类模式输出变化;
--json的data.stages.groups[]结构不变。 - selector / fallback 当 now 指向子组时,跳过顶层成员行(避免与子组