mihomo-cli 2.6.0 → 2.6.2

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.
package/CHANGELOG.md CHANGED
@@ -1,11 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.6.2] - 2026-05-03
4
+
5
+ ### 改进
6
+
7
+ - **配置校验增强** - 新增重名节点/分组去重、无效规则清理,覆盖更多启动失败场景
8
+ - 移除多余的 `mihomo -t` 预校验(启动本身即校验)
9
+
10
+ ---
11
+
12
+ ## [2.6.1] - 2026-05-03
13
+
14
+ ### 修复
15
+
16
+ - **启动前配置校验** - 自动检测并修复 proxy-group 中引用不存在的节点/分组,避免内核启动失败
17
+
18
+ ### 改进
19
+
20
+ - 移除已废弃的 `global-client-fingerprint` 配置项,消除内核启动时的 warning
21
+
22
+ ---
23
+
3
24
  ## [2.6.0] - 2026-05-03
4
25
 
5
26
  ### 改进
6
27
 
7
28
  - **统一使用 mixed-port**:用 `mixed-port: 7890` 替代原来的 `port: 7890` + `socks-port: 7891`,单端口同时支持 HTTP 和 SOCKS5
8
- - **BASE_CONFIG 优化**:新增 `unified-delay`、`tcp-concurrent`、`global-client-fingerprint`、`geo-auto-update`、`profile.store-selected`,不再依赖订阅自带这些配置
29
+ - **BASE_CONFIG 优化**:新增 `unified-delay`、`tcp-concurrent`、`geo-auto-update`、`profile.store-selected`,不再依赖订阅自带这些配置
9
30
  - **自动启用 sniffer**:检测到 `fake-ip` 模式时自动注入 sniffer 配置(嗅探 HTTP/TLS/QUIC),确保域名规则正常工作;订阅自带 sniffer 时不覆盖
10
31
 
11
32
  ---
package/dist/index.js CHANGED
@@ -2707,7 +2707,6 @@ var BASE_CONFIG = {
2707
2707
  "external-controller": "127.0.0.1:9090",
2708
2708
  "unified-delay": true,
2709
2709
  "tcp-concurrent": true,
2710
- "global-client-fingerprint": "chrome",
2711
2710
  "geo-auto-update": true,
2712
2711
  "geo-update-interval": 24,
2713
2712
  "geodata-mode": true,
@@ -3113,6 +3112,77 @@ function excludeOverwriteProxiesFromIncludeAll(config, overwriteFiles) {
3113
3112
  }
3114
3113
  }
3115
3114
  }
