evolclaw 3.0.0 → 3.1.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.
Files changed (99) hide show
  1. package/README.md +1 -1
  2. package/bin/ec.js +29 -0
  3. package/dist/agents/baseagent-normalize.js +19 -0
  4. package/dist/agents/claude-runner.js +7 -9
  5. package/dist/agents/codex-runner.js +2 -0
  6. package/dist/agents/gemini-runner.js +9 -9
  7. package/dist/agents/kit-renderer.js +281 -0
  8. package/dist/aun/aid/identity.js +28 -0
  9. package/dist/aun/aid/index.js +1 -1
  10. package/dist/aun/aid/lifecycle-log.js +33 -0
  11. package/dist/aun/msg/group.js +3 -1
  12. package/dist/aun/msg/p2p.js +4 -1
  13. package/dist/channels/aun.js +353 -125
  14. package/dist/channels/dingtalk.js +2 -1
  15. package/dist/channels/feishu.js +118 -5
  16. package/dist/channels/qqbot.js +2 -1
  17. package/dist/channels/wechat.js +3 -1
  18. package/dist/channels/wecom.js +2 -1
  19. package/dist/cli/bench.js +1219 -0
  20. package/dist/cli/index.js +279 -19
  21. package/dist/cli/link-rules.js +245 -0
  22. package/dist/cli/net-check.js +640 -0
  23. package/dist/cli/watch-msg.js +589 -0
  24. package/dist/config-store.js +37 -5
  25. package/dist/core/channel-loader.js +23 -10
  26. package/dist/core/command-handler.js +46 -22
  27. package/dist/core/evolagent.js +5 -10
  28. package/dist/core/message/im-renderer.js +50 -44
  29. package/dist/core/message/items-formatter.js +11 -4
  30. package/dist/core/message/message-bridge.js +7 -2
  31. package/dist/core/message/message-log.js +2 -0
  32. package/dist/core/message/message-processor.js +150 -99
  33. package/dist/core/message/message-queue.js +10 -3
  34. package/dist/core/permission.js +95 -3
  35. package/dist/core/session/session-manager.js +98 -64
  36. package/dist/core/trigger/scheduler.js +1 -1
  37. package/dist/data/error-dict.json +118 -0
  38. package/dist/eck/baseagent-caps.js +18 -0
  39. package/dist/eck/detect.js +47 -0
  40. package/dist/eck/init.js +77 -0
  41. package/dist/eck/rules-loader.js +28 -0
  42. package/dist/index.js +137 -16
  43. package/dist/net-check.js +640 -0
  44. package/dist/paths.js +31 -40
  45. package/dist/utils/aid-lifecycle-log.js +33 -0
  46. package/dist/utils/atomic-write.js +10 -0
  47. package/dist/utils/cross-platform.js +17 -8
  48. package/dist/utils/error-utils.js +10 -2
  49. package/dist/utils/instance-registry.js +6 -5
  50. package/dist/utils/log-writer.js +2 -1
  51. package/dist/utils/logger.js +10 -0
  52. package/dist/utils/npm-ops.js +35 -3
  53. package/dist/utils/process-introspect.js +16 -38
  54. package/dist/watch-msg.js +26 -11
  55. package/evolclaw-install-aun.md +14 -2
  56. package/kits/docs/GUIDE.md +20 -0
  57. package/kits/docs/INDEX.md +52 -0
  58. package/kits/docs/aun/CHEATSHEET.md +17 -0
  59. package/kits/docs/aun/SYNC_PROTOCOL.md +15 -0
  60. package/kits/docs/channels/feishu.md +27 -0
  61. package/kits/docs/eck_templates/GUIDE.template.md +22 -0
  62. package/kits/docs/eck_templates/INDEX.template.md +28 -0
  63. package/kits/docs/eck_templates/path-registry.template.md +33 -0
  64. package/kits/docs/eck_templates/runtime.template.md +19 -0
  65. package/kits/docs/evolclaw/MSG_GROUP.md +30 -0
  66. package/kits/docs/evolclaw/MSG_PRIVATE.md +25 -0
  67. package/kits/docs/identity/AID_PROFILE_SPEC.md +27 -0
  68. package/kits/docs/identity/PATH_OPS.md +16 -0
  69. package/kits/docs/identity/ROLE_DETAIL.md +20 -0
  70. package/kits/docs/path-registry.md +43 -0
  71. package/kits/eck_manifest.json +95 -0
  72. package/kits/rules/01-overview.md +120 -0
  73. package/kits/rules/02-navigation.md +75 -0
  74. package/kits/rules/03-identity.md +34 -0
  75. package/kits/rules/04-relation.md +49 -0
  76. package/kits/rules/05-venue.md +45 -0
  77. package/kits/rules/06-channel.md +43 -0
  78. package/kits/templates/system-fragments/baseagent.md +2 -0
  79. package/kits/templates/system-fragments/channel.md +10 -0
  80. package/kits/templates/system-fragments/identity.md +12 -0
  81. package/kits/templates/system-fragments/relation.md +9 -0
  82. package/kits/templates/system-fragments/runtime.md +19 -0
  83. package/kits/templates/system-fragments/venue.md +5 -0
  84. package/package.json +7 -5
  85. package/dist/agents/templates.js +0 -122
  86. package/dist/data/prompts.md +0 -137
  87. package/kits/aun/meta.md +0 -25
  88. package/kits/aun/role.md +0 -25
  89. package/kits/templates/group.md +0 -20
  90. package/kits/templates/private.md +0 -9
  91. package/kits/templates/system-fragments/personal-context.md +0 -3
  92. package/kits/templates/system-fragments/self-intro.md +0 -5
  93. package/kits/templates/system-fragments/speaker-intro.md +0 -5
  94. package/kits/templates/system-fragments/venue-intro.md +0 -5
  95. /package/kits/{channels → docs/channels}/aun.md +0 -0
  96. /package/kits/{evolclaw/commands.md → docs/evolclaw/AGENT_CMD.md} +0 -0
  97. /package/kits/{evolclaw → docs/evolclaw}/self-summary.md +0 -0
  98. /package/kits/{evolclaw → docs/evolclaw}/tools.md +0 -0
  99. /package/kits/{evolclaw → docs/identity}/identity-tools.md +0 -0
