mihomo-cli 1.2.2 → 1.2.4

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/index.js CHANGED
@@ -8,6 +8,7 @@ const kernel = require('./src/kernel');
8
8
  const subscription = require('./src/subscription');
9
9
  const processMgr = require('./src/process');
10
10
  const overwrite = require('./src/overwrite');
11
+ const utils = require('./src/utils');
11
12
 
12
13
  const VERSION = require('./package.json').version;
13
14
 
@@ -33,7 +34,7 @@ process.on('SIGTERM', () => {
33
34
  process.exit(0);
34
35
  });
35
36
 
36
- process.on('uncaughtException', (e) => {
37
+ process.on('uncaughtException', e => {
37
38
  console.error('\n未捕获的异常: ' + e.message);
38
39
  if (e.stack) {
39
40
  console.error(e.stack.split('\n').slice(1).join('\n'));
@@ -41,80 +42,79 @@ process.on('uncaughtException', (e) => {
41
42
  process.exit(1);
42
43
  });
43
44
 
44
- process.on('unhandledRejection', (reason) => {
45
+ process.on('unhandledRejection', reason => {
45
46
  const msg = reason instanceof Error ? reason.message : String(reason);
46
47
  console.error('\n未处理的 Promise 拒绝: ' + msg);
47
48
  process.exit(1);
48
49
  });
49
50
 
50
51
  function printShortHelp() {
51
- console.log('\nmihomo-cli v' + VERSION);
52
- console.log('别名: mihomo, mmc, mh\n');
53
- console.log('命令:\n' +
54
- ' start [tun|mixed] 启动/切换代理\n' +
55
- ' stop 停止代理\n' +
56
- ' status 查看状态\n' +
57
- ' ui [zash|dash|yacd] Web 界面\n' +
58
- ' log 实时日志\n' +
59
- ' logs 日志列表\n' +
60
- ' subscription 订阅管理(别名 sub)\n' +
61
- ' overwrite [on|off] 覆写配置(别名 ow)\n' +
62
- ' directory 数据目录(别名 dir)\n' +
63
- ' kernel 更新内核\n' +
64
- ' reset 重置配置\n' +
65
- ' version 版本信息\n');
52
+ console.log('\nmihomo-cli v' + VERSION + ' (mihomo help 查看完整帮助)\n');
53
+ console.log(
54
+ '常用命令:\n' +
55
+ ' start [tun|mixed] 启动/切换代理\n' +
56
+ ' ui [zash|dash|yacd] 打开 Web UI\n' +
57
+ ' ow [on|off] 覆写配置\n' +
58
+ ' sub [use|update] 订阅管理\n',
59
+ );
66
60
  }
67
61
 
68
62
  function printHelp() {
69
- console.log('\nmihomo-cli v' + VERSION + '\n' +
70
- '\n' +
71
- '命令别名: mihomo, mmc, mh\n' +
72
- '\n' +
73
- '用法:\n' +
74
- ' mihomo <命令> [选项]\n' +
75
- '\n' +
76
- '控制:\n' +
77
- ' start [tun|mixed] 启动/切换代理 (默认 mixed)\n' +
78
- ' stop 停止代理\n' +
79
- ' status 查看状态\n' +
80
- '\n' +
81
- '界面:\n' +
82
- ' ui [zash|dash|yacd] 打开 Web UI (默认 zash)\n' +
83
- ' log [-o] 实时日志(-o 打开文件)\n' +
84
- ' logs [编号] [-n N] [-o] 日志列表(0=当前,1+=归档)\n' +
85
- '\n' +
86
- '订阅:\n' +
87
- ' subscription 列出所有订阅(别名 sub)\n' +
88
- ' subscription add <url> [name] 添加订阅\n' +
89
- ' subscription update [name] 更新订阅(无参更新所有)\n' +
90
- ' subscription use <name> 切换默认订阅\n' +
91
- ' subscription web [name] 打开订阅页面\n' +
92
- '\n' +
93
- '配置:\n' +
94
- ' overwrite 查看覆写状态(别名 ow)\n' +
95
- ' overwrite on|off 启用/禁用覆写配置\n' +
96
- ' directory 显示数据目录位置(别名 dir)\n' +
97
- ' directory open [target] 打开目录: root|subs|logs|overwrites|...\n' +
98
- '\n' +
99
- '系统:\n' +
100
- ' kernel [镜像|--no-mirror] 更新内核\n' +
101
- ' reset [--full] 重置用户数据 (--full 同时删除内核)\n' +
102
- ' help, -h 显示帮助\n' +
103
- ' version, -v 显示版本\n' +
104
- '\n' +
105
- '示例:\n' +
106
- ' mihomo start # 启动/重启 Mixed 模式\n' +
107
- ' mihomo start tun # 切换到 TUN 透明代理模式\n' +
108
- ' mihomo sub add <url> # 添加订阅 (sub 是 subscription 别名)\n' +
109
- ' mihomo ui # 打开 Web UI\n' +
110
- '\n' +
111
- '模式说明:\n' +
112
- ' mixed HTTP + SOCKS5 混合端口 (默认)\n' +
113
- ' tun 透明代理,全局自动路由,需要 sudo\n' +
114
- '\n' +
115
- '数据目录:\n' +
116
- ' 环境变量 MIHOMO_CLI_DIR 可自定义位置\n' +
117
- ' 默认: ' + config.USER_DATA_DIR + '\n');
63
+ console.log(
64
+ '\nmihomo-cli v' +
65
+ VERSION +
66
+ '\n' +
67
+ '\n' +
68
+ '命令别名: mihomo, mmc, mh\n' +
69
+ '\n' +
70
+ '用法:\n' +
71
+ ' mihomo <命令> [选项]\n' +
72
+ '\n' +
73
+ '控制:\n' +
74
+ ' start [tun|mixed] 启动/切换代理 (默认 mixed)\n' +
75
+ ' stop 停止代理\n' +
76
+ ' status 查看状态\n' +
77
+ '\n' +
78
+ '界面:\n' +
79
+ ' ui [zash|dash|yacd] 打开 Web UI (默认 zash)\n' +
80
+ ' log [-o] 实时日志(-o 打开文件)\n' +
81
+ ' logs [编号] [-n N] [-o] 日志列表(0=当前,1+=归档)\n' +
82
+ '\n' +
83
+ '订阅:\n' +
84
+ ' subscription 列出所有订阅(别名 sub)\n' +
85
+ ' subscription add <url> [name] 添加订阅\n' +
86
+ ' subscription update [name] 更新订阅(无参更新所有)\n' +
87
+ ' subscription use <name> 切换默认订阅\n' +
88
+ ' subscription web [name] 打开订阅页面\n' +
89
+ '\n' +
90
+ '配置:\n' +
91
+ ' overwrite 查看覆写状态(别名 ow)\n' +
92
+ ' overwrite on|off 启用/禁用覆写配置\n' +
93
+ ' directory 显示数据目录位置(别名 dir)\n' +
94
+ ' directory open [target] 打开目录: root|subs|logs|overwrites|...\n' +
95
+ '\n' +
96
+ '系统:\n' +
97
+ ' kernel [镜像|--no-mirror] 更新内核\n' +
98
+ ' reset [--full] 重置用户数据 (--full 同时删除内核)\n' +
99
+ ' help, -h 显示帮助\n' +
100
+ ' version, -v 显示版本\n' +
101
+ '\n' +
102
+ '示例:\n' +
103
+ ' mihomo start # 启动/重启 Mixed 模式\n' +
104
+ ' mihomo start tun # 切换到 TUN 透明代理模式\n' +
105
+ ' mihomo sub add <url> # 添加订阅 (sub 是 subscription 别名)\n' +
106
+ ' mihomo ui # 打开 Web UI\n' +
107
+ '\n' +
108
+ '模式说明:\n' +
109
+ ' mixed HTTP + SOCKS5 混合端口 (默认)\n' +
110
+ ' tun 透明代理,全局自动路由,需要 sudo\n' +
111
+ '\n' +
112
+ '数据目录:\n' +
113
+ ' 环境变量 MIHOMO_CLI_DIR 可自定义位置\n' +
114
+ ' 默认: ' +
115
+ config.USER_DATA_DIR +
116
+ '\n',
117
+ );
118
118
  }
119
119
 
120
120
  function printVersion() {
@@ -126,9 +126,9 @@ function printVersion() {
126
126
 
127
127
  function printStatus() {
128
128
  const status = processMgr.getStatus();
129
- const info = subscription.getConfigInfo();
129
+ const info = config.getConfigInfo();
130
130
  const owEnabled = overwrite.isOverwriteEnabled();
131
- const owFiles = overwrite.listOverwriteFiles().files;
131
+ const owFiles = overwrite.listOverwriteFile().files;
132
132
  const activeSub = getActiveSubscription();
133
133
 
134
134
  console.log('');
@@ -160,12 +160,7 @@ function printStatus() {
160
160
  if (activeSub) {
161
161
  let subLine = '订阅: ' + activeSub.name;
162
162
  if (info) {
163
- let parts = [];
164
- if (info.proxyGroups && info.proxyGroups > 0) {
165
- parts.push(info.proxyGroups + ' 组');
166
- }
167
- parts.push(info.proxies + ' 节点');
168
- subLine += ' (' + parts.join(', ') + ')';
163
+ subLine += ' (' + subscription.formatProxySummary(info) + ')';
169
164
  }
170
165
  console.log(subLine);
171
166
  } else {
@@ -213,7 +208,7 @@ function findSubscriptionFuzzy(subs, pattern) {
213
208
  return includes;
214
209
  }
215
210
 
216
- function pickSingleSubscription(subs, pattern, actionName) {
211
+ function pickSingleSubscription(subs, pattern) {
217
212
  if (subs.length === 0) {
218
213
  console.error('错误: 未找到匹配 "' + pattern + '" 的订阅');
219
214
  process.exit(1);
@@ -227,32 +222,6 @@ function pickSingleSubscription(subs, pattern, actionName) {
227
222
  process.exit(1);
228
223
  }
229
224
 
230
- function hasFlag(args, short, long) {
231
- return args && (args.includes(short) || args.includes(long));
232
- }
233
-
234
- function parseIntArg(args, short, long, defaultValue) {
235
- if (!args) return defaultValue;
236
- for (let i = 0; i < args.length; i++) {
237
- if (args[i] === short || args[i] === long) {
238
- if (i + 1 < args.length) {
239
- const val = parseInt(args[i + 1]);
240
- return isNaN(val) ? defaultValue : val;
241
- }
242
- }
243
- }
244
- return defaultValue;
245
- }
246
-
247
- function getNonFlagArg(args, startIdx) {
248
- if (!args) return null;
249
- for (let i = startIdx; i < args.length; i++) {
250
- if (!args[i].startsWith('-')) {
251
- return args[i];
252
- }
253
- }
254
- return null;
255
- }
256
225
 
257
226
  function openLogFile(logPath, label) {
258
227
  const displayLabel = label || logPath;
@@ -291,7 +260,7 @@ function viewLogWithTail(logPath, options) {
291
260
  const tail = spawn('tail', tailArgs, { stdio: 'inherit' });
292
261
 
293
262
  tail.on('close', () => process.exit(0));
294
- tail.on('error', (e) => {
263
+ tail.on('error', e => {
295
264
  console.error('无法读取日志: ' + e.message);
296
265
  process.exit(1);
297
266
  });
@@ -311,7 +280,7 @@ async function cmdStart(args) {
311
280
  process.exit(1);
312
281
  }
313
282
 
314
- await subscription.autoUpdateStaleSubscriptions();
283
+ await subscription.autoUpdateStaleSubscription();
315
284
 
316
285
  // 每次 start 都先确保完全干净的状态(停止进程 + 清理运行时文件)
317
286
  const status = processMgr.getStatus();
@@ -344,10 +313,7 @@ async function cmdStart(args) {
344
313
  }
345
314
 
346
315
  const modeLabel = targetMode === 'tun' ? 'TUN' : 'Mixed';
347
- const parts = [];
348
- if (cfgInfo.proxyGroups && cfgInfo.proxyGroups > 0) parts.push(cfgInfo.proxyGroups + ' 组');
349
- parts.push(cfgInfo.proxies + ' 节点');
350
- console.log([modeLabel, sub.name, parts.join(', ')].join(' · '));
316
+ console.log([modeLabel, sub.name, subscription.formatProxySummary(cfgInfo)].join(' · '));
351
317
 
352
318
  try {
353
319
  const result = await processMgr.start(targetMode);
@@ -377,7 +343,7 @@ async function cmdStop() {
377
343
  console.log('已停止');
378
344
  }
379
345
 
380
- function cmdUi(args) {
346
+ function cmdUI(args) {
381
347
  const uiName = args[1] || 'zash';
382
348
  const url = UI_URLS[uiName];
383
349
 
@@ -396,11 +362,10 @@ function cmdUi(args) {
396
362
  }
397
363
  }
398
364
 
399
-
400
365
  function cmdLog(args) {
401
366
  const logPath = processMgr.getLogPath();
402
367
 
403
- if (hasFlag(args, '-o', '--open')) {
368
+ if (utils.hasFlag(args, '-o', '--open')) {
404
369
  openLogFile(logPath);
405
370
  return;
406
371
  }
@@ -409,9 +374,9 @@ function cmdLog(args) {
409
374
  }
410
375
 
411
376
  function cmdLogs(args) {
412
- const targetName = getNonFlagArg(args, 1);
413
- const lines = parseIntArg(args, '-n', '--lines', 100);
414
- const openInViewer = hasFlag(args, '-o', '--open');
377
+ const targetName = utils.getNonFlagArg(args, 1);
378
+ const lines = utils.parseIntArg(args, '-n', '--lines', 100);
379
+ const openInViewer = utils.hasFlag(args, '-o', '--open');
415
380
 
416
381
  if (targetName) {
417
382
  let logPath;
@@ -419,7 +384,20 @@ function cmdLogs(args) {
419
384
  if (targetName === 'current' || targetName === '0') {
420
385
  logPath = processMgr.getLogPath();
421
386
  } else {
422
- logPath = processMgr.getLogPathByName(targetName);
387
+ // 纯数字 1+ 表示归档日志的位置(最新=1)
388
+ const parsedIdx = parseInt(targetName);
389
+ if (!isNaN(parsedIdx) && parsedIdx > 0 && String(parsedIdx) === targetName) {
390
+ const archiveLogs = processMgr.listLogs();
391
+ const archive = archiveLogs.archives[parsedIdx - 1];
392
+ if (!archive) {
393
+ console.error('错误: 未找到日志 "' + targetName + '"');
394
+ console.log('使用 "mihomo logs" 查看可用日志列表');
395
+ process.exit(1);
396
+ }
397
+ logPath = archive.path;
398
+ } else {
399
+ logPath = processMgr.getLogPathByName(targetName);
400
+ }
423
401
  }
424
402
 
425
403
  if (!logPath) {
@@ -454,25 +432,32 @@ function cmdLogs(args) {
454
432
  console.log('日志列表:');
455
433
  console.log('');
456
434
 
457
- all.forEach((log, idx) => {
458
- const num = log.isCurrent ? ' 0' : (idx < 10 ? ' ' + idx : '' + idx);
459
- const time = subscription.formatDate(log.mtime);
460
- const size = subscription.formatBytes(log.size);
435
+ let archiveCounter = 0;
436
+ all.forEach(log => {
437
+ let num;
438
+ if (log.isCurrent) {
439
+ num = ' 0';
440
+ } else {
441
+ archiveCounter++;
442
+ num = archiveCounter < 10 ? ' ' + archiveCounter : '' + archiveCounter;
443
+ }
444
+ const time = utils.formatDate(log.mtime);
445
+ const size = utils.formatBytes(log.size);
461
446
  const name = log.isCurrent ? 'mihomo.log (当前运行中)' : log.name;
462
447
 
463
448
  console.log(' ' + num + '. ' + name);
464
449
  console.log(' 时间: ' + time + ' 大小: ' + size);
465
450
  if (!log.isCurrent) {
466
- console.log(' 查看: mihomo logs ' + idx + ' 或 mihomo logs -o ' + idx);
451
+ console.log(' 查看: mihomo logs ' + archiveCounter + ' 或 mihomo logs ' + archiveCounter + ' -o');
467
452
  }
468
453
  console.log('');
469
454
  });
470
455
 
471
456
  console.log('用法:');
472
457
  console.log(' mihomo logs 0 # 查看当前日志 (最后 100 行)');
473
- console.log(' mihomo logs 1 # 查看第 1 个归档日志');
458
+ console.log(' mihomo logs 1 # 查看第 1 个归档日志(最新)');
474
459
  console.log(' mihomo logs 1 -n 200 # 查看 200 行');
475
- console.log(' mihomo logs 1 -o # 用系统默认程序打开');
460
+ console.log(' mihomo logs 1 -o # 用系统默认程序打开');
476
461
  console.log('');
477
462
  }
478
463
 
@@ -542,11 +527,8 @@ async function cmdKernel(args) {
542
527
 
543
528
  console.log('\n可用镜像:');
544
529
  config.AVAILABLE_MIRRORS.forEach(m => {
545
- const isCurrent = effectiveMirror && (
546
- effectiveMirror.includes('//' + m + '/') ||
547
- effectiveMirror.includes('//' + m + ':') ||
548
- effectiveMirror.endsWith('//' + m)
549
- );
530
+ const isCurrent =
531
+ effectiveMirror && (effectiveMirror.includes('//' + m + '/') || effectiveMirror.includes('//' + m + ':') || effectiveMirror.endsWith('//' + m));
550
532
  console.log(' ' + m + (isCurrent ? ' (当前)' : ''));
551
533
  });
552
534
 
@@ -568,9 +550,9 @@ async function cmdKernel(args) {
568
550
  }
569
551
 
570
552
  console.log('\n正在下载...');
571
- const result = await kernel.downloadKernel((msg) => {
553
+ const result = await kernel.downloadKernel(msg => {
572
554
  console.log(msg);
573
- }, mirrorInfo.mirror); // 传递镜像参数(undefined = 用配置,null = 禁用)
555
+ }, mirrorInfo.mirror); // 传递镜像参数(undefined = 用配置,null = 禁用)
574
556
  console.log('已更新到 ' + result.version);
575
557
  } catch (e) {
576
558
  console.error('更新失败: ' + e.message);
@@ -579,7 +561,7 @@ async function cmdKernel(args) {
579
561
  }
580
562
 
581
563
  async function printSubscriptionList() {
582
- const updateResult = await subscription.autoUpdateStaleSubscriptions();
564
+ const updateResult = await subscription.autoUpdateStaleSubscription();
583
565
  if (updateResult.total > 0) {
584
566
  console.log('');
585
567
  }
@@ -594,7 +576,7 @@ async function printSubscriptionList() {
594
576
  }
595
577
  console.log('订阅列表:');
596
578
  subs.forEach((s, i) => {
597
- const time = subscription.formatDate(s.updated_at);
579
+ const time = utils.formatDate(s.updated_at);
598
580
  const defaultMark = i === 0 ? ' [默认]' : '';
599
581
  const interval = s.update_interval || subscription.DEFAULT_UPDATE_INTERVAL_HOURS;
600
582
  console.log(' ' + (i + 1) + '. ' + s.name + defaultMark);
@@ -605,8 +587,8 @@ async function printSubscriptionList() {
605
587
  }
606
588
  if (s.download !== undefined || s.total !== undefined) {
607
589
  const used = (s.upload || 0) + (s.download || 0);
608
- const usedStr = subscription.formatBytes(used);
609
- const totalStr = subscription.formatBytes(s.total);
590
+ const usedStr = utils.formatBytes(used);
591
+ const totalStr = utils.formatBytes(s.total);
610
592
  let percentStr = '';
611
593
  if (s.total && s.total > 0) {
612
594
  const percent = Math.min((used / s.total) * 100, 100);
@@ -615,7 +597,7 @@ async function printSubscriptionList() {
615
597
  console.log(' 流量: ' + usedStr + ' / ' + totalStr + percentStr);
616
598
  }
617
599
  if (s.expire !== undefined) {
618
- console.log(' 到期: ' + subscription.formatTimestamp(s.expire));
600
+ console.log(' 到期: ' + utils.formatTimestamp(s.expire));
619
601
  }
620
602
  if (s.web_page_url) {
621
603
  console.log(' 页面: ' + s.web_page_url);
@@ -625,6 +607,7 @@ async function printSubscriptionList() {
625
607
  console.log('切换默认: mihomo sub use <name>');
626
608
  console.log('更新订阅: mihomo sub update [name]');
627
609
  console.log('打开页面: mihomo sub web [name]');
610
+ console.log('新增订阅: mihomo sub add <url> [name]');
628
611
  console.log('');
629
612
  }
630
613
 
@@ -649,10 +632,7 @@ async function cmdSubscription(args) {
649
632
  try {
650
633
  config.addSubscription(url, name);
651
634
  const info = await subscription.downloadSubscription(url, name);
652
- const parts = [];
653
- if (info.proxyGroups && info.proxyGroups > 0) parts.push(info.proxyGroups + ' 组');
654
- parts.push(info.proxies + ' 节点');
655
- console.log('已添加 (' + parts.join(', ') + ')');
635
+ console.log('已添加 (' + subscription.formatProxySummary(info) + ')');
656
636
  } catch (e) {
657
637
  console.error('添加失败: ' + e.message);
658
638
  process.exit(1);
@@ -678,10 +658,7 @@ async function cmdSubscription(args) {
678
658
  results.forEach(r => {
679
659
  if (r.success) {
680
660
  ok++;
681
- const parts = [];
682
- if (r.proxyGroups && r.proxyGroups > 0) parts.push(r.proxyGroups + ' 组');
683
- parts.push(r.proxies + ' 节点');
684
- console.log('✓ ' + r.name + ': 已更新 (' + parts.join(', ') + ')');
661
+ console.log('✓ ' + r.name + ': 已更新 (' + subscription.formatProxySummary(r) + ')');
685
662
  } else {
686
663
  console.log('✗ ' + r.name + ': 失败 (' + r.error.split('\n')[0] + ')');
687
664
  }
@@ -693,15 +670,12 @@ async function cmdSubscription(args) {
693
670
  }
694
671
 
695
672
  const matches = findSubscriptionFuzzy(subs, name);
696
- const target = pickSingleSubscription(matches, name, '更新');
673
+ const target = pickSingleSubscription(matches, name);
697
674
 
698
675
  console.log('更新订阅: ' + target.name);
699
676
  try {
700
677
  const info = await subscription.downloadSubscription(target.url, target.name);
701
- const parts = [];
702
- if (info.proxyGroups && info.proxyGroups > 0) parts.push(info.proxyGroups + ' 组');
703
- parts.push(info.proxies + ' 节点');
704
- console.log('已更新 (' + parts.join(', ') + ')');
678
+ console.log('已更新 (' + subscription.formatProxySummary(info) + ')');
705
679
  } catch (e) {
706
680
  console.error('更新失败: ' + e.message);
707
681
  process.exit(1);
@@ -725,7 +699,7 @@ async function cmdSubscription(args) {
725
699
  }
726
700
 
727
701
  const matches = findSubscriptionFuzzy(subs, name);
728
- const target = pickSingleSubscription(matches, name, '切换');
702
+ const target = pickSingleSubscription(matches, name);
729
703
 
730
704
  // 检查是否已是当前默认订阅
731
705
  const currentDefault = getActiveSubscription();
@@ -775,7 +749,7 @@ async function cmdSubscription(args) {
775
749
  let target;
776
750
  if (name) {
777
751
  const matches = findSubscriptionFuzzy(subs, name);
778
- target = pickSingleSubscription(matches, name, '打开');
752
+ target = pickSingleSubscription(matches, name);
779
753
  } else {
780
754
  target = subs[0];
781
755
  }
@@ -833,11 +807,11 @@ async function cmdReset(args) {
833
807
  const readline = require('readline');
834
808
  const rl = readline.createInterface({
835
809
  input: process.stdin,
836
- output: process.stdout
810
+ output: process.stdout,
837
811
  });
838
812
 
839
813
  const answer = await new Promise(resolve => {
840
- rl.question('确认? (y/N) ', (a) => {
814
+ rl.question('确认? (y/N) ', a => {
841
815
  rl.close();
842
816
  resolve(a);
843
817
  });
@@ -854,7 +828,7 @@ async function cmdReset(args) {
854
828
  }
855
829
 
856
830
  function printOverwriteList() {
857
- const info = overwrite.listOverwriteFiles();
831
+ const info = overwrite.listOverwriteFile();
858
832
  console.log('状态: ' + (info.enabled ? '已启用' : '已禁用'));
859
833
  console.log('目录: ' + info.dir);
860
834
  console.log('');
@@ -943,14 +917,14 @@ async function cmdOverwrite(args) {
943
917
 
944
918
  // 目录目标映射(精确匹配)
945
919
  const DIRECTORY_TARGETS = {
946
- 'root': { path: null, label: '根目录' },
947
- 'subs': { path: config.DIRS.subscriptions, label: '订阅目录' },
948
- 'logs': { path: config.DIRS.logs, label: '日志目录' },
949
- 'data': { path: config.DIRS.data, label: 'mihomo 数据目录' },
950
- 'runtime': { path: config.DIRS.runtime, label: '运行时目录' },
951
- 'overwrites': { path: config.DIRS.overwrites, label: '覆写目录' },
952
- 'settings': { path: config.PATHS.settingsFile, label: '设置文件' },
953
- 'kernel': { path: config.DIRS.core, label: '内核目录' },
920
+ root: { path: null, label: '根目录' },
921
+ subs: { path: config.DIRS.subscriptions, label: '订阅目录' },
922
+ logs: { path: config.DIRS.logs, label: '日志目录' },
923
+ data: { path: config.DIRS.data, label: 'mihomo 数据目录' },
924
+ runtime: { path: config.DIRS.runtime, label: '运行时目录' },
925
+ overwrites: { path: config.DIRS.overwrites, label: '覆写目录' },
926
+ settings: { path: config.PATHS.settingsFile, label: '设置文件' },
927
+ kernel: { path: config.DIRS.core, label: '内核目录' },
954
928
  };
955
929
 
956
930
  function cmdDirectory(args) {
@@ -1055,7 +1029,7 @@ async function main() {
1055
1029
  cmdLogs(args);
1056
1030
  break;
1057
1031
  case 'ui':
1058
- cmdUi(args);
1032
+ cmdUI(args);
1059
1033
  break;
1060
1034
  case 'kernel':
1061
1035
  await cmdKernel(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mihomo-cli",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "A terminal-based mihomo (Clash.Meta) client for macOS",
5
5
  "main": "index.js",
6
6
  "bin": {