mihomo-cli 2.7.1 → 2.7.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,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.7.2] - 2026-05-04
4
+
5
+ ### 修复
6
+
7
+ - **进度条轮次标题** - 多轮测试时第 1 轮标题正确显示在进度条之前,单轮不显示轮次标题
8
+
9
+ ### 改进
10
+
11
+ - **自定义轮数** - clean 命令支持 `-r N` / `--rounds N` 指定测试轮数(默认 3)
12
+
13
+ ---
14
+
3
15
  ## [2.7.1] - 2026-05-04
4
16
 
5
17
  ### 修复
package/README.md CHANGED
@@ -102,9 +102,9 @@ mihomo ui yacd # YACD
102
102
  | `mihomo sub remove <name>` | 删除订阅(支持模糊匹配) |
103
103
  | `mihomo sub web [name]` | 打开订阅页面(无参打开默认) |
104
104
  | `mihomo sub test [name]` | 测试节点连通性(`-t` 超时,`-j` 并发) |
105
- | `mihomo sub clean [name]` | 测速并清理失败节点 |
105
+ | `mihomo sub clean [name]` | 测速并清理失败节点(`-r` 轮数,默认3)|
106
106
  | `mihomo test` | 快速测试当前节点连通性(`-t` 超时,`-j` 并发) |
107
- | `mihomo clean` | 清理失败节点并自动重启(`-t` 超时,`-j` 并发) |
107
+ | `mihomo clean` | 清理失败节点并自动重启(`-t` 超时,`-j` 并发,`-r` 轮数) |
108
108
 
109
109
  ### 覆写配置
110
110
 
package/dist/index.js CHANGED
@@ -4031,7 +4031,7 @@ ${colors.cyan("\u8BA2\u9605:")}
4031
4031
  ${colors.bold("subscription")} test [name] \u6D4B\u8BD5\u8282\u70B9\u8FDE\u901A\u6027
4032
4032
  ${colors.bold("subscription")} clean [name] \u6D4B\u901F\u5E76\u6E05\u7406\u5931\u8D25\u8282\u70B9
4033
4033
  ${colors.bold("test")} [-t ms] [-j N] \u5FEB\u901F\u6D4B\u8BD5\u5F53\u524D\u8282\u70B9\u8FDE\u901A\u6027
4034
- ${colors.bold("clean")} [-t ms] [-j N] \u6E05\u7406\u5931\u8D25\u8282\u70B9\u5E76\u81EA\u52A8\u91CD\u542F
4034
+ ${colors.bold("clean")} [-t ms] [-j N] [-r N] \u6E05\u7406\u5931\u8D25\u8282\u70B9\u5E76\u81EA\u52A8\u91CD\u542F
4035
4035
 
4036
4036
  ${colors.cyan("\u914D\u7F6E:")}
4037
4037
  ${colors.bold("overwrite")} \u67E5\u770B\u8986\u5199\u72B6\u6001\uFF08\u522B\u540D ow\uFF09
@@ -4812,7 +4812,7 @@ function cleanDeadProxies(parsed, deadNames) {
4812
4812
  }