package/dist/cli/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
4
  import os from 'os';
5
- import { spawn, execFile } from 'child_process';
5
+ import { spawn, execFileSync, execFile } from 'child_process';
6
6
  import { promisify } from 'util';
7
7
  import { resolveRoot, resolvePaths, ensureDataDirs, getPackageRoot } from '../paths.js';
8
8
  import { loadDefaults, loadAllAgents, mergeForAgent } from '../config-store.js';
@@ -13,7 +13,8 @@ import { ipcQuery } from '../ipc.js';
13
13
  import { cmdInitWechat, cmdInitFeishu, cmdInitDingtalk, cmdInitQQBot, cmdInitWecom } from './init-channel.js';
14
14
  import * as platform from '../utils/cross-platform.js';
15
15
  import { EventBus } from '../core/event-bus.js';
16
- import { tryUpgrade } from '../utils/npm-ops.js';
16
+ import { tryUpgrade, tryUpgradeAunSdk } from '../utils/npm-ops.js';
17
+ import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
17
18
  import { scanInstances, cleanupInstances, writeRestartMonitor, removeRestartMonitor, isRestartMonitorWinner, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
18
19
  // Suppress Node.js ExperimentalWarning (e.g. SQLite) from cluttering CLI output
19
20
  process.removeAllListeners('warning');
@@ -231,6 +232,10 @@ function reportOrphans(orphans) {
231
232
  console.log(' 使用 evolclaw restart --clear 一并清掉,或手动 kill。');
232
233
  }
233
234
  async function cmdStart() {
235
+ const cmdStartedAt = Date.now();
236
+ const pkgRoot = getPackageRoot();
237
+ const isNpmInstall = pkgRoot.includes('node_modules');
238
+ console.log(`⏱ ${new Date().toLocaleString()} [${isNpmInstall ? 'pkg' : 'dev'}] ${pkgRoot}`);
234
239
  const p = resolvePaths();
235
240
  ensureDataDirs();
236
241
  // 旧配置自动迁移(evolclaw.json → 新结构)
@@ -315,7 +320,14 @@ async function cmdStart() {
315
320
  const checkReady = () => {
316
321
  // ready signal 出现(优先检查,避免 Windows 上误判进程状态)
317
322
  if (fs.existsSync(p.readySignal)) {
318
- console.log(`✓ EvolClaw started successfully (PID: ${childPid})`);
323
+ const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
324
+ let aunVer = 'unknown';
325
+ try {
326
+ const aunPkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'node_modules', '@agentunion', 'fastaun', 'package.json'), 'utf-8'));
327
+ aunVer = aunPkg.version;
328
+ }
329
+ catch { /* ignore */ }
330
+ console.log(`✓ EvolClaw v${pkg.version} started successfully (PID: ${childPid}) fastaun v${aunVer}`);
319
331
  console.log(` EVOLCLAW_HOME: ${resolveRoot()}`);
320
332
  console.log(` Logs: ${p.logs}/`);
321
333
  // 从主日志提取渠道连接摘要
@@ -358,6 +370,7 @@ async function cmdStart() {
358
370
  if (resolveRoot() === getPackageRoot()) {
359
371
  countLines(getPackageRoot(), p.logs);
360
372
  }
373
+ console.log(`⏱ done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
361
374
  return;
362
375
  }
363
376
  // 超时
@@ -369,6 +382,7 @@ async function cmdStart() {
369
382
  const content = fs.readFileSync(stdoutLog, 'utf-8').trim().split('\n');
370
383
  console.log(content.slice(-10).map(l => ` ${l}`).join('\n'));
371
384
  }
385
+ console.log(`⏱ failed after ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
372
386
  process.exit(1);
373
387
  return;
374
388
  }
@@ -383,6 +397,7 @@ async function cmdStart() {
383
397
  const content = fs.readFileSync(stdoutLog, 'utf-8').trim().split('\n');
384
398
  console.log(content.slice(-10).map(l => ` ${l}`).join('\n'));
385
399
  }
400
+ console.log(`⏱ failed after ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
386
401
  process.exit(1);
387
402
  return;
388
403
  }
@@ -428,6 +443,10 @@ async function cmdStop() {
428
443
  }
429
444
  }
430
445
  async function cmdRestart(opts = {}) {
446
+ const cmdStartedAt = Date.now();
447
+ const pkgRoot = getPackageRoot();
448
+ const isNpmInstall = pkgRoot.includes('node_modules');
449
+ console.log(`⏱ ${new Date().toLocaleString()} [${isNpmInstall ? 'pkg' : 'dev'}] ${pkgRoot}`);
431
450
  console.log('🔄 Restarting EvolClaw...');
432
451
  // 版本检查与自动升级
433
452
  console.log('📦 Checking for updates...');
@@ -448,6 +467,18 @@ async function cmdRestart(opts = {}) {
448
467
  console.log(`⚠ Upgrade failed (${upgrade.from} → ${upgrade.to}), continuing with current version`);
449
468
  break;
450
469
  }
470
+ // AUN SDK 版本检查与升级
471
+ const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
472
+ switch (aunUpgrade.status) {
473
+ case 'upgraded':
474
+ console.log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
475
+ break;
476
+ case 'no-update':
477
+ break; // silent
478
+ case 'failed':
479
+ console.log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to})`);
480
+ break;
481
+ }
451
482
  // 停止所有活 main 进程(可能不止一个)
452
483
  const status = scanInstances();
453
484
  const aliveMains = status.mains.filter(m => m.alive);
@@ -457,20 +488,164 @@ async function cmdRestart(opts = {}) {
457
488
  }
458
489
  await Promise.all(aliveMains.map(m => stopPid(m.record.pid)));
459
490
  await sleep(500);
460
- cleanupInstances();
461
491
  }
462
- // 跨 HOME 孤儿处理:只在 --clear 时主动 kill;
463
- // 否则交给后续 cmdStart() 统一警告,避免重复输出。
464
- if (opts.clear) {
492
+ cleanupInstances();
493
+ // 孤儿处理:同 HOME 的孤儿无条件 kill(restart 必须替换旧实例);
494
+ // 跨 HOME 的孤儿只在 --clear 时 kill,否则仅警告。
495
+ {
465
496
  const orphans = findOrphanProcesses();
466
- if (orphans.length > 0) {
467
- const killed = killOrphans(orphans);
468
- console.log(`☠ SIGKILL ${killed.length} 个孤儿进程: ${killed.join(', ')}`);
497
+ const currentHome = resolveRoot();
498
+ const sameHome = orphans.filter(o => o.evolclawHome === currentHome);
499
+ const otherHome = orphans.filter(o => o.evolclawHome !== currentHome);
500
+ if (sameHome.length > 0) {
501
+ const killed = killOrphans(sameHome);
502
+ console.log(`☠ 已 SIGKILL ${killed.length} 个同 HOME 孤儿进程: ${killed.join(', ')}`);
503
+ await sleep(500);
504
+ }
505
+ if (opts.clear && otherHome.length > 0) {
506
+ const killed = killOrphans(otherHome);
507
+ console.log(`☠ 已 SIGKILL ${killed.length} 个跨 HOME 孤儿进程: ${killed.join(', ')}`);
469
508
  await sleep(500);
470
509
  }
471
510
  }
511
+ console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
472
512
  setTimeout(() => cmdStart(), 1000);
473
513
  }
514
+ async function cmdDev(args) {
515
+ const pkgRoot = getPackageRoot();
516
+ const isNpmInstall = pkgRoot.includes('node_modules');
517
+ const p = resolvePaths();
518
+ const devMarker = path.join(p.dataDir, 'dev-repo.path');
519
+ const sub = args[0];
520
+ if (!sub) {
521
+ if (!isNpmInstall) {
522
+ console.log(`当前: [dev] ${pkgRoot}`);
523
+ console.log('');
524
+ console.log('断开开发仓链接:');
525
+ console.log(' evolclaw dev off');
526
+ }
527
+ else {
528
+ console.log(`当前: [pkg] ${pkgRoot}`);
529
+ console.log('');
530
+ let devPath = null;
531
+ try {
532
+ devPath = fs.readFileSync(devMarker, 'utf-8').trim();
533
+ }
534
+ catch { }
535
+ if (devPath && fs.existsSync(devPath)) {
536
+ console.log('链接到开发仓:');
537
+ console.log(` evolclaw dev on`);
538
+ console.log(` (已记录路径: ${devPath})`);
539
+ }
540
+ else {
541
+ console.log('链接到开发仓:');
542
+ console.log(' evolclaw dev <开发仓路径>');
543
+ }
544
+ }
545
+ return;
546
+ }
547
+ if (sub === 'off') {
548
+ if (isNpmInstall) {
549
+ console.log('当前已是 [pkg] 模式,无需断开');
550
+ return;
551
+ }
552
+ console.log('🔗 断开开发仓链接...');
553
+ let npmPrefix;
554
+ if (process.platform === 'win32' && process.env.APPDATA) {
555
+ npmPrefix = path.join(process.env.APPDATA, 'npm');
556
+ }
557
+ else {
558
+ npmPrefix = execFileSync('npm', ['prefix', '-g'], { encoding: 'utf-8', shell: true }).trim();
559
+ }
560
+ const linkPath = path.join(npmPrefix, 'node_modules', 'evolclaw');
561
+ const binPath = path.join(npmPrefix, 'evolclaw');
562
+ try {
563
+ fs.rmSync(linkPath, { recursive: true });
564
+ }
565
+ catch { }
566
+ try {
567
+ fs.unlinkSync(binPath);
568
+ }
569
+ catch { }
570
+ try {
571
+ fs.unlinkSync(binPath + '.cmd');
572
+ }
573
+ catch { }
574
+ try {
575
+ fs.unlinkSync(binPath + '.ps1');
576
+ }
577
+ catch { }
578
+ console.log('✓ 已断开');
579
+ console.log(` 已删除: ${linkPath}`);
580
+ console.log(` 如需恢复: evolclaw dev on(需从已安装的 evolclaw 执行)`);
581
+ return;
582
+ }
583
+ if (sub === 'on') {
584
+ if (!isNpmInstall) {
585
+ console.log(`当前已是 [dev] 模式: ${pkgRoot}`);
586
+ return;
587
+ }
588
+ let devPath = null;
589
+ try {
590
+ devPath = fs.readFileSync(devMarker, 'utf-8').trim();
591
+ }
592
+ catch { }
593
+ if (!devPath || !fs.existsSync(devPath)) {
594
+ console.log('未记录开发仓路径');
595
+ console.log('');
596
+ console.log('用法: evolclaw dev <开发仓路径>');
597
+ process.exit(1);
598
+ }
599
+ console.log(`🔗 链接开发仓: ${devPath}`);
600
+ try {
601
+ execFileSync('npm', ['link'], { stdio: 'inherit', cwd: devPath, shell: true });
602
+ console.log(`✓ 已链接 [dev] ${devPath}`);
603
+ }
604
+ catch (e) {
605
+ console.error('❌ npm link 失败:', e.message);
606
+ process.exit(1);
607
+ }
608
+ return;
609
+ }
610
+ // evolclaw dev <path> — 记录路径 + 建立链接
611
+ const devPath = path.resolve(sub);
612
+ const pkgJson = path.join(devPath, 'package.json');
613
+ if (!fs.existsSync(pkgJson)) {
614
+ console.error(`❌ 路径不存在或无 package.json: ${devPath}`);
615
+ process.exit(1);
616
+ }
617
+ let pkg;
618
+ try {
619
+ pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'));
620
+ }
621
+ catch {
622
+ console.error(`❌ 无法解析 package.json: ${pkgJson}`);
623
+ process.exit(1);
624
+ }
625
+ if (pkg.name !== 'evolclaw') {
626
+ console.error(`❌ package.json name 不是 evolclaw(是 "${pkg.name}")`);
627
+ process.exit(1);
628
+ }
629
+ // 已经链接到同一路径,只记录不重复 link
630
+ if (!isNpmInstall && path.resolve(pkgRoot) === devPath) {
631
+ fs.mkdirSync(p.dataDir, { recursive: true });
632
+ fs.writeFileSync(devMarker, devPath, 'utf-8');
633
+ console.log(`✓ 当前已链接到该路径,路径已记录`);
634
+ return;
635
+ }
636
+ console.log(`🔗 链接开发仓: ${devPath}`);
637
+ try {
638
+ execFileSync('npm', ['link'], { stdio: 'inherit', cwd: devPath, shell: true });
639
+ }
640
+ catch (e) {
641
+ console.error('❌ npm link 失败:', e.message);
642
+ process.exit(1);
643
+ }
644
+ fs.mkdirSync(p.dataDir, { recursive: true });
645
+ fs.writeFileSync(devMarker, devPath, 'utf-8');
646
+ console.log(`✓ 已链接 [dev] ${devPath}`);
647
+ console.log(` 路径已记录,下次可用 evolclaw dev on 快速切换`);
648
+ }
474
649
  function formatTimeAgo(ms) {
475
650
  const sec = Math.floor(ms / 1000);
476
651
  if (sec < 60)
@@ -1250,7 +1425,7 @@ async function cmdWatchMenu() {
1250
1425
  await cmdWatchAid();
1251
1426
  }
1252
1427
  else if (chosen === 'msg') {
1253
- const { cmdWatchMsg } = await import('../watch-msg.js');
1428
+ const { cmdWatchMsg } = await import('./watch-msg.js');
1254
1429
  await cmdWatchMsg();
1255
1430
  }
1256
1431
  resolve();
@@ -1686,7 +1861,31 @@ async function cmdWatchAid() {
1686
1861
  const subLine1 = ` ${nameColor}${namePart}${nameReset}${msgPreview ? ' ' + msgPreview : ''}`;
1687
1862
  const dirLabel = projectPath || '—';
1688
1863
  const subLine2 = `${DIM} ${dirLabel}${RST}`;
1689
- return [mainLine, subLine1, subLine2];
1864
+ const result = [mainLine, subLine1, subLine2];
1865
+ if (aid.status === 'failed' || aid.status === 'kicked' || aid.status === 'kicked_no_retry') {
1866
+ const parts = [];
1867
+ if (aid.lastAttemptAt) {
1868
+ const d = new Date(aid.lastAttemptAt);
1869
+ const ts = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
1870
+ parts.push(`last_attempt=${ts}`);
1871
+ }
1872
+ if (aid.kickDetail?.code) {
1873
+ parts.push(`code=${aid.kickDetail.code}`);
1874
+ }
1875
+ if (aid.kickDetail?.reason) {
1876
+ parts.push(`reason=${aid.kickDetail.reason}`);
1877
+ }
1878
+ if (aid.lastError) {
1879
+ parts.push(`error=${aid.lastError}`);
1880
+ }
1881
+ if (aid.gatewayUrl) {
1882
+ parts.push(`gateway=${aid.gatewayUrl}`);
1883
+ }
1884
+ if (parts.length > 0) {
1885
+ result.push(`${RED} ⚠ ${parts.join(' ')}${RST}`);
1886
+ }
1887
+ }
1888
+ return result;
1690
1889
  }
1691
1890
  let lastLineCount = 0;
1692
1891
  async function render() {
@@ -1905,6 +2104,19 @@ async function cmdRestartMonitor() {
1905
2104
  await notifyChannel(p, pendingInfo, `⚠️ 升级失败,使用当前版本继续`, log);
1906
2105
  break;
1907
2106
  }
2107
+ // AUN SDK 版本检查与升级
2108
+ const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
2109
+ switch (aunUpgrade.status) {
2110
+ case 'upgraded':
2111
+ log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
2112
+ await notifyChannel(p, pendingInfo, `📦 AUN SDK 已升级 ${aunUpgrade.from} → ${aunUpgrade.to}`, log);
2113
+ break;
2114
+ case 'no-update':
2115
+ break;
2116
+ case 'failed':
2117
+ log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to}): ${aunUpgrade.error}`);
2118
+ break;
2119
+ }
1908
2120
  // 启动并检测 ready signal
1909
2121
  let started = await spawnAndWaitReady(p, log, READY_TIMEOUT);
1910
2122
  if (started) {
@@ -2486,7 +2698,7 @@ async function cmdCtl(args) {
2486
2698
  async function cmdAgent(args) {
2487
2699
  const sub = args[0];
2488
2700
  const formatJson = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
2489
- if (sub === 'help') {
2701
+ if (sub === 'help' || sub === '--help' || sub === '-h' || args.includes('--help') || args.includes('-h')) {
2490
2702
  console.log(`用法: evolclaw agent <command>
2491
2703
 
2492
2704
  Commands:
@@ -2949,7 +3161,7 @@ async function cmdAid(args) {
2949
3161
  const sub = args[0] || 'list';
2950
3162
  const formatJson = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
2951
3163
  const aunPath = resolveAunPath(args);
2952
- if (sub === 'help') {
3164
+ if (sub === 'help' || sub === '--help' || sub === '-h' || args.includes('--help') || args.includes('-h')) {
2953
3165
  console.log(`用法: evolclaw aid <command>
2954
3166
 
2955
3167
  Commands:
@@ -3495,7 +3707,8 @@ Options:
3495
3707
  }
3496
3708
  body = { mode: 'text', text };
3497
3709
  }
3498
- const result = await msgSend({ from, to, body, ...commonOpts });
3710
+ const encrypt = args.includes('--encrypt');
3711
+ const result = await msgSend({ from, to, body, encrypt, ...commonOpts });
3499
3712
  if (!result.ok) {
3500
3713
  if (formatJson) {
3501
3714
  console.log(JSON.stringify(result));
@@ -3789,7 +4002,8 @@ Options:
3789
4002
  body = { mode: 'text', text };
3790
4003
  }
3791
4004
  const mentions = collectMentions();
3792
- const result = await groupSend({ from, groupId, body, mentions: mentions.length ? mentions : undefined, ...commonOpts });
4005
+ const encryptGroup = args.includes('--encrypt');
4006
+ const result = await groupSend({ from, groupId, body, mentions: mentions.length ? mentions : undefined, encrypt: encryptGroup, ...commonOpts });
3793
4007
  outputResult(result, () => {
3794
4008
  const r = result;
3795
4009
  console.log(`✓ 已发送 message_id=${r.message?.message_id ?? '-'} seq=${r.message?.seq ?? '-'}`);
@@ -4125,7 +4339,26 @@ export async function main(args) {
4125
4339
  await cmdWatchAid();
4126
4340
  }
4127
4341
  else if (args[1] === 'msg') {
4128
- const { cmdWatchMsg } = await import('../watch-msg.js');
4342
+ if (args[2] === '--help' || args[2] === '-h' || args[2] === 'help') {
4343
+ console.log(`用法: evolclaw watch msg
4344
+
4345
+ 三面板交互式消息监控 TUI。
4346
+
4347
+ 面板:
4348
+ 左 (Scope) 本地 AID 列表,显示收发统计和对端数量
4349
+ 中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
4350
+ 右 (Messages) 消息流,带滚动条
4351
+
4352
+ 操作:
4353
+ ↑↓ 当前面板内导航
4354
+ ←→ / Tab 切换面板
4355
+ Enter 选中 AID / 选中对端
4356
+ Backspace 返回上一级
4357
+ Page Up/Down 消息滚动
4358
+ ESC 退出`);
4359
+ break;
4360
+ }
4361
+ const { cmdWatchMsg } = await import('./watch-msg.js');
4129
4362
  await cmdWatchMsg();
4130
4363
  }
4131
4364
  else if (args[1] === 'log') {
@@ -4141,12 +4374,20 @@ export async function main(args) {
4141
4374
  case 'restart-monitor':
4142
4375
  await cmdRestartMonitor();
4143
4376
  break;
4377
+ case 'dev':
4378
+ await cmdDev(args.slice(1));
4379
+ break;
4144
4380
  case 'mv':
4145
4381
  await cmdMv(args[1], args[2]);
4146
4382
  break;
4147
4383
  case 'diagnose':
4148
4384
  await cmdDiagnose();
4149
4385
  break;
4386
+ case 'net': {
4387
+ const { cmdNet } = await import('./net-check.js');
4388
+ await cmdNet(args.slice(1));
4389
+ break;
4390
+ }
4150
4391
  case 'ctl':
4151
4392
  await cmdCtl(args.slice(1));
4152
4393
  break;
@@ -4183,8 +4424,20 @@ export async function main(args) {
4183
4424
  await cmdGroup(args.slice(1));
4184
4425
  break;
4185
4426
  }
4427
+ case 'bench': {
4428
+ const { suppressSdkLogs } = await import('../aun/aid/index.js');
4429
+ suppressSdkLogs();
4430
+ const { cmdBench } = await import('./bench.js');
4431
+ await cmdBench(args.slice(1));
4432
+ break;
4433
+ }
4434
+ case 'link-rules': {
4435
+ const { cmdLinkRules } = await import('./link-rules.js');
4436
+ cmdLinkRules(args.slice(1));
4437
+ break;
4438
+ }
4186
4439
  default:
4187
- console.log(`Usage: evolclaw {init|start|stop|restart|status|logs|watch|ctl|diagnose|mv}
4440
+ console.log(`Usage: evolclaw {init|start|stop|restart|status|logs|watch|ctl|diagnose|net|mv}
4188
4441
 
4189
4442
  Commands:
4190
4443
  init 初始化 evolclaw home (${resolvePaths().defaultsConfig})
@@ -4202,8 +4455,10 @@ Commands:
4202
4455
  --level error|warn 只显示指定级别及以上
4203
4456
  --module <name> 只显示指定模块(如 feishu、AgentRunner)
4204
4457
  --raw 原始输出,不着色
4205
- watch 监控 logs/ 下所有 .log 文件(汇总实时输出,启动时显示最近 20 条)
4458
+ watch 监控面板选择菜单(↑↓ 选择 log/aid/msg)
4459
+ watch log 监控 logs/ 下所有 .log 文件(汇总实时输出,启动时显示最近 20 条)
4206
4460
  watch aid AID 连接状态实时监控(显示各 AID 在线/离线/重连状态)
4461
+ watch msg 消息监控(三面板交互式 TUI:AID 列表 / 对端统计 / 消息流)
4207
4462
  ctl 运行时自管理(模型切换、推理强度、压缩上下文等)
4208
4463
  evolclaw ctl help 查看完整命令列表
4209
4464
  agent 管理 EvolAgent
@@ -4228,6 +4483,9 @@ Commands:
4228
4483
  aid lookup <aid> 远程探测 AID(是否存在 + 网关 + agent.md)
4229
4484
  aid agentmd put <aid> 签名并上传 agent.md
4230
4485
  aid agentmd get <aid> 下载并验签 agent.md
4486
+ net 网络链路诊断
4487
+ net check [<aid>] 10 步链路检测(DNS→Discovery→TCP→TLS→WSS→Auth→Ping→Echo)
4488
+ net help 查看详细帮助
4231
4489
  rpc AUN RPC 调用
4232
4490
  rpc --as <aid> --params <json|jsonl|file>
4233
4491
  storage 文件存储
@@ -4238,6 +4496,8 @@ Commands:
4238
4496
  storage quota <aid>
4239
4497
  diagnose 诊断启动环境(配置、数据库、进程)
4240
4498
  mv <old> <new> 迁移项目目录(保留 Claude/Codex/EvolClaw 会话)
4499
+ bench AUN 消息性能基准测试
4500
+ bench --aids 5 --rounds 10 --concurrency 5
4241
4501
 
4242
4502
  Environment:
4243
4503
  EVOLCLAW_HOME 数据目录 (默认: ~/.evolclaw)