proxyctl 0.5.3__tar.gz → 0.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {proxyctl-0.5.3 → proxyctl-0.5.4}/PKG-INFO +1 -1
- {proxyctl-0.5.3 → proxyctl-0.5.4}/pyproject.toml +1 -1
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/cli.py +29 -22
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/explain.py +25 -6
- {proxyctl-0.5.3 → proxyctl-0.5.4}/.gitignore +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/LICENSE +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/README.md +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/man/proxyctl.1 +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/__init__.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/_io.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/audit.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/autostart.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/builtin_plugins/__init__.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/builtin_plugins/connectivity_basic.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/builtin_plugins/corp_network.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/check.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/completion.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/core/__init__.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/core/plugin.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/engine/__init__.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/engine/base.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/engine/mihomo.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/engine/singbox.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/status.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/subscription.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/suggest.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/suggest_rules.py +0 -0
- {proxyctl-0.5.3 → proxyctl-0.5.4}/src/proxyctl/trace.py +0 -0
|
@@ -2010,32 +2010,39 @@ def _plan_engine(backend, target: str) -> list[dict]:
|
|
|
2010
2010
|
|
|
2011
2011
|
|
|
2012
2012
|
def _plan_fix(backend, config) -> list[dict]:
|
|
2013
|
-
"""fix 的 plan
|
|
2013
|
+
"""fix 的 plan(v0.5.4:按平台分支)。
|
|
2014
|
+
|
|
2015
|
+
Linux:cmd_fix 仅走 Clash API 热重载,不改系统 DNS(systemd-resolved
|
|
2016
|
+
上的 127.0.0.53 stub 不该被 networksetup 替换)。plan 同步只出 http_put。
|
|
2017
|
+
macOS:保留 DNS 重写 + 缓存清理 + 热重载三步。
|
|
2014
2018
|
|
|
2015
2019
|
networksetup / scutil 迭代型操作不可逐条 argv 化(每个网络服务调一次),
|
|
2016
|
-
标 action=system_op + 描述性 target。
|
|
2017
|
-
|
|
2018
|
-
contract test 不做 subprocess 子集校验(plugin 可注入),只校验
|
|
2019
|
-
placeholder 已消除(< / > 字符不出现)。
|
|
2020
|
+
标 action=system_op + 描述性 target。contract test 不做 subprocess 子集
|
|
2021
|
+
校验(plugin 可注入),只校验 placeholder 已消除。
|
|
2020
2022
|
"""
|
|
2021
2023
|
api_base = config.get('api_base', 'http://127.0.0.1:9090')
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2024
|
+
plan = []
|
|
2025
|
+
if IS_MACOS:
|
|
2026
|
+
plan.extend([
|
|
2027
|
+
{"action": "system_op",
|
|
2028
|
+
"target": "networksetup -setdnsservers (per service) 127.0.0.1",
|
|
2029
|
+
"summary": "重置系统 DNS 指向 127.0.0.1(对抗 DHCP 续租)",
|
|
2030
|
+
"reversible": True, "requires_sudo": True,
|
|
2031
|
+
"side_effects": ["system"]},
|
|
2032
|
+
{"action": "system_op",
|
|
2033
|
+
"target": "scutil DNS reset + dscacheutil -flushcache",
|
|
2034
|
+
"summary": "清 macOS DNS 缓存(含 fakeip 表)",
|
|
2035
|
+
"reversible": True, "requires_sudo": True,
|
|
2036
|
+
"side_effects": ["cache"]},
|
|
2037
|
+
])
|
|
2038
|
+
plan.append({
|
|
2039
|
+
"action": "http_put",
|
|
2040
|
+
"target": f"{api_base}/configs?force=true",
|
|
2041
|
+
"summary": "向 Clash API 发热重载请求(不重启进程)",
|
|
2042
|
+
"reversible": True,
|
|
2043
|
+
"side_effects": ["network-io"],
|
|
2044
|
+
})
|
|
2045
|
+
return plan
|
|
2039
2046
|
|
|
2040
2047
|
|
|
2041
2048
|
def _plan_audit_apply(days: int, backend, config: dict) -> list[dict]:
|
|
@@ -1544,6 +1544,12 @@ def cmd_doctor(args: list, backend, config) -> None:
|
|
|
1544
1544
|
port = config.get("proxy_port", 7890)
|
|
1545
1545
|
api_base = config.get("api_base", "http://127.0.0.1:9090")
|
|
1546
1546
|
|
|
1547
|
+
# mode 先取(dns_ok 判定 + 显示均依赖;v0.5.4 起)
|
|
1548
|
+
try:
|
|
1549
|
+
mode_str = get_mode(backend)
|
|
1550
|
+
except Exception:
|
|
1551
|
+
mode_str = "unknown"
|
|
1552
|
+
|
|
1547
1553
|
if suggest_only:
|
|
1548
1554
|
# Fast path:跳过所有 5 项 score 探测(最慢可累计 5-10s)
|
|
1549
1555
|
engine_up = None
|
|
@@ -1560,7 +1566,7 @@ def cmd_doctor(args: list, backend, config) -> None:
|
|
|
1560
1566
|
else:
|
|
1561
1567
|
engine_up = bool(service_running(backend))
|
|
1562
1568
|
port_listen = _tcp_open("127.0.0.1", port)
|
|
1563
|
-
dns_ok =
|
|
1569
|
+
dns_ok = _dns_check_ok(mode_str)
|
|
1564
1570
|
system_proxy_ok = _system_proxy_points_to_loopback(port)
|
|
1565
1571
|
connectivity_ok = (_quick_connectivity(api_base, port)
|
|
1566
1572
|
if engine_up else False)
|
|
@@ -1575,10 +1581,6 @@ def cmd_doctor(args: list, backend, config) -> None:
|
|
|
1575
1581
|
hint = _doctor_hint(flags_for_human)
|
|
1576
1582
|
|
|
1577
1583
|
# informational extra(不计分)
|
|
1578
|
-
try:
|
|
1579
|
-
mode_str = get_mode(backend)
|
|
1580
|
-
except Exception:
|
|
1581
|
-
mode_str = "unknown"
|
|
1582
1584
|
try:
|
|
1583
1585
|
held = _io.held_lock_names()
|
|
1584
1586
|
except Exception:
|
|
@@ -1643,7 +1645,9 @@ def cmd_doctor(args: list, backend, config) -> None:
|
|
|
1643
1645
|
f"{DIM}engine={backend.name}{ev_tag} mode={mode_str} port={port}{NC}")
|
|
1644
1646
|
print(f" {icon(engine_up)} engine_up ({backend.name} 服务运行中)")
|
|
1645
1647
|
print(f" {icon(port_listen)} port_listen (127.0.0.1:{port})")
|
|
1646
|
-
|
|
1648
|
+
dns_desc = ("proxy 模式无需 DNS 劫持" if mode_str == "proxy"
|
|
1649
|
+
else "系统 DNS 含 127.0.0.1")
|
|
1650
|
+
print(f" {icon(dns_ok)} dns_ok ({dns_desc})")
|
|
1647
1651
|
print(f" {icon(system_proxy_ok)} system_proxy_ok (macOS HTTP/HTTPS proxy)")
|
|
1648
1652
|
print(f" {icon(connectivity_ok)} connectivity_ok (https://www.google.com via proxy)")
|
|
1649
1653
|
if held:
|
|
@@ -1765,6 +1769,21 @@ def _dns_points_to_loopback() -> bool:
|
|
|
1765
1769
|
return False
|
|
1766
1770
|
|
|
1767
1771
|
|
|
1772
|
+
def _dns_check_ok(mode: str) -> bool:
|
|
1773
|
+
"""doctor dns_ok 判定(v0.5.4:mode-aware)。
|
|
1774
|
+
|
|
1775
|
+
proxy 模式无需系统 DNS 指向 127.0.0.1——流量走 HTTP/SOCKS 代理,
|
|
1776
|
+
mihomo 不在 :53 监听,系统 DNS 用 systemd-resolved / DHCP 默认即可。
|
|
1777
|
+
旧逻辑在 Ubuntu(DNS=127.0.0.53 stub)+ proxy 模式下永远判 ✗
|
|
1778
|
+
并建议 `proxyctl fix`——但 fix 的 DNS 改写只对 macOS TUN 模式有意义。
|
|
1779
|
+
|
|
1780
|
+
tun / mixed / 未知模式:保留旧的"系统 DNS 含 127.0.0.1"判定。
|
|
1781
|
+
"""
|
|
1782
|
+
if mode == "proxy":
|
|
1783
|
+
return True
|
|
1784
|
+
return _dns_points_to_loopback()
|
|
1785
|
+
|
|
1786
|
+
|
|
1768
1787
|
def _system_proxy_points_to_loopback(port: int) -> bool:
|
|
1769
1788
|
"""macOS:networksetup -getwebproxy 是否指向 127.0.0.1:port。Linux:跳过判 True。"""
|
|
1770
1789
|
if sys.platform != "darwin":
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|