evolclaw 3.0.0 → 3.1.1
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/README.md +1 -1
- package/bin/ec.js +29 -0
- package/dist/agents/baseagent-normalize.js +19 -0
- package/dist/agents/claude-runner.js +47 -12
- package/dist/agents/codex-runner.js +2 -0
- package/dist/agents/gemini-runner.js +9 -9
- package/dist/agents/kit-renderer.js +281 -0
- package/dist/aun/aid/identity.js +28 -0
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/lifecycle-log.js +33 -0
- package/dist/aun/msg/group.js +3 -1
- package/dist/aun/msg/p2p.js +42 -1
- package/dist/channels/aun.js +427 -146
- package/dist/channels/dingtalk.js +3 -1
- package/dist/channels/feishu.js +128 -7
- package/dist/channels/qqbot.js +3 -1
- package/dist/channels/wechat.js +4 -1
- package/dist/channels/wecom.js +3 -1
- package/dist/cli/bench.js +1219 -0
- package/dist/cli/index.js +418 -40
- package/dist/cli/init.js +3 -4
- package/dist/cli/link-rules.js +245 -0
- package/dist/cli/net-check.js +640 -0
- package/dist/cli/watch-msg.js +666 -0
- package/dist/config-store.js +82 -5
- package/dist/core/channel-loader.js +23 -10
- package/dist/core/command-handler.js +127 -99
- package/dist/core/evolagent.js +5 -10
- package/dist/core/message/im-renderer.js +93 -48
- package/dist/core/message/items-formatter.js +11 -4
- package/dist/core/message/message-bridge.js +11 -2
- package/dist/core/message/message-log.js +8 -1
- package/dist/core/message/message-processor.js +194 -127
- package/dist/core/message/message-queue.js +10 -3
- package/dist/core/permission.js +95 -3
- package/dist/core/relation/peer-identity.js +161 -0
- package/dist/core/session/session-manager.js +103 -65
- package/dist/core/trigger/manager.js +16 -0
- package/dist/core/trigger/parser.js +110 -0
- package/dist/core/trigger/scheduler.js +7 -1
- package/dist/data/error-dict.json +118 -0
- package/dist/eck/baseagent-caps.js +18 -0
- package/dist/eck/detect.js +47 -0
- package/dist/eck/init.js +77 -0
- package/dist/eck/rules-loader.js +28 -0
- package/dist/index.js +186 -19
- package/dist/net-check.js +640 -0
- package/dist/paths.js +31 -40
- package/dist/utils/aid-lifecycle-log.js +33 -0
- package/dist/utils/atomic-write.js +10 -0
- package/dist/utils/cross-platform.js +17 -8
- package/dist/utils/error-utils.js +27 -15
- package/dist/utils/instance-registry.js +6 -5
- package/dist/utils/log-writer.js +2 -1
- package/dist/utils/logger.js +10 -0
- package/dist/utils/npm-ops.js +35 -3
- package/dist/utils/process-introspect.js +16 -38
- package/dist/utils/stats.js +216 -2
- package/dist/watch-msg.js +26 -11
- package/evolclaw-install-aun.md +14 -2
- package/kits/docs/GUIDE.md +20 -0
- package/kits/docs/INDEX.md +52 -0
- package/kits/docs/aun/CHEATSHEET.md +17 -0
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -0
- package/kits/docs/channels/feishu.md +27 -0
- package/kits/docs/eck_templates/GUIDE.template.md +22 -0
- package/kits/docs/eck_templates/INDEX.template.md +28 -0
- package/kits/docs/eck_templates/path-registry.template.md +33 -0
- package/kits/docs/eck_templates/runtime.template.md +19 -0
- package/kits/docs/evolclaw/MSG_GROUP.md +30 -0
- package/kits/docs/evolclaw/MSG_PRIVATE.md +72 -0
- package/kits/docs/identity/AID_PROFILE_SPEC.md +27 -0
- package/kits/docs/identity/PATH_OPS.md +16 -0
- package/kits/docs/identity/ROLE_DETAIL.md +20 -0
- package/kits/docs/path-registry.md +43 -0
- package/kits/eck_manifest.json +95 -0
- package/kits/rules/01-overview.md +120 -0
- package/kits/rules/02-navigation.md +75 -0
- package/kits/rules/03-identity.md +34 -0
- package/kits/rules/04-relation.md +49 -0
- package/kits/rules/05-venue.md +45 -0
- package/kits/rules/06-channel.md +73 -0
- package/kits/templates/system-fragments/baseagent.md +2 -0
- package/kits/templates/system-fragments/channel.md +10 -0
- package/kits/templates/system-fragments/identity.md +12 -0
- package/kits/templates/system-fragments/relation.md +9 -0
- package/kits/templates/system-fragments/runtime.md +19 -0
- package/kits/templates/system-fragments/venue.md +5 -0
- package/package.json +7 -5
- package/dist/agents/templates.js +0 -122
- package/dist/data/prompts.md +0 -137
- package/kits/aun/meta.md +0 -25
- package/kits/aun/role.md +0 -25
- package/kits/templates/group.md +0 -20
- package/kits/templates/private.md +0 -9
- package/kits/templates/system-fragments/personal-context.md +0 -3
- package/kits/templates/system-fragments/self-intro.md +0 -5
- package/kits/templates/system-fragments/speaker-intro.md +0 -5
- package/kits/templates/system-fragments/venue-intro.md +0 -5
- /package/kits/{channels → docs/channels}/aun.md +0 -0
- /package/kits/{evolclaw/commands.md → docs/evolclaw/AGENT_CMD.md} +0 -0
- /package/kits/{evolclaw → docs/evolclaw}/self-summary.md +0 -0
- /package/kits/{evolclaw → docs/evolclaw}/tools.md +0 -0
- /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');
|
|
@@ -230,7 +231,53 @@ function reportOrphans(orphans) {
|
|
|
230
231
|
console.log(' 这些进程不属于当前 HOME 的实例登记簿,自动清理不会处理它们。');
|
|
231
232
|
console.log(' 使用 evolclaw restart --clear 一并清掉,或手动 kill。');
|
|
232
233
|
}
|
|
234
|
+
function formatLocalTime(ms) {
|
|
235
|
+
const d = new Date(ms);
|
|
236
|
+
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
|
|
237
|
+
}
|
|
238
|
+
function printStartupInfo() {
|
|
239
|
+
const pkgRoot = getPackageRoot();
|
|
240
|
+
const isNpmInstall = pkgRoot.includes('node_modules');
|
|
241
|
+
const cliRunsSource = !import.meta.url.includes('/dist/');
|
|
242
|
+
const daemonEntry = path.join(pkgRoot, 'dist', 'index.js');
|
|
243
|
+
const daemonRunsDist = fs.existsSync(daemonEntry);
|
|
244
|
+
const scanDir = path.join(pkgRoot, daemonRunsDist ? 'dist' : 'src');
|
|
245
|
+
let latestMtime = 0;
|
|
246
|
+
const scanRecursive = (dir) => {
|
|
247
|
+
try {
|
|
248
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
249
|
+
if (entry.name === 'node_modules')
|
|
250
|
+
continue;
|
|
251
|
+
const full = path.join(dir, entry.name);
|
|
252
|
+
if (entry.isDirectory()) {
|
|
253
|
+
scanRecursive(full);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
if (entry.name.endsWith('.js') || entry.name.endsWith('.ts')) {
|
|
257
|
+
const mt = fs.statSync(full).mtimeMs;
|
|
258
|
+
if (mt > latestMtime)
|
|
259
|
+
latestMtime = mt;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch { }
|
|
264
|
+
};
|
|
265
|
+
scanRecursive(scanDir);
|
|
266
|
+
let version = '?';
|
|
267
|
+
try {
|
|
268
|
+
version = JSON.parse(fs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf-8')).version;
|
|
269
|
+
}
|
|
270
|
+
catch { }
|
|
271
|
+
console.log(` EvolClaw v${version}`);
|
|
272
|
+
console.log(` 包路径: ${pkgRoot}`);
|
|
273
|
+
console.log(` 安装类型: ${isNpmInstall ? 'npm全局安装' : '开发仓(link)'}`);
|
|
274
|
+
console.log(` CLI执行: ${cliRunsSource ? '源码(tsx)' : '编译产物(dist)'}`);
|
|
275
|
+
console.log(` Daemon执行: ${daemonRunsDist ? '编译产物(dist)' : '未知'}`);
|
|
276
|
+
console.log(` 代码时间: ${latestMtime ? formatLocalTime(latestMtime) : '?'}`);
|
|
277
|
+
}
|
|
233
278
|
async function cmdStart() {
|
|
279
|
+
const cmdStartedAt = Date.now();
|
|
280
|
+
printStartupInfo();
|
|
234
281
|
const p = resolvePaths();
|
|
235
282
|
ensureDataDirs();
|
|
236
283
|
// 旧配置自动迁移(evolclaw.json → 新结构)
|
|
@@ -258,7 +305,7 @@ async function cmdStart() {
|
|
|
258
305
|
if (aliveMains.length > 0) {
|
|
259
306
|
const first = aliveMains[0];
|
|
260
307
|
console.log(`❌ EvolClaw is already running (PID: ${aliveMains.map(m => m.record.pid).join(', ')})`);
|
|
261
|
-
console.log(` 启动于: ${first.record.startedAtIso}`);
|
|
308
|
+
console.log(` 启动于: ${new Date(first.record.startedAtIso).toLocaleString()}`);
|
|
262
309
|
console.log(` 启动方式: ${first.record.launchedBy}`);
|
|
263
310
|
// 报告 AID 状态
|
|
264
311
|
if (status.aidLastActivity.size > 0) {
|
|
@@ -315,7 +362,14 @@ async function cmdStart() {
|
|
|
315
362
|
const checkReady = () => {
|
|
316
363
|
// ready signal 出现(优先检查,避免 Windows 上误判进程状态)
|
|
317
364
|
if (fs.existsSync(p.readySignal)) {
|
|
318
|
-
|
|
365
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
|
|
366
|
+
let aunVer = 'unknown';
|
|
367
|
+
try {
|
|
368
|
+
const aunPkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'node_modules', '@agentunion', 'fastaun', 'package.json'), 'utf-8'));
|
|
369
|
+
aunVer = aunPkg.version;
|
|
370
|
+
}
|
|
371
|
+
catch { /* ignore */ }
|
|
372
|
+
console.log(`✓ EvolClaw v${pkg.version} started successfully (PID: ${childPid}) fastaun v${aunVer}`);
|
|
319
373
|
console.log(` EVOLCLAW_HOME: ${resolveRoot()}`);
|
|
320
374
|
console.log(` Logs: ${p.logs}/`);
|
|
321
375
|
// 从主日志提取渠道连接摘要
|
|
@@ -358,6 +412,7 @@ async function cmdStart() {
|
|
|
358
412
|
if (resolveRoot() === getPackageRoot()) {
|
|
359
413
|
countLines(getPackageRoot(), p.logs);
|
|
360
414
|
}
|
|
415
|
+
console.log(`⏱ done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
|
|
361
416
|
return;
|
|
362
417
|
}
|
|
363
418
|
// 超时
|
|
@@ -369,6 +424,7 @@ async function cmdStart() {
|
|
|
369
424
|
const content = fs.readFileSync(stdoutLog, 'utf-8').trim().split('\n');
|
|
370
425
|
console.log(content.slice(-10).map(l => ` ${l}`).join('\n'));
|
|
371
426
|
}
|
|
427
|
+
console.log(`⏱ failed after ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
|
|
372
428
|
process.exit(1);
|
|
373
429
|
return;
|
|
374
430
|
}
|
|
@@ -383,6 +439,7 @@ async function cmdStart() {
|
|
|
383
439
|
const content = fs.readFileSync(stdoutLog, 'utf-8').trim().split('\n');
|
|
384
440
|
console.log(content.slice(-10).map(l => ` ${l}`).join('\n'));
|
|
385
441
|
}
|
|
442
|
+
console.log(`⏱ failed after ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
|
|
386
443
|
process.exit(1);
|
|
387
444
|
return;
|
|
388
445
|
}
|
|
@@ -428,6 +485,8 @@ async function cmdStop() {
|
|
|
428
485
|
}
|
|
429
486
|
}
|
|
430
487
|
async function cmdRestart(opts = {}) {
|
|
488
|
+
const cmdStartedAt = Date.now();
|
|
489
|
+
printStartupInfo();
|
|
431
490
|
console.log('🔄 Restarting EvolClaw...');
|
|
432
491
|
// 版本检查与自动升级
|
|
433
492
|
console.log('📦 Checking for updates...');
|
|
@@ -448,6 +507,18 @@ async function cmdRestart(opts = {}) {
|
|
|
448
507
|
console.log(`⚠ Upgrade failed (${upgrade.from} → ${upgrade.to}), continuing with current version`);
|
|
449
508
|
break;
|
|
450
509
|
}
|
|
510
|
+
// AUN SDK 版本检查与升级
|
|
511
|
+
const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
|
|
512
|
+
switch (aunUpgrade.status) {
|
|
513
|
+
case 'upgraded':
|
|
514
|
+
console.log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
|
|
515
|
+
break;
|
|
516
|
+
case 'no-update':
|
|
517
|
+
break; // silent
|
|
518
|
+
case 'failed':
|
|
519
|
+
console.log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to})`);
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
451
522
|
// 停止所有活 main 进程(可能不止一个)
|
|
452
523
|
const status = scanInstances();
|
|
453
524
|
const aliveMains = status.mains.filter(m => m.alive);
|
|
@@ -457,20 +528,164 @@ async function cmdRestart(opts = {}) {
|
|
|
457
528
|
}
|
|
458
529
|
await Promise.all(aliveMains.map(m => stopPid(m.record.pid)));
|
|
459
530
|
await sleep(500);
|
|
460
|
-
cleanupInstances();
|
|
461
531
|
}
|
|
462
|
-
|
|
463
|
-
//
|
|
464
|
-
|
|
532
|
+
cleanupInstances();
|
|
533
|
+
// 孤儿处理:同 HOME 的孤儿无条件 kill(restart 必须替换旧实例);
|
|
534
|
+
// 跨 HOME 的孤儿只在 --clear 时 kill,否则仅警告。
|
|
535
|
+
{
|
|
465
536
|
const orphans = findOrphanProcesses();
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
537
|
+
const currentHome = resolveRoot();
|
|
538
|
+
const sameHome = orphans.filter(o => o.evolclawHome === currentHome);
|
|
539
|
+
const otherHome = orphans.filter(o => o.evolclawHome !== currentHome);
|
|
540
|
+
if (sameHome.length > 0) {
|
|
541
|
+
const killed = killOrphans(sameHome);
|
|
542
|
+
console.log(`☠ 已 SIGKILL ${killed.length} 个同 HOME 孤儿进程: ${killed.join(', ')}`);
|
|
543
|
+
await sleep(500);
|
|
544
|
+
}
|
|
545
|
+
if (opts.clear && otherHome.length > 0) {
|
|
546
|
+
const killed = killOrphans(otherHome);
|
|
547
|
+
console.log(`☠ 已 SIGKILL ${killed.length} 个跨 HOME 孤儿进程: ${killed.join(', ')}`);
|
|
469
548
|
await sleep(500);
|
|
470
549
|
}
|
|
471
550
|
}
|
|
551
|
+
console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
|
|
472
552
|
setTimeout(() => cmdStart(), 1000);
|
|
473
553
|
}
|
|
554
|
+
async function cmdDev(args) {
|
|
555
|
+
const pkgRoot = getPackageRoot();
|
|
556
|
+
const isNpmInstall = pkgRoot.includes('node_modules');
|
|
557
|
+
const p = resolvePaths();
|
|
558
|
+
const devMarker = path.join(p.dataDir, 'dev-repo.path');
|
|
559
|
+
const sub = args[0];
|
|
560
|
+
if (!sub) {
|
|
561
|
+
if (!isNpmInstall) {
|
|
562
|
+
console.log(`当前: [dev] ${pkgRoot}`);
|
|
563
|
+
console.log('');
|
|
564
|
+
console.log('断开开发仓链接:');
|
|
565
|
+
console.log(' evolclaw dev off');
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
console.log(`当前: [pkg] ${pkgRoot}`);
|
|
569
|
+
console.log('');
|
|
570
|
+
let devPath = null;
|
|
571
|
+
try {
|
|
572
|
+
devPath = fs.readFileSync(devMarker, 'utf-8').trim();
|
|
573
|
+
}
|
|
574
|
+
catch { }
|
|
575
|
+
if (devPath && fs.existsSync(devPath)) {
|
|
576
|
+
console.log('链接到开发仓:');
|
|
577
|
+
console.log(` evolclaw dev on`);
|
|
578
|
+
console.log(` (已记录路径: ${devPath})`);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
console.log('链接到开发仓:');
|
|
582
|
+
console.log(' evolclaw dev <开发仓路径>');
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (sub === 'off') {
|
|
588
|
+
if (isNpmInstall) {
|
|
589
|
+
console.log('当前已是 [pkg] 模式,无需断开');
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
console.log('🔗 断开开发仓链接...');
|
|
593
|
+
let npmPrefix;
|
|
594
|
+
if (process.platform === 'win32' && process.env.APPDATA) {
|
|
595
|
+
npmPrefix = path.join(process.env.APPDATA, 'npm');
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
npmPrefix = execFileSync('npm', ['prefix', '-g'], { encoding: 'utf-8', shell: true }).trim();
|
|
599
|
+
}
|
|
600
|
+
const linkPath = path.join(npmPrefix, 'node_modules', 'evolclaw');
|
|
601
|
+
const binPath = path.join(npmPrefix, 'evolclaw');
|
|
602
|
+
try {
|
|
603
|
+
fs.rmSync(linkPath, { recursive: true });
|
|
604
|
+
}
|
|
605
|
+
catch { }
|
|
606
|
+
try {
|
|
607
|
+
fs.unlinkSync(binPath);
|
|
608
|
+
}
|
|
609
|
+
catch { }
|
|
610
|
+
try {
|
|
611
|
+
fs.unlinkSync(binPath + '.cmd');
|
|
612
|
+
}
|
|
613
|
+
catch { }
|
|
614
|
+
try {
|
|
615
|
+
fs.unlinkSync(binPath + '.ps1');
|
|
616
|
+
}
|
|
617
|
+
catch { }
|
|
618
|
+
console.log('✓ 已断开');
|
|
619
|
+
console.log(` 已删除: ${linkPath}`);
|
|
620
|
+
console.log(` 如需恢复: evolclaw dev on(需从已安装的 evolclaw 执行)`);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (sub === 'on') {
|
|
624
|
+
if (!isNpmInstall) {
|
|
625
|
+
console.log(`当前已是 [dev] 模式: ${pkgRoot}`);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
let devPath = null;
|
|
629
|
+
try {
|
|
630
|
+
devPath = fs.readFileSync(devMarker, 'utf-8').trim();
|
|
631
|
+
}
|
|
632
|
+
catch { }
|
|
633
|
+
if (!devPath || !fs.existsSync(devPath)) {
|
|
634
|
+
console.log('未记录开发仓路径');
|
|
635
|
+
console.log('');
|
|
636
|
+
console.log('用法: evolclaw dev <开发仓路径>');
|
|
637
|
+
process.exit(1);
|
|
638
|
+
}
|
|
639
|
+
console.log(`🔗 链接开发仓: ${devPath}`);
|
|
640
|
+
try {
|
|
641
|
+
execFileSync('npm', ['link'], { stdio: 'inherit', cwd: devPath, shell: true });
|
|
642
|
+
console.log(`✓ 已链接 [dev] ${devPath}`);
|
|
643
|
+
}
|
|
644
|
+
catch (e) {
|
|
645
|
+
console.error('❌ npm link 失败:', e.message);
|
|
646
|
+
process.exit(1);
|
|
647
|
+
}
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
// evolclaw dev <path> — 记录路径 + 建立链接
|
|
651
|
+
const devPath = path.resolve(sub);
|
|
652
|
+
const pkgJson = path.join(devPath, 'package.json');
|
|
653
|
+
if (!fs.existsSync(pkgJson)) {
|
|
654
|
+
console.error(`❌ 路径不存在或无 package.json: ${devPath}`);
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
657
|
+
let pkg;
|
|
658
|
+
try {
|
|
659
|
+
pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'));
|
|
660
|
+
}
|
|
661
|
+
catch {
|
|
662
|
+
console.error(`❌ 无法解析 package.json: ${pkgJson}`);
|
|
663
|
+
process.exit(1);
|
|
664
|
+
}
|
|
665
|
+
if (pkg.name !== 'evolclaw') {
|
|
666
|
+
console.error(`❌ package.json name 不是 evolclaw(是 "${pkg.name}")`);
|
|
667
|
+
process.exit(1);
|
|
668
|
+
}
|
|
669
|
+
// 已经链接到同一路径,只记录不重复 link
|
|
670
|
+
if (!isNpmInstall && path.resolve(pkgRoot) === devPath) {
|
|
671
|
+
fs.mkdirSync(p.dataDir, { recursive: true });
|
|
672
|
+
fs.writeFileSync(devMarker, devPath, 'utf-8');
|
|
673
|
+
console.log(`✓ 当前已链接到该路径,路径已记录`);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
console.log(`🔗 链接开发仓: ${devPath}`);
|
|
677
|
+
try {
|
|
678
|
+
execFileSync('npm', ['link'], { stdio: 'inherit', cwd: devPath, shell: true });
|
|
679
|
+
}
|
|
680
|
+
catch (e) {
|
|
681
|
+
console.error('❌ npm link 失败:', e.message);
|
|
682
|
+
process.exit(1);
|
|
683
|
+
}
|
|
684
|
+
fs.mkdirSync(p.dataDir, { recursive: true });
|
|
685
|
+
fs.writeFileSync(devMarker, devPath, 'utf-8');
|
|
686
|
+
console.log(`✓ 已链接 [dev] ${devPath}`);
|
|
687
|
+
console.log(` 路径已记录,下次可用 evolclaw dev on 快速切换`);
|
|
688
|
+
}
|
|
474
689
|
function formatTimeAgo(ms) {
|
|
475
690
|
const sec = Math.floor(ms / 1000);
|
|
476
691
|
if (sec < 60)
|
|
@@ -1250,7 +1465,7 @@ async function cmdWatchMenu() {
|
|
|
1250
1465
|
await cmdWatchAid();
|
|
1251
1466
|
}
|
|
1252
1467
|
else if (chosen === 'msg') {
|
|
1253
|
-
const { cmdWatchMsg } = await import('
|
|
1468
|
+
const { cmdWatchMsg } = await import('./watch-msg.js');
|
|
1254
1469
|
await cmdWatchMsg();
|
|
1255
1470
|
}
|
|
1256
1471
|
resolve();
|
|
@@ -1348,7 +1563,7 @@ function cmdWatch() {
|
|
|
1348
1563
|
}
|
|
1349
1564
|
const m = aliveMainEntries[0].record;
|
|
1350
1565
|
const uptime = formatTimeAgo(Date.now() - m.startedAt);
|
|
1351
|
-
console.log(`📦 Instance: PID ${m.pid} | 启动于 ${m.startedAtIso} (${uptime}) | via ${m.launchedBy}`);
|
|
1566
|
+
console.log(`📦 Instance: PID ${m.pid} | 启动于 ${new Date(m.startedAtIso).toLocaleString()} (${uptime}) | via ${m.launchedBy}`);
|
|
1352
1567
|
if (instStatus.aidLastActivity.size > 0) {
|
|
1353
1568
|
const now = Date.now();
|
|
1354
1569
|
const aidLines = [];
|
|
@@ -1598,6 +1813,11 @@ async function cmdWatchAid() {
|
|
|
1598
1813
|
const COL_LRECV = 10;
|
|
1599
1814
|
const COL_LSENT = 10;
|
|
1600
1815
|
const COL_PEERS = 5;
|
|
1816
|
+
// 表头跟随系统语言
|
|
1817
|
+
const isChinese = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || Intl.DateTimeFormat().resolvedOptions().locale || '').toLowerCase().includes('zh');
|
|
1818
|
+
const HEADERS = isChinese
|
|
1819
|
+
? { aid: 'AID', status: '状态', uptime: '运行', state: '工作', reconn: '重连', recv: '收', sent: '发', sys: '系统', bin: '入流量', bout: '出流量', lrecv: '最后收', lsent: '最后发', peers: '对端' }
|
|
1820
|
+
: { aid: 'AID', status: 'STATUS', uptime: 'UPTIME', state: 'STATE', reconn: 'RECONN', recv: 'RECV', sent: 'SENT', sys: 'SYS R/S', bin: 'BYTES IN', bout: 'BYTES OUT', lrecv: 'LAST RECV', lsent: 'LAST SENT', peers: 'PEERS' };
|
|
1601
1821
|
function formatDuration(ms) {
|
|
1602
1822
|
const sec = Math.floor(ms / 1000);
|
|
1603
1823
|
if (sec < 60)
|
|
@@ -1615,19 +1835,19 @@ async function cmdWatchAid() {
|
|
|
1615
1835
|
}
|
|
1616
1836
|
function renderHeader() {
|
|
1617
1837
|
return ' ' +
|
|
1618
|
-
padRight(
|
|
1619
|
-
padRight(
|
|
1620
|
-
padRight(
|
|
1621
|
-
padRight(
|
|
1622
|
-
padRight(
|
|
1623
|
-
padRight(
|
|
1624
|
-
padRight(
|
|
1625
|
-
padRight(
|
|
1626
|
-
padRight(
|
|
1627
|
-
padRight(
|
|
1628
|
-
padRight(
|
|
1629
|
-
padRight(
|
|
1630
|
-
padRight(
|
|
1838
|
+
padRight(HEADERS.aid, COL_AID) +
|
|
1839
|
+
padRight(HEADERS.status, COL_STATUS) +
|
|
1840
|
+
padRight(HEADERS.uptime, COL_UPTIME) +
|
|
1841
|
+
padRight(HEADERS.state, COL_STATE) +
|
|
1842
|
+
padRight(HEADERS.reconn, COL_RECONN) +
|
|
1843
|
+
padRight(HEADERS.recv, COL_RECV) +
|
|
1844
|
+
padRight(HEADERS.sent, COL_SENT) +
|
|
1845
|
+
padRight(HEADERS.sys, COL_SYS) +
|
|
1846
|
+
padRight(HEADERS.bin, COL_BIN) +
|
|
1847
|
+
padRight(HEADERS.bout, COL_BOUT) +
|
|
1848
|
+
padRight(HEADERS.lrecv, COL_LRECV) +
|
|
1849
|
+
padRight(HEADERS.lsent, COL_LSENT) +
|
|
1850
|
+
padRight(HEADERS.peers, COL_PEERS);
|
|
1631
1851
|
}
|
|
1632
1852
|
function renderRow(aid, stats, projectPath) {
|
|
1633
1853
|
const aidLabel = aid.aid.length > COL_AID - 2 ? aid.aid.slice(0, COL_AID - 4) + '..' : aid.aid;
|
|
@@ -1666,6 +1886,13 @@ async function cmdWatchAid() {
|
|
|
1666
1886
|
const nameReset = refreshedAids.has(aid.aid) ? '' : RST;
|
|
1667
1887
|
const BLUE = useColor ? '\x1b[34m' : '';
|
|
1668
1888
|
const ORANGE = useColor ? '\x1b[38;5;208m' : '';
|
|
1889
|
+
const MAGENTA = useColor ? '\x1b[35m' : '';
|
|
1890
|
+
// 标记生成:[明文/密文|自主/响应](紫色=工具渲染标记)
|
|
1891
|
+
const mkTags = (encrypt, chatmode) => {
|
|
1892
|
+
const enc = encrypt ? '密文' : '明文';
|
|
1893
|
+
const mode = chatmode === 'proactive' ? '自主' : '响应';
|
|
1894
|
+
return `${MAGENTA}[${enc}|${mode}]${RST}`;
|
|
1895
|
+
};
|
|
1669
1896
|
let msgPreview = '';
|
|
1670
1897
|
if (stats?.lastReceivedAt || stats?.lastSentAt) {
|
|
1671
1898
|
const recvTs = stats.lastReceivedAt ?? 0;
|
|
@@ -1676,17 +1903,81 @@ async function cmdWatchAid() {
|
|
|
1676
1903
|
}
|
|
1677
1904
|
else if (stats.lastSentText) {
|
|
1678
1905
|
const toShort = stats.lastSentTo ? stats.lastSentTo.split('.')[0] : '';
|
|
1679
|
-
|
|
1906
|
+
const tags = mkTags(stats.lastSentEncrypt, stats.lastSentChatmode);
|
|
1907
|
+
// task 进行中时也显示计数(processing > 0 说明还在跑)
|
|
1908
|
+
const isWorking = (stats.processing ?? 0) > 0;
|
|
1909
|
+
const taskEnd = stats?.lastTaskEnd;
|
|
1910
|
+
const counts = isWorking && taskEnd
|
|
1911
|
+
? `${MAGENTA}[大模型${taskEnd.numTurns}|调用${taskEnd.toolUseCount}|thought${taskEnd.thoughtPutCount}|msg${taskEnd.replyCount}]${RST}`
|
|
1912
|
+
: '';
|
|
1913
|
+
msgPreview = `${BLUE}↑${tags}${counts} ${toShort ? `${ORANGE}${toShort}${RST}${BLUE}: ` : ''}${stats.lastSentText.replace(/\n/g, ' ').slice(0, 60)}${RST}`;
|
|
1680
1914
|
}
|
|
1681
1915
|
else if (stats.lastReceivedText) {
|
|
1682
1916
|
const fromShort = stats.lastReceivedFrom ? stats.lastReceivedFrom.split('.')[0] : '';
|
|
1683
1917
|
msgPreview = `${GREEN}↓ ${fromShort ? `${ORANGE}${fromShort}${RST}${GREEN}: ` : ''}${stats.lastReceivedText.replace(/\n/g, ' ').slice(0, 60)}${RST}`;
|
|
1684
1918
|
}
|
|
1685
1919
|
}
|
|
1920
|
+
// 任务结束状态覆盖:仅当 taskEnd 比最后收发都新时才覆盖
|
|
1921
|
+
const taskEnd = stats?.lastTaskEnd;
|
|
1922
|
+
if (taskEnd && taskEnd.ts >= (stats?.lastSentAt ?? 0) && taskEnd.ts >= (stats?.lastReceivedAt ?? 0)) {
|
|
1923
|
+
const tags = mkTags(taskEnd.encrypt, taskEnd.chatmode);
|
|
1924
|
+
// 计数标记: [大模型N|调用N|thoughtN(streamN)|msgN]
|
|
1925
|
+
const thoughtLabel = taskEnd.thoughtPutCount > 0
|
|
1926
|
+
? `thought${taskEnd.numTurns}(stream${taskEnd.thoughtPutCount})`
|
|
1927
|
+
: `thought${taskEnd.numTurns}`;
|
|
1928
|
+
const counts = `${MAGENTA}[大模型${taskEnd.numTurns}|调用${taskEnd.toolUseCount}|${thoughtLabel}|msg${taskEnd.replyCount}]${RST}`;
|
|
1929
|
+
if (taskEnd.status === 'error') {
|
|
1930
|
+
msgPreview = `${RED}${tags}${counts} 错误: ${taskEnd.errorType ?? '未知错误'}${RST}`;
|
|
1931
|
+
}
|
|
1932
|
+
else if (taskEnd.sentDuringTask) {
|
|
1933
|
+
// 有 message.send:蓝色加粗 + 内容
|
|
1934
|
+
const toShort = stats?.lastSentTo ? stats.lastSentTo.split('.')[0] : '';
|
|
1935
|
+
const textPreview = stats?.lastSentText ? stats.lastSentText.replace(/\n/g, ' ').slice(0, 60) : '';
|
|
1936
|
+
msgPreview = `${BOLD}${BLUE}↑${tags}${counts} ${toShort ? `${ORANGE}${toShort}${RST}${BOLD}${BLUE}: ` : ''}${textPreview}${RST}`;
|
|
1937
|
+
}
|
|
1938
|
+
else if (taskEnd.thoughtDuringTask) {
|
|
1939
|
+
// 只有 thought:普通蓝色 + thought 内容
|
|
1940
|
+
const textPreview = taskEnd.lastThoughtText
|
|
1941
|
+
? taskEnd.lastThoughtText.replace(/\n/g, ' ').slice(0, 60)
|
|
1942
|
+
: (taskEnd.finalText ? taskEnd.finalText.replace(/\n/g, ' ').slice(0, 60) : '');
|
|
1943
|
+
msgPreview = `${BLUE}↑${tags}${counts} ${textPreview}${RST}`;
|
|
1944
|
+
}
|
|
1945
|
+
else {
|
|
1946
|
+
// 既没 send 也没 thought
|
|
1947
|
+
const textPreview = taskEnd.finalText
|
|
1948
|
+
? taskEnd.finalText.replace(/\n/g, ' ').slice(0, 60)
|
|
1949
|
+
: '(无输出)';
|
|
1950
|
+
msgPreview = `${ORANGE}${tags}${counts} ${textPreview}${RST}`;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1686
1953
|
const subLine1 = ` ${nameColor}${namePart}${nameReset}${msgPreview ? ' ' + msgPreview : ''}`;
|
|
1687
1954
|
const dirLabel = projectPath || '—';
|
|
1688
1955
|
const subLine2 = `${DIM} ${dirLabel}${RST}`;
|
|
1689
|
-
|
|
1956
|
+
const result = [mainLine, subLine1, subLine2];
|
|
1957
|
+
if (aid.status === 'failed' || aid.status === 'kicked' || aid.status === 'kicked_no_retry') {
|
|
1958
|
+
const parts = [];
|
|
1959
|
+
if (aid.lastAttemptAt) {
|
|
1960
|
+
const d = new Date(aid.lastAttemptAt);
|
|
1961
|
+
const ts = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
|
|
1962
|
+
parts.push(`last_attempt=${ts}`);
|
|
1963
|
+
}
|
|
1964
|
+
if (aid.kickDetail?.code) {
|
|
1965
|
+
parts.push(`code=${aid.kickDetail.code}`);
|
|
1966
|
+
}
|
|
1967
|
+
if (aid.kickDetail?.reason) {
|
|
1968
|
+
parts.push(`reason=${aid.kickDetail.reason}`);
|
|
1969
|
+
}
|
|
1970
|
+
if (aid.lastError) {
|
|
1971
|
+
parts.push(`error=${aid.lastError}`);
|
|
1972
|
+
}
|
|
1973
|
+
if (aid.gatewayUrl) {
|
|
1974
|
+
parts.push(`gateway=${aid.gatewayUrl}`);
|
|
1975
|
+
}
|
|
1976
|
+
if (parts.length > 0) {
|
|
1977
|
+
result.push(`${RED} ⚠ ${parts.join(' ')}${RST}`);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
return result;
|
|
1690
1981
|
}
|
|
1691
1982
|
let lastLineCount = 0;
|
|
1692
1983
|
async function render() {
|
|
@@ -1905,6 +2196,19 @@ async function cmdRestartMonitor() {
|
|
|
1905
2196
|
await notifyChannel(p, pendingInfo, `⚠️ 升级失败,使用当前版本继续`, log);
|
|
1906
2197
|
break;
|
|
1907
2198
|
}
|
|
2199
|
+
// AUN SDK 版本检查与升级
|
|
2200
|
+
const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
|
|
2201
|
+
switch (aunUpgrade.status) {
|
|
2202
|
+
case 'upgraded':
|
|
2203
|
+
log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
|
|
2204
|
+
await notifyChannel(p, pendingInfo, `📦 AUN SDK 已升级 ${aunUpgrade.from} → ${aunUpgrade.to}`, log);
|
|
2205
|
+
break;
|
|
2206
|
+
case 'no-update':
|
|
2207
|
+
break;
|
|
2208
|
+
case 'failed':
|
|
2209
|
+
log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to}): ${aunUpgrade.error}`);
|
|
2210
|
+
break;
|
|
2211
|
+
}
|
|
1908
2212
|
// 启动并检测 ready signal
|
|
1909
2213
|
let started = await spawnAndWaitReady(p, log, READY_TIMEOUT);
|
|
1910
2214
|
if (started) {
|
|
@@ -2486,7 +2790,7 @@ async function cmdCtl(args) {
|
|
|
2486
2790
|
async function cmdAgent(args) {
|
|
2487
2791
|
const sub = args[0];
|
|
2488
2792
|
const formatJson = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
|
|
2489
|
-
if (sub === 'help') {
|
|
2793
|
+
if (!sub || sub === 'help' || sub === '--help' || sub === '-h' || args.includes('--help') || args.includes('-h')) {
|
|
2490
2794
|
console.log(`用法: evolclaw agent <command>
|
|
2491
2795
|
|
|
2492
2796
|
Commands:
|
|
@@ -2538,17 +2842,43 @@ Options:
|
|
|
2538
2842
|
console.log('No agents configured.');
|
|
2539
2843
|
return;
|
|
2540
2844
|
}
|
|
2541
|
-
|
|
2542
|
-
|
|
2845
|
+
// 表头跟随系统语言
|
|
2846
|
+
const isChinese = (process.env.LANG || process.env.LC_ALL || process.env.LANGUAGE || Intl.DateTimeFormat().resolvedOptions().locale || '').toLowerCase().includes('zh');
|
|
2847
|
+
const headers = isChinese
|
|
2848
|
+
? { name: '名称', status: '状态', channels: '渠道', project: '项目', baseagent: '基座', lastActive: '最后活跃' }
|
|
2849
|
+
: { name: 'NAME', status: 'STATUS', channels: 'CHANNELS', project: 'PROJECT', baseagent: 'BASEAGENT', lastActive: 'LAST ACTIVE' };
|
|
2850
|
+
// 计算各列实际需要的宽度
|
|
2851
|
+
let maxNameLen = headers.name.length;
|
|
2852
|
+
let maxStatusLen = headers.status.length;
|
|
2853
|
+
let maxChannelsLen = headers.channels.length;
|
|
2854
|
+
let maxProjectLen = headers.project.length;
|
|
2855
|
+
let maxBaseagentLen = headers.baseagent.length;
|
|
2856
|
+
for (const info of result.agents) {
|
|
2857
|
+
maxNameLen = Math.max(maxNameLen, info.name.length);
|
|
2858
|
+
maxStatusLen = Math.max(maxStatusLen, (info.status || 'stopped').length);
|
|
2859
|
+
const channelsStr = info.channels?.length > 0 ? info.channels.join(', ') : '—';
|
|
2860
|
+
maxChannelsLen = Math.max(maxChannelsLen, channelsStr.length);
|
|
2861
|
+
const projectStr = info.projectPath ? path.basename(info.projectPath) : '—';
|
|
2862
|
+
maxProjectLen = Math.max(maxProjectLen, projectStr.length);
|
|
2863
|
+
maxBaseagentLen = Math.max(maxBaseagentLen, (info.baseagent || '—').length);
|
|
2864
|
+
}
|
|
2865
|
+
// 加 2 作为列间距
|
|
2866
|
+
const colName = maxNameLen + 2;
|
|
2867
|
+
const colStatus = maxStatusLen + 2;
|
|
2868
|
+
const colChannels = maxChannelsLen + 1;
|
|
2869
|
+
const colProject = maxProjectLen + 2;
|
|
2870
|
+
const colBaseagent = maxBaseagentLen + 2;
|
|
2871
|
+
console.log(headers.name.padEnd(colName) + headers.status.padEnd(colStatus) + headers.channels.padEnd(colChannels) +
|
|
2872
|
+
headers.project.padEnd(colProject) + headers.baseagent.padEnd(colBaseagent) + headers.lastActive);
|
|
2543
2873
|
for (const info of result.agents) {
|
|
2544
2874
|
const name = info.name;
|
|
2545
2875
|
const status = info.status || 'stopped';
|
|
2546
|
-
const channels = info.channels?.length > 0 ? info.channels.join(', ')
|
|
2876
|
+
const channels = info.channels?.length > 0 ? info.channels.join(', ') : '—';
|
|
2547
2877
|
const project = info.projectPath ? path.basename(info.projectPath) : '—';
|
|
2548
2878
|
const baseagent = info.baseagent || '—';
|
|
2549
2879
|
const lastActive = info.lastActivity ? formatTimeAgo(Date.now() - info.lastActivity) : '—';
|
|
2550
|
-
console.log(name.padEnd(
|
|
2551
|
-
project.padEnd(
|
|
2880
|
+
console.log(name.padEnd(colName) + status.padEnd(colStatus) + channels.padEnd(colChannels) +
|
|
2881
|
+
project.padEnd(colProject) + baseagent.padEnd(colBaseagent) + lastActive);
|
|
2552
2882
|
}
|
|
2553
2883
|
return;
|
|
2554
2884
|
}
|
|
@@ -2949,7 +3279,7 @@ async function cmdAid(args) {
|
|
|
2949
3279
|
const sub = args[0] || 'list';
|
|
2950
3280
|
const formatJson = args.includes('--format') && args[args.indexOf('--format') + 1] === 'json';
|
|
2951
3281
|
const aunPath = resolveAunPath(args);
|
|
2952
|
-
if (sub === 'help') {
|
|
3282
|
+
if (!sub || sub === 'help' || sub === '--help' || sub === '-h' || args.includes('--help') || args.includes('-h')) {
|
|
2953
3283
|
console.log(`用法: evolclaw aid <command>
|
|
2954
3284
|
|
|
2955
3285
|
Commands:
|
|
@@ -3495,7 +3825,8 @@ Options:
|
|
|
3495
3825
|
}
|
|
3496
3826
|
body = { mode: 'text', text };
|
|
3497
3827
|
}
|
|
3498
|
-
const
|
|
3828
|
+
const encrypt = args.includes('--encrypt');
|
|
3829
|
+
const result = await msgSend({ from, to, body, encrypt, ...commonOpts });
|
|
3499
3830
|
if (!result.ok) {
|
|
3500
3831
|
if (formatJson) {
|
|
3501
3832
|
console.log(JSON.stringify(result));
|
|
@@ -3789,7 +4120,8 @@ Options:
|
|
|
3789
4120
|
body = { mode: 'text', text };
|
|
3790
4121
|
}
|
|
3791
4122
|
const mentions = collectMentions();
|
|
3792
|
-
const
|
|
4123
|
+
const encryptGroup = args.includes('--encrypt');
|
|
4124
|
+
const result = await groupSend({ from, groupId, body, mentions: mentions.length ? mentions : undefined, encrypt: encryptGroup, ...commonOpts });
|
|
3793
4125
|
outputResult(result, () => {
|
|
3794
4126
|
const r = result;
|
|
3795
4127
|
console.log(`✓ 已发送 message_id=${r.message?.message_id ?? '-'} seq=${r.message?.seq ?? '-'}`);
|
|
@@ -4125,7 +4457,26 @@ export async function main(args) {
|
|
|
4125
4457
|
await cmdWatchAid();
|
|
4126
4458
|
}
|
|
4127
4459
|
else if (args[1] === 'msg') {
|
|
4128
|
-
|
|
4460
|
+
if (args[2] === '--help' || args[2] === '-h' || args[2] === 'help') {
|
|
4461
|
+
console.log(`用法: evolclaw watch msg
|
|
4462
|
+
|
|
4463
|
+
三面板交互式消息监控 TUI。
|
|
4464
|
+
|
|
4465
|
+
面板:
|
|
4466
|
+
左 (Scope) 本地 AID 列表,显示收发统计和对端数量
|
|
4467
|
+
中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
|
|
4468
|
+
右 (Messages) 消息流,带滚动条
|
|
4469
|
+
|
|
4470
|
+
操作:
|
|
4471
|
+
↑↓ 当前面板内导航
|
|
4472
|
+
←→ / Tab 切换面板
|
|
4473
|
+
Enter 选中 AID / 选中对端
|
|
4474
|
+
Backspace 返回上一级
|
|
4475
|
+
Page Up/Down 消息滚动
|
|
4476
|
+
ESC 退出`);
|
|
4477
|
+
break;
|
|
4478
|
+
}
|
|
4479
|
+
const { cmdWatchMsg } = await import('./watch-msg.js');
|
|
4129
4480
|
await cmdWatchMsg();
|
|
4130
4481
|
}
|
|
4131
4482
|
else if (args[1] === 'log') {
|
|
@@ -4141,12 +4492,20 @@ export async function main(args) {
|
|
|
4141
4492
|
case 'restart-monitor':
|
|
4142
4493
|
await cmdRestartMonitor();
|
|
4143
4494
|
break;
|
|
4495
|
+
case 'dev':
|
|
4496
|
+
await cmdDev(args.slice(1));
|
|
4497
|
+
break;
|
|
4144
4498
|
case 'mv':
|
|
4145
4499
|
await cmdMv(args[1], args[2]);
|
|
4146
4500
|
break;
|
|
4147
4501
|
case 'diagnose':
|
|
4148
4502
|
await cmdDiagnose();
|
|
4149
4503
|
break;
|
|
4504
|
+
case 'net': {
|
|
4505
|
+
const { cmdNet } = await import('./net-check.js');
|
|
4506
|
+
await cmdNet(args.slice(1));
|
|
4507
|
+
break;
|
|
4508
|
+
}
|
|
4150
4509
|
case 'ctl':
|
|
4151
4510
|
await cmdCtl(args.slice(1));
|
|
4152
4511
|
break;
|
|
@@ -4183,8 +4542,20 @@ export async function main(args) {
|
|
|
4183
4542
|
await cmdGroup(args.slice(1));
|
|
4184
4543
|
break;
|
|
4185
4544
|
}
|
|
4545
|
+
case 'bench': {
|
|
4546
|
+
const { suppressSdkLogs } = await import('../aun/aid/index.js');
|
|
4547
|
+
suppressSdkLogs();
|
|
4548
|
+
const { cmdBench } = await import('./bench.js');
|
|
4549
|
+
await cmdBench(args.slice(1));
|
|
4550
|
+
break;
|
|
4551
|
+
}
|
|
4552
|
+
case 'link-rules': {
|
|
4553
|
+
const { cmdLinkRules } = await import('./link-rules.js');
|
|
4554
|
+
cmdLinkRules(args.slice(1));
|
|
4555
|
+
break;
|
|
4556
|
+
}
|
|
4186
4557
|
default:
|
|
4187
|
-
console.log(`Usage: evolclaw {init|start|stop|restart|status|logs|watch|ctl|diagnose|mv}
|
|
4558
|
+
console.log(`Usage: evolclaw {init|start|stop|restart|status|logs|watch|ctl|diagnose|net|mv}
|
|
4188
4559
|
|
|
4189
4560
|
Commands:
|
|
4190
4561
|
init 初始化 evolclaw home (${resolvePaths().defaultsConfig})
|
|
@@ -4202,8 +4573,10 @@ Commands:
|
|
|
4202
4573
|
--level error|warn 只显示指定级别及以上
|
|
4203
4574
|
--module <name> 只显示指定模块(如 feishu、AgentRunner)
|
|
4204
4575
|
--raw 原始输出,不着色
|
|
4205
|
-
watch
|
|
4576
|
+
watch 监控面板选择菜单(↑↓ 选择 log/aid/msg)
|
|
4577
|
+
watch log 监控 logs/ 下所有 .log 文件(汇总实时输出,启动时显示最近 20 条)
|
|
4206
4578
|
watch aid AID 连接状态实时监控(显示各 AID 在线/离线/重连状态)
|
|
4579
|
+
watch msg 消息监控(三面板交互式 TUI:AID 列表 / 对端统计 / 消息流)
|
|
4207
4580
|
ctl 运行时自管理(模型切换、推理强度、压缩上下文等)
|
|
4208
4581
|
evolclaw ctl help 查看完整命令列表
|
|
4209
4582
|
agent 管理 EvolAgent
|
|
@@ -4228,6 +4601,9 @@ Commands:
|
|
|
4228
4601
|
aid lookup <aid> 远程探测 AID(是否存在 + 网关 + agent.md)
|
|
4229
4602
|
aid agentmd put <aid> 签名并上传 agent.md
|
|
4230
4603
|
aid agentmd get <aid> 下载并验签 agent.md
|
|
4604
|
+
net 网络链路诊断
|
|
4605
|
+
net check [<aid>] 10 步链路检测(DNS→Discovery→TCP→TLS→WSS→Auth→Ping→Echo)
|
|
4606
|
+
net help 查看详细帮助
|
|
4231
4607
|
rpc AUN RPC 调用
|
|
4232
4608
|
rpc --as <aid> --params <json|jsonl|file>
|
|
4233
4609
|
storage 文件存储
|
|
@@ -4238,6 +4614,8 @@ Commands:
|
|
|
4238
4614
|
storage quota <aid>
|
|
4239
4615
|
diagnose 诊断启动环境(配置、数据库、进程)
|
|
4240
4616
|
mv <old> <new> 迁移项目目录(保留 Claude/Codex/EvolClaw 会话)
|
|
4617
|
+
bench AUN 消息性能基准测试
|
|
4618
|
+
bench --aids 5 --rounds 10 --concurrency 5
|
|
4241
4619
|
|
|
4242
4620
|
Environment:
|
|
4243
4621
|
EVOLCLAW_HOME 数据目录 (默认: ~/.evolclaw)
|