mihomo-cli 2.8.1 → 2.9.0

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,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.9.0] - 2026-05-13
4
+
5
+ ### 新功能
6
+
7
+ - **跳过自动更新** - `start -s` 跳过启动时的订阅自动更新
8
+ - **自动更新超时** - `start -u <ms>` 设置自动更新超时时间(默认 10 秒),超时后使用缓存配置继续启动
9
+ - **通用 Promise 超时工具** - 新增 `withTimeout` / `TimeoutError` 工具函数
10
+
11
+ ### 变更
12
+
13
+ - **命令别名调整** - 移除 `mmc`,新增 `mhm` 作为命令别名
14
+
15
+ ---
16
+
3
17
  ## [2.8.1] - 2026-05-07
4
18
 
5
19
  ### 修复
package/README.md CHANGED
@@ -83,7 +83,7 @@ mihomo ui yacd # YACD
83
83
 
84
84
  | 命令 | 说明 |
85
85
  | --------------------------- | ---------------------------------------------------------------------------- |
86
- | `mihomo start [tun\|mixed]` | 启动/重启/切换代理模式(`-r` 清理轮次,`-t` 超时,`-j` 并发) |
86
+ | `mihomo start [tun\|mixed]` | 启动/重启/切换代理模式(`-s` 跳过更新,`-u` 更新超时,`-r` 清理轮次,`-t` 超时,`-j` 并发) |
87
87
  | `mihomo stop` | 停止代理 |
88
88
  | `mihomo status` | 查看运行状态 |
89
89
  | `mihomo log` | 实时查看日志 (`-o` 用系统编辑器打开) |
@@ -142,7 +142,7 @@ mihomo ui yacd # YACD
142
142
 
143
143
  | 快捷命令 | 等效于 |
144
144
  | ---------------------- | -------------------------- |
145
- | `mihomo up` | `mihomo start`(同样支持 `-r`/`-t`/`-j`)|
145
+ | `mihomo up` | `mihomo start`(同样支持 `-s`/`-u`/`-r`/`-t`/`-j`)|
146
146
  | `mihomo down` | `mihomo stop` |
147
147
  | `mihomo tun` | `mihomo start tun` |
148
148
  | `mihomo use <name>` | `mihomo sub use <name>` |
@@ -197,6 +197,7 @@ mihomo kernel --mirror-all hk.gh-proxy.org
197
197
  - 默认更新间隔:GitHub 订阅 6 小时,其他订阅 12 小时(订阅服务端可通过 `profile-update-interval` 覆盖)
198
198
  - 触发时机:`start` 命令、`sub list` 命令
199
199
  - 更新失败时继续使用本地缓存,不影响使用
200
+ - 自动更新默认超时 10 秒,可通过 `-u <ms>` 调整;使用 `-s` 可完全跳过自动更新
200
201
 
201
202
  ## 数据目录
202
203
 