3115
+ var BUILTIN_PROXY_NAMES = /* @__PURE__ */ new Set(["DIRECT", "REJECT", "REJECT-DROP", "PASS", "COMPATIBLE"]);
3116
+ function deduplicateByName(items) {
3117
+ const names = /* @__PURE__ */ new Set();
3118
+ const duplicates = [];
3119
+ const result = items.filter((item) => {
3120
+ if (names.has(item.name)) {
3121
+ duplicates.push(item.name);
3122
+ return false;
3123
+ }
3124
+ names.add(item.name);
3125
+ return true;
3126
+ });
3127
+ return { result, names, duplicates };
3128
+ }
3129
+ function validateConfig(config) {
3130
+ const warnings = [];
3131
+ const proxies = config.proxies || [];
3132
+ const groups = config["proxy-groups"] || [];
3133
+ const rules = config.rules || [];
3134
+ const proxyDedup = deduplicateByName(proxies);
3135
+ config.proxies = proxyDedup.result;
3136
+ if (proxyDedup.duplicates.length > 0) {
3137
+ const preview = proxyDedup.duplicates.slice(0, 3).map((n) => `"${n}"`).join(", ");
3138
+ warnings.push(`\u79FB\u9664\u4E86 ${proxyDedup.duplicates.length} \u4E2A\u91CD\u540D\u8282\u70B9: ${preview}${proxyDedup.duplicates.length > 3 ? " ..." : ""}`);
3139
+ }
3140
+ const groupDedup = deduplicateByName(groups);
3141
+ config["proxy-groups"] = groupDedup.result;
3142
+ if (groupDedup.duplicates.length > 0) {
3143
+ warnings.push(`\u79FB\u9664\u4E86 ${groupDedup.duplicates.length} \u4E2A\u91CD\u540D\u5206\u7EC4: ${groupDedup.duplicates.map((n) => `"${n}"`).join(", ")}`);
3144
+ }
3145
+ const validNames = /* @__PURE__ */ new Set([...BUILTIN_PROXY_NAMES, ...proxyDedup.names, ...groupDedup.names]);
3146
+ const activeGroups = groupDedup.result;
3147
+ const removedGroups = /* @__PURE__ */ new Set();
3148
+ let changed = true;
3149
+ while (changed) {
3150
+ changed = false;
3151
+ for (const group of activeGroups) {
3152
+ if (removedGroups.has(group.name)) continue;
3153
+ if (!Array.isArray(group.proxies)) continue;
3154
+ const invalid = group.proxies.filter((name) => !validNames.has(name));
3155
+ if (invalid.length === 0) continue;
3156
+ group.proxies = group.proxies.filter((name) => validNames.has(name));
3157
+ warnings.push(`proxy-group "${group.name}": \u79FB\u9664\u4E86\u4E0D\u5B58\u5728\u7684\u5F15\u7528 ${invalid.map((n) => `"${n}"`).join(", ")}`);
3158
+ const hasOtherSource = group.use || group["include-all"] || group["include-all-proxies"];
3159
+ if (group.proxies.length === 0 && !hasOtherSource) {
3160
+ removedGroups.add(group.name);
3161
+ validNames.delete(group.name);
3162
+ warnings.push(`proxy-group "${group.name}": \u5DF2\u79FB\u9664\uFF08\u65E0\u53EF\u7528\u8282\u70B9\uFF09`);
3163
+ changed = true;
3164
+ }
3165
+ }
3166
+ }
3167
+ if (removedGroups.size > 0) {
3168
+ config["proxy-groups"] = activeGroups.filter((g) => !removedGroups.has(g.name));
3169
+ }
3170
+ if (rules.length > 0) {
3171
+ const removedRules = [];
3172
+ config.rules = rules.filter((rule) => {
3173
+ const parts = rule.split(",");
3174
+ if (parts.length < 2) return true;
3175
+ const target = parts[parts.length - 1].trim();
3176
+ if (!target || validNames.has(target)) return true;
3177
+ removedRules.push(rule);
3178
+ return false;
3179
+ });
3180
+ if (removedRules.length > 0) {
3181
+ warnings.push(`\u79FB\u9664\u4E86 ${removedRules.length} \u6761\u5F15\u7528\u4E0D\u5B58\u5728\u76EE\u6807\u7684\u89C4\u5219`);
3182
+ }
3183
+ }
3184
+ return warnings;
3185
+ }
3116
3186
  function buildConfig(subRawContent, mode) {
3117
3187
  const subscriptionConfig = parseYamlOrJson(subRawContent, "\u8BA2\u9605\u5185\u5BB9");
3118
3188
  if (!subscriptionConfig) {
@@ -3166,7 +3236,8 @@ function buildConfig(subRawContent, mode) {
3166
3236
  "skip-domain": ["+.push.apple.com"]
3167
3237
  };
3168
3238
  }
3169
- return { config: merged, subscriptionConfig, overwriteFiles, systemConfig };
3239
+ const warnings = validateConfig(merged);
3240
+ return { config: merged, subscriptionConfig, overwriteFiles, systemConfig, warnings };
3170
3241
  }
3171
3242
  function writeMihomoConfig(configObj) {
3172
3243
  ensureDirs();
@@ -4444,6 +4515,12 @@ function prepareConfigForStart(mode, subName = "default") {
4444
4515
  throw new Error(`\u672A\u627E\u5230\u8BA2\u9605\u914D\u7F6E "${subName}"\uFF0C\u8BF7\u5148\u6DFB\u52A0\u8BA2\u9605`);
4445
4516
  }
4446
4517
  const buildResult = buildConfig(rawContent, mode);
4518
+ if (buildResult.warnings.length > 0) {
4519
+ for (const warning of buildResult.warnings) {
4520
+ console.log(`${colors.yellow("\u81EA\u52A8\u4FEE\u590D:")} ${warning}`);
4521
+ }
4522
+ console.log("");
4523
+ }
4447
4524
  writeMihomoConfig(buildResult.config);
4448
4525
  writeDebugConfig(buildResult);
4449
4526
  const proxies = buildResult.config.proxies;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mihomo-cli",
3
- "version": "2.6.0",
3
+ "version": "2.6.2",
4
4
  "type": "module",
5
5
  "description": "A terminal-based mihomo (Clash.Meta) client for macOS",
6
6
  "bin": {