4813
4813
  async function autoCleanSubscription(subName, options = {}) {
4814
4814
  const parsed = loadSubscriptionConfig(subName);
4815
- const { onResult, onRetryRound, ...testOptions } = options;
4815
+ const { onResult, onRetryRound, rounds = 3, ...testOptions } = options;
4816
4816
  const wrapOnResult = (round) => onResult ? (r, i, t) => onResult(r, i, t, round) : void 0;
4817
4817
  const summary = await testSubscriptionProxies(subName, {
4818
4818
  ...testOptions,
@@ -4829,7 +4829,7 @@ async function autoCleanSubscription(subName, options = {}) {
4829
4829
  } else {
4830
4830
  const deadNames = new Set(summary.results.filter((r) => r.delay === null).map((r) => r.name));
4831
4831
  const deadProxies = parsed.proxies.filter((p) => deadNames.has(p.name));
4832
- for (let retry = 0; retry < 2; retry++) {
4832
+ for (let retry = 0; retry < rounds - 1; retry++) {
4833
4833
  const round = retry + 2;
4834
4834
  const retryTargets = deadProxies.filter((p) => deadNames.has(p.name));
4835
4835
  if (retryTargets.length === 0) break;
@@ -5042,9 +5042,10 @@ async function withTestInstance(subName, fn) {
5042
5042
  // src/commands/subscription.ts
5043
5043
  var IS_TTY = process.stdout.isTTY === true;
5044
5044
  var BAR_WIDTH = 20;
5045
- function createProgressPrinter() {
5045
+ function createProgressPrinter(totalRounds = 1) {
5046
5046
  let alive = 0;
5047
5047
  let dead = 0;
5048
+ let started = false;
5048
5049
  const resultMap = /* @__PURE__ */ new Map();
5049
5050
  function render(done, total) {
5050
5051
  if (!IS_TTY) return;
@@ -5055,6 +5056,12 @@ function createProgressPrinter() {
5055
5056
  }
5056
5057
  return {
5057
5058
  onResult(result, index, total, round = 1) {
5059
+ if (!started) {
5060
+ started = true;
5061
+ if (totalRounds > 1) {
5062
+ console.log(`--- \u7B2C 1 \u8F6E\u6D4B\u8BD5 (${total} \u4E2A\u8282\u70B9) ---`);
5063
+ }
5064
+ }
5058
5065
  if (result.delay !== null) alive++;
5059
5066
  else dead++;
5060
5067
  resultMap.set(result.name, { result, round });
@@ -5382,14 +5389,16 @@ async function cmdSubscription(args) {
5382
5389
  }
5383
5390
  if (action === "clean") {
5384
5391
  const { target, timeout, concurrency } = resolveTestTarget(args);
5392
+ const rounds = parseIntArg(args, "-r", "--rounds", 3);
5385
5393
  console.log(`\u6E05\u7406\u8BA2\u9605 "${target.name}"...`);
5386
5394
  console.log(`\u8D85\u65F6: ${timeout}ms \u5E76\u53D1: ${concurrency}`);
5387
5395
  console.log("");
5388
- const progress = createProgressPrinter();
5396
+ const progress = createProgressPrinter(rounds);
5389
5397
  const result = await withTestInstance(target.name, async (apiBase) => {
5390
5398
  return autoCleanSubscription(target.name, {
5391
5399
  timeout,
5392
5400
  concurrency,
5401
+ rounds,
5393
5402
  apiBase,
5394
5403
  onResult: progress.onResult,
5395
5404
  onRetryRound: progress.onRetryRound
@@ -5491,7 +5500,7 @@ async function cmdStart(args) {
5491
5500
  console.log(`\u8282\u70B9\u6570 ${configInfo.proxies} \u8D85\u8FC7 ${AUTO_CLEAN_THRESHOLD}\uFF0C\u81EA\u52A8\u6E05\u7406...`);
5492
5501
  console.log("");
5493
5502
  await sleep(1e3);
5494
- const progress = createProgressPrinter();
5503
+ const progress = createProgressPrinter(3);
5495
5504
  const cleanResult = await autoCleanSubscription(sub.name, {
5496
5505
  onResult: progress.onResult,
5497
5506
  onRetryRound: progress.onRetryRound
@@ -5803,13 +5812,15 @@ async function cmdClean(args) {
5803
5812
  const activeSub = requireActiveSub();
5804
5813
  const timeout = parseIntArg(args, "-t", "--timeout", 1500);
5805
5814
  const concurrency = parseIntArg(args, "-j", "--concurrency", 100);
5815
+ const rounds = parseIntArg(args, "-r", "--rounds", 3);
5806
5816
  console.log(`\u6E05\u7406 "${activeSub.name}" \u5931\u8D25\u8282\u70B9...`);
5807
5817
  console.log(`\u8D85\u65F6: ${timeout}ms \u5E76\u53D1: ${concurrency}`);
5808
5818
  console.log("");
5809
- const progress = createProgressPrinter();
5819
+ const progress = createProgressPrinter(rounds);
5810
5820
  const result = await autoCleanSubscription(activeSub.name, {
5811
5821
  timeout,
5812
5822
  concurrency,
5823
+ rounds,
5813
5824
  onResult: progress.onResult,
5814
5825
  onRetryRound: progress.onRetryRound
5815
5826
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mihomo-cli",
3
- "version": "2.7.1",
3
+ "version": "2.7.2",
4
4
  "type": "module",
5
5
  "description": "A terminal-based mihomo (Clash.Meta) client for macOS",
6
6
  "bin": {