package/dist/index.js CHANGED
@@ -3294,6 +3294,27 @@ function sleepSync(ms) {
3294
3294
  function sleep(ms) {
3295
3295
  return new Promise((resolve) => setTimeout(resolve, ms));
3296
3296
  }
3297
+ var TimeoutError = class extends Error {
3298
+ constructor() {
3299
+ super("timeout");
3300
+ this.name = "TimeoutError";
3301
+ }
3302
+ };
3303
+ function withTimeout(promise, ms) {
3304
+ return new Promise((resolve, reject) => {
3305
+ const timer = setTimeout(() => reject(new TimeoutError()), ms);
3306
+ promise.then(
3307
+ (v) => {
3308
+ clearTimeout(timer);
3309
+ resolve(v);
3310
+ },
3311
+ (e) => {
3312
+ clearTimeout(timer);
3313
+ reject(e);
3314
+ }
3315
+ );
3316
+ });
3317
+ }
3297
3318
  function formatBytes(bytes) {
3298
3319
  if (bytes === void 0 || bytes === null) return "\u672A\u77E5";
3299
3320
  const num = Number(bytes);
@@ -4012,7 +4033,8 @@ ${colors.cyan(colors.bold(`mihomo-cli v${VERSION}`))}
4012
4033
  mihomo <\u547D\u4EE4> [\u9009\u9879]
4013
4034
 
4014
4035
  ${colors.cyan("\u63A7\u5236:")}
4015
- ${colors.bold("start")} [tun|mixed] [-r N] [-t ms] [-j N] \u542F\u52A8/\u5207\u6362\u4EE3\u7406 (\u9ED8\u8BA4 mixed)
4036
+ ${colors.bold("start")} [tun|mixed] [-s] [-u ms] \u542F\u52A8/\u5207\u6362\u4EE3\u7406 (\u9ED8\u8BA4 mixed)
4037
+ [-r N] [-t ms] [-j N]
4016
4038
  ${colors.bold("stop")} \u505C\u6B62\u4EE3\u7406
4017
4039
  ${colors.bold("status")} \u67E5\u770B\u72B6\u6001
4018
4040
 
@@ -4049,6 +4071,8 @@ ${colors.cyan("\u7CFB\u7EDF:")}
4049
4071
  ${colors.cyan("\u793A\u4F8B:")}
4050
4072
  mihomo start # \u542F\u52A8/\u91CD\u542F Mixed \u6A21\u5F0F
4051
4073
  mihomo start tun # \u5207\u6362\u5230 TUN \u900F\u660E\u4EE3\u7406\u6A21\u5F0F
4074
+ mihomo start -s # \u8DF3\u8FC7\u81EA\u52A8\u66F4\u65B0\u8BA2\u9605
4075
+ mihomo start -u 30000 # \u81EA\u52A8\u66F4\u65B0\u8D85\u65F6 30 \u79D2 (\u9ED8\u8BA4 10s)
4052
4076
  mihomo sub add <url> # \u6DFB\u52A0\u8BA2\u9605 (sub \u662F subscription \u522B\u540D)
4053
4077
  mihomo ui # \u6253\u5F00 Web UI
4054
4078
 
@@ -4694,7 +4718,8 @@ async function tryUpdateOne(sub) {
4694
4718
  return { name: sub.name, success: false, error: e.message };
4695
4719
  }
4696
4720
  }
4697
- async function autoUpdateStaleSubscription() {
4721
+ var DEFAULT_AUTO_UPDATE_TIMEOUT = 1e4;
4722
+ async function autoUpdateStaleSubscription(options = {}) {
4698
4723
  const allSubs = getSubscriptionsWithCache();
4699
4724
  const staleSubs = allSubs.filter(needsAutoUpdate);
4700
4725
  if (staleSubs.length === 0) {
@@ -4707,7 +4732,17 @@ async function autoUpdateStaleSubscription() {
4707
4732
  } else {
4708
4733
  console.log(`\u68C0\u67E5\u5230 ${staleSubs.length} \u4E2A\u8BA2\u9605\u9700\u8981\u66F4\u65B0\uFF0C\u6B63\u5728\u5E76\u884C\u66F4\u65B0...`);
4709
4734
  }
4710
- const results = await Promise.all(staleSubs.map(tryUpdateOne));
4735
+ const timeoutMs = options.timeout ?? DEFAULT_AUTO_UPDATE_TIMEOUT;
4736
+ let results;
4737
+ try {
4738
+ results = await withTimeout(Promise.all(staleSubs.map(tryUpdateOne)), timeoutMs);
4739
+ } catch (e) {
4740
+ if (e instanceof TimeoutError) {
4741
+ console.log(colors.yellow(`\u81EA\u52A8\u66F4\u65B0\u8D85\u65F6 (${timeoutMs / 1e3}s)\uFF0C\u8DF3\u8FC7\u66F4\u65B0\uFF0C\u4F7F\u7528\u7F13\u5B58\u914D\u7F6E`));
4742
+ return { total: staleSubs.length, updated: 0, failed: staleSubs.length };
4743
+ }
4744
+ throw e;
4745
+ }
4711
4746
  let updatedCount = 0;
4712
4747
  for (const r of results) {
4713
4748
  if (r.success) {
@@ -5465,12 +5500,16 @@ async function cmdStart(args) {
5465
5500
  const rounds = parseIntArg(args, "-r", "--rounds", DEFAULT_CLEAN_ROUNDS);
5466
5501
  const timeout = parseIntArg(args, "-t", "--timeout", 2e3);
5467
5502
  const concurrency = parseIntArg(args, "-j", "--concurrency", 100);
5503
+ const skipUpdate = hasFlag(args, "-s", "--no-update");
5504
+ const updateTimeout = parseIntArg(args, "-u", "--update-timeout", DEFAULT_AUTO_UPDATE_TIMEOUT);
5468
5505
  const sub = getActiveSubscription();
5469
5506
  if (!sub) {
5470
5507
  console.error("\u9519\u8BEF: \u6CA1\u6709\u8BA2\u9605\uFF0C\u8BF7\u5148\u6DFB\u52A0\u8BA2\u9605");
5471
5508
  process.exit(1);
5472
5509
  }
5473
- await autoUpdateStaleSubscription();
5510
+ if (!skipUpdate) {
5511
+ await autoUpdateStaleSubscription({ timeout: updateTimeout });
5512
+ }
5474
5513
  const status = getStatus();
5475
5514
  const hasProcess = status.running || status.allProcesses.length > 0;
5476
5515
  if (hasProcess) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mihomo-cli",
3
- "version": "2.8.1",
3
+ "version": "2.9.0",
4
4
  "type": "module",
5
5
  "description": "A terminal-based mihomo (Clash.Meta) client for macOS",
6
6
  "bin": {