mihomo-cli 2.6.1 → 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 +9 -1
- package/dist/index.js +45 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.6.2] - 2026-05-03
|
|
4
|
+
|
|
5
|
+
### 改进
|
|
6
|
+
|
|
7
|
+
- **配置校验增强** - 新增重名节点/分组去重、无效规则清理,覆盖更多启动失败场景
|
|
8
|
+
- 移除多余的 `mihomo -t` 预校验(启动本身即校验)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
3
12
|
## [2.6.1] - 2026-05-03
|
|
4
13
|
|
|
5
14
|
### 修复
|
|
6
15
|
|
|
7
16
|
- **启动前配置校验** - 自动检测并修复 proxy-group 中引用不存在的节点/分组,避免内核启动失败
|
|
8
|
-
- 写入配置后使用 `mihomo -t` 做内核级校验,提前发现配置错误
|
|
9
17
|
|
|
10
18
|
### 改进
|
|
11
19
|
|
package/dist/index.js
CHANGED
|
@@ -3113,19 +3113,42 @@ function excludeOverwriteProxiesFromIncludeAll(config, overwriteFiles) {
|
|
|
3113
3113
|
}
|
|
3114
3114
|
}
|
|
3115
3115
|
var BUILTIN_PROXY_NAMES = /* @__PURE__ */ new Set(["DIRECT", "REJECT", "REJECT-DROP", "PASS", "COMPATIBLE"]);
|
|
3116
|
-
function
|
|
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) {
|
|
3117
3130
|
const warnings = [];
|
|
3118
3131
|
const proxies = config.proxies || [];
|
|
3119
3132
|
const groups = config["proxy-groups"] || [];
|
|
3120
|
-
|
|
3121
|
-
const
|
|
3122
|
-
|
|
3123
|
-
|
|
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;
|
|
3124
3147
|
const removedGroups = /* @__PURE__ */ new Set();
|
|
3125
3148
|
let changed = true;
|
|
3126
3149
|
while (changed) {
|
|
3127
3150
|
changed = false;
|
|
3128
|
-
for (const group of
|
|
3151
|
+
for (const group of activeGroups) {
|
|
3129
3152
|
if (removedGroups.has(group.name)) continue;
|
|
3130
3153
|
if (!Array.isArray(group.proxies)) continue;
|
|
3131
3154
|
const invalid = group.proxies.filter((name) => !validNames.has(name));
|
|
@@ -3142,7 +3165,21 @@ function validateProxyGroupDependencies(config) {
|
|
|
3142
3165
|
}
|
|
3143
3166
|
}
|
|
3144
3167
|
if (removedGroups.size > 0) {
|
|
3145
|
-
config["proxy-groups"] =
|
|
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
|
+
}
|
|
3146
3183
|
}
|
|
3147
3184
|
return warnings;
|
|
3148
3185
|
}
|
|
@@ -3199,23 +3236,9 @@ function buildConfig(subRawContent, mode) {
|
|
|
3199
3236
|
"skip-domain": ["+.push.apple.com"]
|
|
3200
3237
|
};
|
|
3201
3238
|
}
|
|
3202
|
-
const warnings =
|
|
3239
|
+
const warnings = validateConfig(merged);
|
|
3203
3240
|
return { config: merged, subscriptionConfig, overwriteFiles, systemConfig, warnings };
|
|
3204
3241
|
}
|
|
3205
|
-
function checkConfig() {
|
|
3206
|
-
if (!hasKernel() || !hasConfig()) return { ok: true, errors: [] };
|
|
3207
|
-
try {
|
|
3208
|
-
execSync(`"${PATHS.mihomoBinary}" -t -f "${PATHS.configFile}" 2>&1`, { encoding: "utf8" });
|
|
3209
|
-
return { ok: true, errors: [] };
|
|
3210
|
-
} catch (e) {
|
|
3211
|
-
const output = e.stdout || e.message || "";
|
|
3212
|
-
const errors = output.split("\n").filter((line) => line.includes("level=error") || line.includes("level=fatal")).map((line) => {
|
|
3213
|
-
const match = line.match(/msg="(.+)"/);
|
|
3214
|
-
return match ? match[1] : line;
|
|
3215
|
-
});
|
|
3216
|
-
return { ok: false, errors };
|
|
3217
|
-
}
|
|
3218
|
-
}
|
|
3219
3242
|
function writeMihomoConfig(configObj) {
|
|
3220
3243
|
ensureDirs();
|
|
3221
3244
|
const content = jsYaml.dump(configObj, { indent: 2, lineWidth: -1, noCompatMode: true });
|
|
@@ -4500,12 +4523,6 @@ function prepareConfigForStart(mode, subName = "default") {
|
|
|
4500
4523
|
}
|
|
4501
4524
|
writeMihomoConfig(buildResult.config);
|
|
4502
4525
|
writeDebugConfig(buildResult);
|
|
4503
|
-
const configCheck = checkConfig();
|
|
4504
|
-
if (!configCheck.ok) {
|
|
4505
|
-
const errorDetail = configCheck.errors.length > 0 ? configCheck.errors.join("\n ") : "\u672A\u77E5\u9519\u8BEF";
|
|
4506
|
-
throw new Error(`\u914D\u7F6E\u6821\u9A8C\u5931\u8D25:
|
|
4507
|
-
${errorDetail}`);
|
|
4508
|
-
}
|
|
4509
4526
|
const proxies = buildResult.config.proxies;
|
|
4510
4527
|
const proxyGroups = buildResult.config["proxy-groups"];
|
|
4511
4528
|
return {
|