evolcore 0.0.2 → 0.0.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/CHANGELOG.md +93 -778
- package/README.md +45 -10
- package/bin/ec-safe-output.js +89 -24
- package/dist/agents/baseagent.js +46 -0
- package/dist/agents/claude-runner.js +198 -48
- package/dist/agents/codex-app-server-client.js +68 -0
- package/dist/agents/codex-runner.js +203 -8
- package/dist/agents/runner-types.js +2 -2
- package/dist/aun/aid/agentmd.js +79 -0
- package/dist/aun/aid/encryption-seed-policy.js +29 -0
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/store.js +2 -5
- package/dist/aun/outbox.js +8 -0
- package/dist/channels/aun.js +241 -116
- package/dist/channels/daemon.js +18 -4
- package/dist/channels/dingtalk.js +1005 -260
- package/dist/channels/feishu.js +184 -56
- package/dist/channels/qqbot.js +23 -1
- package/dist/channels/wechat.js +303 -155
- package/dist/channels/wecom.js +1132 -164
- package/dist/cli/agent-command.js +2 -1
- package/dist/cli/aun-commands.js +98 -43
- package/dist/cli/bench.js +2 -2
- package/dist/cli/contact.js +71 -0
- package/dist/cli/ctl-command.js +2 -2
- package/dist/cli/daemon-commands.js +77 -214
- package/dist/cli/handoff-command.js +4 -3
- package/dist/cli/help.js +9 -5
- package/dist/cli/index.js +132 -116
- package/dist/cli/init-channel.js +242 -129
- package/dist/cli/init.js +70 -31
- package/dist/cli/model.js +2 -1
- package/dist/cli/net-check.js +2 -2
- package/dist/cli/queue-command.js +30 -6
- package/dist/cli/raw-key-input.js +25 -0
- package/dist/cli/response.js +5 -6
- package/dist/cli/restart-monitor.js +25 -1
- package/dist/cli/stats.js +6 -4
- package/dist/cli/trigger-command.js +146 -25
- package/dist/cli/version.js +6 -1
- package/dist/config/access-policy-domain.js +38 -0
- package/dist/config/access-policy.js +134 -0
- package/dist/config/builtin-role-templates.js +42 -17
- package/dist/config/builtin-roles.js +31 -6
- package/dist/config/config-field-policy.js +17 -5
- package/dist/config/config-manager.js +409 -29
- package/dist/config/config-operation-service.js +35 -38
- package/dist/config/contact-alias.js +68 -0
- package/dist/config/contact-bind-code.js +274 -0
- package/dist/config/contact-book-store.js +622 -0
- package/dist/config/contact-book-v2-startup.js +35 -0
- package/dist/config/contact-book.js +185 -300
- package/dist/config/contact-operation-service.js +116 -0
- package/dist/config/contact-request-service.js +331 -0
- package/dist/config/peer-role-resolver.js +136 -55
- package/dist/config/role-ranks.js +18 -0
- package/dist/config/role-service.js +16 -19
- package/dist/config/role-store.js +16 -5
- package/dist/config/roles.js +10 -1
- package/dist/config/schema-registry.js +49 -24
- package/dist/config-store.js +14 -4
- package/dist/core/auth/agent-delegation.js +105 -11
- package/dist/core/auth/authorization-audit.js +16 -1
- package/dist/core/auth/operation-authorizer.js +10 -0
- package/dist/core/auth/operation-catalog.js +105 -1
- package/dist/core/auth/trigger-authorization.js +15 -0
- package/dist/core/bootstrap-service.js +2 -9
- package/dist/core/channel-loader.js +6 -2
- package/dist/core/command/command-handler.js +113 -21
- package/dist/core/command/connect-menu.js +599 -0
- package/dist/core/command/evol-menu-version-gate.js +38 -0
- package/dist/core/command/group-menu.js +421 -0
- package/dist/core/command/menu-handler.js +382 -100
- package/dist/core/command/menu-protocol.js +8 -2
- package/dist/core/command/menu-token-store.js +102 -0
- package/dist/core/command/role-menu.js +128 -29
- package/dist/core/command/slash-gate.js +1 -1
- package/dist/core/command/slash-handler.js +186 -49
- package/dist/core/daemon-file-cache.js +40 -6
- package/dist/core/event-catalog.js +99 -0
- package/dist/core/evolagent-registry.js +4 -40
- package/dist/core/evolagent.js +20 -9
- package/dist/core/handoff/runtime.js +162 -37
- package/dist/core/handoff/store.js +46 -2
- package/dist/core/handoff/types.js +1 -0
- package/dist/core/inference/text-inference.js +16 -74
- package/dist/core/message/file-markers.js +7 -0
- package/dist/core/message/im-renderer.js +20 -14
- package/dist/core/message/inbound-admission.js +124 -0
- package/dist/core/message/message-bridge.js +670 -57
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +195 -10
- package/dist/core/message/message-utils.js +8 -2
- package/dist/core/message/peer-mode.js +7 -8
- package/dist/core/message/response-engine.js +642 -96
- package/dist/core/message/send-receipt.js +24 -0
- package/dist/core/message/stream-debouncer.js +11 -2
- package/dist/core/permission/approval-gateway.js +17 -10
- package/dist/core/permission/ec-command-parser.js +101 -46
- package/dist/core/permission/tool-policy.js +115 -38
- package/dist/core/protected-paths.js +38 -11
- package/dist/core/session/session-fs-store.js +44 -3
- package/dist/core/session/session-manager.js +86 -8
- package/dist/core/session/session-mapper.js +2 -0
- package/dist/core/session/session-renew.js +125 -69
- package/dist/core/session/session-turn-coordinator.js +5 -1
- package/dist/eck/kit-renderer.js +12 -1
- package/dist/eck/message-renderer.js +79 -1
- package/dist/index.js +285 -94
- package/dist/ipc.js +114 -8
- package/dist/paths.js +3 -0
- package/dist/response-system/config-resolver.js +29 -0
- package/dist/response-system/coordinator.js +8 -32
- package/dist/response-system/engines/v1/proactive-flow.js +1 -1
- package/dist/response-system/index.js +1 -0
- package/dist/response-system/modes/single-session/index.js +7 -4
- package/dist/stats/billing.js +20 -8
- package/dist/trigger/manager.js +3 -0
- package/dist/trigger/parser.js +126 -11
- package/dist/trigger/patch.js +12 -2
- package/dist/trigger/scheduler.js +444 -40
- package/dist/trigger/validation.js +13 -0
- package/dist/utils/aid-bind.js +43 -29
- package/dist/utils/error-dict.json +7 -0
- package/dist/utils/evolcore-version.js +21 -0
- package/dist/utils/instance-registry.js +14 -7
- package/dist/utils/log-writer.js +46 -0
- package/dist/utils/logger.js +2 -2
- package/dist/utils/media-cache.js +4 -1
- package/dist/utils/model-prices.jsonl +6 -3
- package/dist/utils/restart-safety.js +31 -0
- package/dist/utils/stable-semver.js +21 -0
- package/dist/utils/stats.js +33 -9
- package/dist/utils/system-memory.js +62 -0
- package/kits/docs/INDEX.md +2 -1
- package/kits/docs/channels/aun.md +4 -13
- package/kits/docs/evolcore/INDEX.md +5 -3
- package/kits/docs/evolcore/agent.md +9 -1
- package/kits/docs/evolcore/aid.md +5 -2
- package/kits/docs/evolcore/config.md +47 -2
- package/kits/docs/evolcore/contact.md +61 -0
- package/kits/docs/evolcore/fs.md +9 -0
- package/kits/docs/evolcore/group-rules.md +46 -4
- package/kits/docs/evolcore/group.md +15 -6
- package/kits/docs/evolcore/model.md +4 -1
- package/kits/docs/evolcore/msg.md +12 -6
- package/kits/docs/evolcore/response.md +16 -21
- package/kits/docs/evolcore/rpc.md +2 -0
- package/kits/docs/evolcore/stats.md +15 -2
- package/kits/docs/evolcore/storage.md +1 -0
- package/kits/docs/evolcore/trigger.md +42 -10
- package/kits/docs/path-registry.md +36 -17
- package/kits/eck_manifest.json +12 -0
- package/kits/eck_message_manifest.json +12 -1
- package/kits/migrations/migrate-contact-book-v2.mjs +754 -0
- package/kits/rules/01-overview.md +17 -7
- package/kits/rules/02-navigation.md +38 -18
- package/kits/rules/03-identity.md +28 -24
- package/kits/rules/04-relation.md +44 -28
- package/kits/rules/05-venue.md +31 -15
- package/kits/rules/06-channel.md +11 -7
- package/kits/schemas/_meta.json +21 -7
- package/kits/schemas/agent-config.schema.6.json +322 -0
- package/kits/schemas/agent-config.schema.7.json +303 -0
- package/kits/schemas/agent-config.schema.8.json +304 -0
- package/kits/schemas/agent-config.schema.9.json +374 -0
- package/kits/schemas/contact-book.schema.2.json +43 -0
- package/kits/schemas/contact-book.schema.3.json +67 -0
- package/kits/schemas/daemon.schema.1.json +3 -2
- package/kits/schemas/daemon.schema.2.json +101 -0
- package/kits/schemas/daemon.schema.3.json +123 -0
- package/kits/schemas/defaults.schema.2.json +85 -0
- package/kits/schemas/defaults.schema.3.json +73 -0
- package/kits/schemas/relation-config.schema.5.json +47 -0
- package/kits/schemas/relation-config.schema.6.json +46 -0
- package/kits/schemas/relation-config.schema.7.json +59 -0
- package/kits/schemas/role-config.schema.1.json +1 -0
- package/kits/schemas/role-registry.schema.1.json +2 -2
- package/kits/schemas/single-session.schema.2.json +57 -0
- package/kits/templates/message-fragments/handoff-context-to-target.md +9 -0
- package/kits/templates/message-fragments/handoff-request-to-target.md +14 -8
- package/kits/templates/message-fragments/handoff-response-to-origin.md +5 -6
- package/kits/templates/roles/admin.json +47 -0
- package/kits/templates/roles/member.json +5 -0
- package/kits/templates/roles/owner.json +1 -0
- package/kits/templates/roles/visitor.json +5 -0
- package/kits/templates/system-fragments/channel.md +12 -2
- package/kits/templates/system-fragments/commands.md +3 -1
- package/kits/templates/system-fragments/identity.md +3 -1
- package/kits/templates/system-fragments/relation.md +1 -1
- package/kits/templates/system-fragments/session.md +6 -2
- package/package.json +7 -5
- package/MIGRATION-0.5.0.md +0 -378
- package/ROLE_ACCESS_CONTROL.md +0 -174
- package/assets/brand/evolcore/README.md +0 -19
- package/assets/brand/evolcore/evolcore-app-icon.png +0 -0
- package/assets/brand/evolcore/evolcore-app-icon.svg +0 -13
- package/assets/brand/evolcore/evolcore-brand-board.png +0 -0
- package/assets/brand/evolcore/evolcore-brand-board.svg +0 -126
- package/assets/brand/evolcore/evolcore-logo-kit.zip +0 -0
- package/assets/brand/evolcore/evolcore-logo-reverse.png +0 -0
- package/assets/brand/evolcore/evolcore-logo-reverse.svg +0 -14
- package/assets/brand/evolcore/evolcore-logo.png +0 -0
- package/assets/brand/evolcore/evolcore-logo.svg +0 -14
- package/assets/brand/evolcore/evolcore-mark.png +0 -0
- package/assets/brand/evolcore/evolcore-mark.svg +0 -10
package/dist/cli/init.js
CHANGED
|
@@ -64,27 +64,36 @@ export function parseOwnerAids(raw, isValid) {
|
|
|
64
64
|
function installErrorMessage(e) {
|
|
65
65
|
return String(e?.stderr || e?.message || e).trim();
|
|
66
66
|
}
|
|
67
|
-
async function ensureEcwebInstalledForInit() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
export async function ensureEcwebInstalledForInit(options = {}) {
|
|
68
|
+
const isInstalled = options.isInstalled ?? (() => commandExists(WEB_CLI_BIN));
|
|
69
|
+
if (isInstalled())
|
|
70
|
+
return { ok: true, installedNow: false };
|
|
71
|
+
if (!options.quiet)
|
|
72
|
+
console.log(` 📦 EC Web 组件未安装,正在安装 ${WEB_PACKAGE_LATEST}...`);
|
|
71
73
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
const install = options.install ?? (async (pkg) => {
|
|
75
|
+
const { npmInstallGlobal } = await import('../utils/npm-ops.js');
|
|
76
|
+
await npmInstallGlobal(pkg);
|
|
77
|
+
});
|
|
78
|
+
await install(WEB_PACKAGE_LATEST);
|
|
79
|
+
if (!options.quiet)
|
|
80
|
+
console.log(' ✓ EC Web 组件安装完成');
|
|
81
|
+
return { ok: true, installedNow: true };
|
|
76
82
|
}
|
|
77
83
|
catch (e) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
const error = installErrorMessage(e);
|
|
85
|
+
if (!options.quiet) {
|
|
86
|
+
console.log(` ⚠ EC Web 组件安装失败: ${error}`);
|
|
87
|
+
console.log(` 可稍后运行 ec watch web 自动安装并启动,或手动运行 npm install -g ${WEB_PACKAGE_LATEST}`);
|
|
88
|
+
}
|
|
89
|
+
return { ok: false, error };
|
|
81
90
|
}
|
|
82
91
|
}
|
|
83
92
|
// ==================== Main ====================
|
|
84
93
|
export async function cmdInit(options) {
|
|
85
94
|
// 云部署非交互式路径:当带 --owner 或 --format json 时走结构化分支,与交互式 tail 完全隔离。
|
|
86
95
|
// 预留方案 B:当 daemon 支持 Control Plane 无 agent 启动时,可在此分支跳过 agent new 预创建。
|
|
87
|
-
if (options?.nonInteractive && (options.owner || options.format === 'json')) {
|
|
96
|
+
if (options?.nonInteractive && (options.owner || options.format === 'json' || options.projectpath || options.ecweb)) {
|
|
88
97
|
return cmdInitNonInteractive({
|
|
89
98
|
owner: options.owner,
|
|
90
99
|
baseagent: options.baseagent,
|
|
@@ -339,16 +348,22 @@ export async function initTail() {
|
|
|
339
348
|
if (daemonConfigForEcweb.ecweb?.enabled === undefined) {
|
|
340
349
|
const ans = (await ask(rl, '\n是否在 ec start 时自动启动 ECWeb 控制台?[y/N] ')).trim().toLowerCase();
|
|
341
350
|
if (ans === 'y' || ans === 'yes') {
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
351
|
+
const installResult = await ensureEcwebInstalledForInit();
|
|
352
|
+
if (installResult.ok) {
|
|
353
|
+
const cfg = loadDaemonConfig();
|
|
354
|
+
saveDaemonConfig({ ...cfg, ecweb: { ...(cfg.ecweb ?? {}), enabled: true } });
|
|
355
|
+
console.log(' ✓ 已启用 ECWeb(ec start 将自动在后台启动)');
|
|
356
|
+
console.log(' 提示:首次访问运行 ec watch web 查看配对码和 URL');
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
const cfg = loadDaemonConfig();
|
|
360
|
+
saveDaemonConfig({ ...cfg, ecweb: { ...(cfg.ecweb ?? {}), enabled: false } });
|
|
361
|
+
console.log(' 提示:安装完成后运行 ec start;如需立即打开控制台,运行 ec watch web');
|
|
362
|
+
}
|
|
349
363
|
}
|
|
350
364
|
else {
|
|
351
|
-
|
|
365
|
+
const cfg = loadDaemonConfig();
|
|
366
|
+
saveDaemonConfig({ ...cfg, ecweb: { ...(cfg.ecweb ?? {}), enabled: false } });
|
|
352
367
|
console.log(' 已跳过(可日后运行 ec watch web 手动启动,或编辑 daemon.json)');
|
|
353
368
|
}
|
|
354
369
|
}
|
|
@@ -375,7 +390,7 @@ export async function initTail() {
|
|
|
375
390
|
* Present instance selection menu when existing instances are found.
|
|
376
391
|
* Returns the user's choice, or null if cancelled.
|
|
377
392
|
*/
|
|
378
|
-
export async function selectInstance(rl, channelType, instances) {
|
|
393
|
+
export async function selectInstance(rl, channelType, instances, options = {}) {
|
|
379
394
|
const typeLabel = channelType === 'feishu' ? '飞书' : channelType === 'wechat' ? '微信' : channelType === 'dingtalk' ? '钉钉' : channelType === 'qqbot' ? 'QQ机器人' : channelType === 'wecom' ? '企业微信' : channelType.toUpperCase();
|
|
380
395
|
console.log(`\n发现已有 ${typeLabel} 配置:`);
|
|
381
396
|
const letters = 'abcdefghijklmnopqrstuvwxyz';
|
|
@@ -412,10 +427,12 @@ export async function selectInstance(rl, channelType, instances) {
|
|
|
412
427
|
}
|
|
413
428
|
const target = instances[choiceIndex];
|
|
414
429
|
console.log(`\n已选择:${target.name}`);
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
430
|
+
if (options.confirmOverwrite !== false) {
|
|
431
|
+
const confirm = (await new Promise(r => rl.question(`⚠️ 即将覆盖该配置,确认?(y/N) `, r))).trim().toLowerCase();
|
|
432
|
+
if (confirm !== 'y' && confirm !== 'yes') {
|
|
433
|
+
console.log('已取消');
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
419
436
|
}
|
|
420
437
|
return { action: 'overwrite', index: choiceIndex, name: target.name };
|
|
421
438
|
}
|
|
@@ -436,10 +453,13 @@ function fail(code, message, exitCode, format) {
|
|
|
436
453
|
emitResult({ type: 'init.result', success: false, error: { code, message } }, format);
|
|
437
454
|
process.exit(exitCode);
|
|
438
455
|
}
|
|
439
|
-
export async function cmdInitNonInteractive(opts) {
|
|
456
|
+
export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
440
457
|
const format = opts.format;
|
|
441
458
|
const p = resolvePaths();
|
|
442
459
|
ensureDataDirs();
|
|
460
|
+
if (format !== undefined && format !== 'json') {
|
|
461
|
+
fail('INVALID_FORMAT', `--format only supports json: ${format}`, EXIT_USAGE, format);
|
|
462
|
+
}
|
|
443
463
|
// ── 1. owner 校验 ──
|
|
444
464
|
if (!opts.owner) {
|
|
445
465
|
fail('MISSING_OWNER', '--owner is required in non-interactive mode', EXIT_USAGE, format);
|
|
@@ -459,7 +479,7 @@ export async function cmdInitNonInteractive(opts) {
|
|
|
459
479
|
fail('DAEMON_RUNNING', `EvolCore daemon is running (PID: ${pids}); run 'ec stop' first`, EXIT_USAGE, format);
|
|
460
480
|
}
|
|
461
481
|
// ── 3. baseagent 探测 + 校验 ──
|
|
462
|
-
const available = detectAvailable();
|
|
482
|
+
const available = dependencies.availableBaseagents ?? detectAvailable();
|
|
463
483
|
if (available.length === 0) {
|
|
464
484
|
fail('BASEAGENT_UNAVAILABLE', 'no baseagent CLI detected (install claude/codex/gemini)', EXIT_USAGE, format);
|
|
465
485
|
}
|
|
@@ -503,14 +523,33 @@ export async function cmdInitNonInteractive(opts) {
|
|
|
503
523
|
}
|
|
504
524
|
const forced = differentOwner && !!opts.force;
|
|
505
525
|
const previousOwners = forced ? [...existingOwners] : undefined;
|
|
506
|
-
// ── 6.
|
|
526
|
+
// ── 6. EC Web 安装(先安装成功,再写 enabled 配置)──
|
|
527
|
+
if (opts.ecweb === true) {
|
|
528
|
+
const ensureEcweb = dependencies.ensureEcweb ?? (() => ensureEcwebInstalledForInit({ quiet: true }));
|
|
529
|
+
const installResult = await ensureEcweb();
|
|
530
|
+
if (!installResult.ok) {
|
|
531
|
+
if (existingCfg.ecweb?.enabled === true) {
|
|
532
|
+
try {
|
|
533
|
+
saveDaemonConfig({
|
|
534
|
+
...existingCfg,
|
|
535
|
+
ecweb: { ...(existingCfg.ecweb ?? {}), enabled: false },
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
catch (e) {
|
|
539
|
+
fail('ECWEB_INSTALL_FAILED', `failed to install ${WEB_PACKAGE_LATEST}: ${installResult.error}; failed to disable ecweb: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
fail('ECWEB_INSTALL_FAILED', `failed to install ${WEB_PACKAGE_LATEST}: ${installResult.error}`, EXIT_RUNTIME, format);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// ── 7. 写 defaults.json ──
|
|
507
546
|
try {
|
|
508
547
|
saveDefaultsSafe(buildDefaults(chosenBaseagent, available, projectsDefaultPath));
|
|
509
548
|
}
|
|
510
549
|
catch (e) {
|
|
511
550
|
fail('IO_ERROR', `failed to write defaults.json: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
512
551
|
}
|
|
513
|
-
// ──
|
|
552
|
+
// ── 8. 控制 AID:缺失则生成 ──
|
|
514
553
|
let controlAid = existingCfg.aid;
|
|
515
554
|
if (!controlAid) {
|
|
516
555
|
try {
|
|
@@ -521,7 +560,7 @@ export async function cmdInitNonInteractive(opts) {
|
|
|
521
560
|
fail('CONTROL_AID_CREATE_FAILED', `gateway unreachable: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
522
561
|
}
|
|
523
562
|
}
|
|
524
|
-
// ──
|
|
563
|
+
// ── 9. 写 daemon.json(aid + owners + ecweb)──
|
|
525
564
|
try {
|
|
526
565
|
const next = {
|
|
527
566
|
...existingCfg,
|
|
@@ -535,7 +574,7 @@ export async function cmdInitNonInteractive(opts) {
|
|
|
535
574
|
catch (e) {
|
|
536
575
|
fail('IO_ERROR', `failed to write daemon.json: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
537
576
|
}
|
|
538
|
-
// ──
|
|
577
|
+
// ── 10. 输出 init.result ──
|
|
539
578
|
const result = {
|
|
540
579
|
type: 'init.result',
|
|
541
580
|
success: true,
|
package/dist/cli/model.js
CHANGED
|
@@ -243,13 +243,14 @@ Commands:
|
|
|
243
243
|
check 诊断网关连通性与模型可用性(分阶段输出进度)
|
|
244
244
|
|
|
245
245
|
作用域(越具体越优先:关系 > 角色 > agent > defaults):
|
|
246
|
-
(无参数) 只读 catalog/defaults,不允许写入
|
|
246
|
+
(无参数) 本机 CLI 只读 catalog/defaults,不允许写入
|
|
247
247
|
--self <aid> agent级 → config.json
|
|
248
248
|
--self <aid> --role <role> 角色策略预览(只读)
|
|
249
249
|
--self <aid> --peer <X> 关系级 → relations/<peerKey>/config.json
|
|
250
250
|
|
|
251
251
|
修改 agent/关系作用域后,对应范围所有会话的下一条消息即时生效。
|
|
252
252
|
角色策略请通过角色策略编辑器修改。
|
|
253
|
+
托管会话内省略 --self/--peer/--role 时,命令作用于当前会话。
|
|
253
254
|
|
|
254
255
|
Options:
|
|
255
256
|
--self <aid> 本端 AID
|
package/dist/cli/net-check.js
CHANGED
|
@@ -10,7 +10,7 @@ import { WebSocket } from 'ws';
|
|
|
10
10
|
import { aunPath as defaultAunPath } from '../paths.js';
|
|
11
11
|
import { isHostChinese } from '../utils/locale.js';
|
|
12
12
|
import { getAidStore, loadClient, SLOT } from '../aun/aid/store.js';
|
|
13
|
-
import { isHelpFlag } from './help.js';
|
|
13
|
+
import { isHelpFlag, wantsHelp } from './help.js';
|
|
14
14
|
const GREEN = '\x1b[32m';
|
|
15
15
|
const RED = '\x1b[31m';
|
|
16
16
|
const YELLOW = '\x1b[33m';
|
|
@@ -645,7 +645,7 @@ export async function cmdNet(args) {
|
|
|
645
645
|
const sub = args[0];
|
|
646
646
|
const formatJson = args.includes('--format') && args.includes('json');
|
|
647
647
|
const kickTest = args.includes('--kick-test');
|
|
648
|
-
if (isHelpFlag(sub)) {
|
|
648
|
+
if (isHelpFlag(sub) || wantsHelp(args)) {
|
|
649
649
|
console.log(`用法: ec net check [<aid>] [--format json] [--kick-test]
|
|
650
650
|
|
|
651
651
|
检查 AUN 网络链路连通性(11 步逐层诊断)。
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { resolvePaths } from '../paths.js';
|
|
2
2
|
import { ipcQuery } from '../ipc.js';
|
|
3
|
-
import { isHelpFlag } from './help.js';
|
|
3
|
+
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
4
4
|
export async function cmdQueue(args) {
|
|
5
|
-
if (args.length === 0 || isHelpFlag(args[0])) {
|
|
5
|
+
if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
|
|
6
6
|
console.log(`用法: ec queue --agent <aid> [选项]
|
|
7
7
|
|
|
8
8
|
查询与操作 EvolAgent 的消息队列。
|
|
@@ -24,7 +24,7 @@ export async function cmdQueue(args) {
|
|
|
24
24
|
ec queue --agent mybot.agentid.pub --clear
|
|
25
25
|
ec queue --agent mybot.agentid.pub --cancel msg_d4e5f6
|
|
26
26
|
ec queue --agent mybot.agentid.pub --interrupt --sessionkey feishu#oc_abc123#main`);
|
|
27
|
-
|
|
27
|
+
return;
|
|
28
28
|
}
|
|
29
29
|
// 解析参数
|
|
30
30
|
const agentIdx = args.indexOf('--agent');
|
|
@@ -33,15 +33,39 @@ export async function cmdQueue(args) {
|
|
|
33
33
|
process.exit(1);
|
|
34
34
|
}
|
|
35
35
|
const agent = args[agentIdx + 1];
|
|
36
|
+
if (agent.startsWith('--')) {
|
|
37
|
+
console.error('❌ --agent 缺少 <aid> 参数');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
36
40
|
const showId = args.includes('--showid');
|
|
37
41
|
const full = args.includes('--full');
|
|
38
|
-
const
|
|
42
|
+
const formatValue = getArgValue(args, '--format');
|
|
43
|
+
if (formatValue !== undefined && formatValue !== 'json') {
|
|
44
|
+
console.error(`❌ --format 仅支持 json: ${formatValue}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const formatJson = formatValue === 'json';
|
|
39
48
|
const clear = args.includes('--clear');
|
|
40
49
|
const cancelIdx = args.indexOf('--cancel');
|
|
41
|
-
const
|
|
50
|
+
const cancelCandidate = cancelIdx >= 0 && cancelIdx + 1 < args.length ? args[cancelIdx + 1] : undefined;
|
|
51
|
+
const cancelMsgId = cancelCandidate && !cancelCandidate.startsWith('--') ? cancelCandidate : undefined;
|
|
42
52
|
const interrupt = args.includes('--interrupt');
|
|
43
53
|
const sessionKeyIdx = args.indexOf('--sessionkey');
|
|
44
|
-
const
|
|
54
|
+
const sessionCandidate = sessionKeyIdx >= 0 && sessionKeyIdx + 1 < args.length ? args[sessionKeyIdx + 1] : undefined;
|
|
55
|
+
const sessionKey = sessionCandidate && !sessionCandidate.startsWith('--') ? sessionCandidate : undefined;
|
|
56
|
+
const actionCount = [clear, cancelIdx >= 0, interrupt].filter(Boolean).length;
|
|
57
|
+
if (actionCount > 1) {
|
|
58
|
+
console.error('❌ --clear、--cancel、--interrupt 互斥,只能指定一个');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
if (cancelIdx >= 0 && !cancelMsgId) {
|
|
62
|
+
console.error('❌ --cancel 缺少 <messageId>');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (interrupt && !sessionKey) {
|
|
66
|
+
console.error('❌ --interrupt 必须配合 --sessionkey <key>');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
45
69
|
// 构建 IPC 请求
|
|
46
70
|
const action = clear ? 'clear'
|
|
47
71
|
: cancelMsgId ? 'cancel'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Temporarily listen for single-key input and restore stdin's previous state.
|
|
3
|
+
*
|
|
4
|
+
* Standalone init commands enter this flow after closing readline, so stdin is
|
|
5
|
+
* paused and must be paused again during cleanup or Node will stay alive. Some
|
|
6
|
+
* parent wizards keep readline active, so an already-flowing stdin must remain
|
|
7
|
+
* flowing for their next prompt.
|
|
8
|
+
*/
|
|
9
|
+
export function setupRawKeyListener(onKey, input = process.stdin) {
|
|
10
|
+
if (!input.isTTY)
|
|
11
|
+
return () => { };
|
|
12
|
+
const wasPaused = input.isPaused();
|
|
13
|
+
const wasRaw = Boolean(input.isRaw);
|
|
14
|
+
input.setRawMode(true);
|
|
15
|
+
input.resume();
|
|
16
|
+
input.setEncoding('utf8');
|
|
17
|
+
const handler = (chunk) => onKey(String(chunk));
|
|
18
|
+
input.on('data', handler);
|
|
19
|
+
return () => {
|
|
20
|
+
input.removeListener('data', handler);
|
|
21
|
+
input.setRawMode(wasRaw);
|
|
22
|
+
if (wasPaused)
|
|
23
|
+
input.pause();
|
|
24
|
+
};
|
|
25
|
+
}
|
package/dist/cli/response.js
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 查看/切换/配置会话的响应模式。作用域由 --self/--peer 决定。
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* (无) → 全局 defaults.json
|
|
6
|
+
* 读取解析链(越具体越优先:关系 > agent > defaults):
|
|
8
7
|
* --self → agent config.json
|
|
9
8
|
* --self --peer → 关系 relations/<peerKey>/config.json
|
|
10
9
|
*
|
|
@@ -149,11 +148,11 @@ Options:
|
|
|
149
148
|
示例:
|
|
150
149
|
ec response list
|
|
151
150
|
ec response current --self bot.agentid.pub
|
|
152
|
-
ec response info
|
|
151
|
+
ec response info single-session
|
|
153
152
|
ec response set single-session --self bot.agentid.pub
|
|
154
|
-
ec response set
|
|
155
|
-
ec response config
|
|
156
|
-
ec response config set
|
|
153
|
+
ec response set single-session --self bot.agentid.pub --peer aun#team.group.com
|
|
154
|
+
ec response config single-session --self bot.agentid.pub
|
|
155
|
+
ec response config set tool_use_reminder false --mode single-session --self bot.agentid.pub
|
|
157
156
|
ec response reset --self bot.agentid.pub --peer alice.agentid.pub`;
|
|
158
157
|
// ── list ────────────────────────────────────────────────────────────────
|
|
159
158
|
function cmdList(args, formatJson) {
|
|
@@ -10,8 +10,10 @@ import { tryUpgrade, tryUpgradeAunSdk, tryUpgradeGlobalPkg, resolveGlobalPkg } f
|
|
|
10
10
|
import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
|
|
11
11
|
import { isValidAid } from '../aun/aid/index.js';
|
|
12
12
|
import { msgSend } from '../aun/msg/index.js';
|
|
13
|
-
import { scanInstances, cleanupInstances, writeRestartMonitor, removeRestartMonitor, isRestartMonitorWinner } from '../utils/instance-registry.js';
|
|
13
|
+
import { scanInstances, cleanupInstances, writeRestartMonitor, removeRestartMonitor, isRestartMonitorWinner, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
|
|
14
14
|
import { WEB_PACKAGE_NAME } from '../product.js';
|
|
15
|
+
import { shouldSuppressRealRestart } from '../utils/restart-safety.js';
|
|
16
|
+
import { rotateStdoutLog } from '../utils/log-writer.js';
|
|
15
17
|
const execFileAsync = promisify(execFile);
|
|
16
18
|
// 清理 Claude Code 环境变量,防止 SDK 认为是嵌套会话
|
|
17
19
|
function cleanEnv() {
|
|
@@ -24,6 +26,10 @@ function cleanEnv() {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
export async function cmdRestartMonitor() {
|
|
29
|
+
// Defense in depth: a unit test that accidentally executes the real restart
|
|
30
|
+
// path must not detach a persistent daemon from the test worker.
|
|
31
|
+
if (shouldSuppressRealRestart())
|
|
32
|
+
return;
|
|
27
33
|
const p = resolvePaths();
|
|
28
34
|
const restartLog = path.join(p.logs, 'restart.log');
|
|
29
35
|
const MAX_HEAL_ATTEMPTS = 3;
|
|
@@ -66,6 +72,17 @@ export async function cmdRestartMonitor() {
|
|
|
66
72
|
return s.mains.some(m => m.alive);
|
|
67
73
|
};
|
|
68
74
|
log('Restart monitor started');
|
|
75
|
+
// Test daemons live in one temporary HOME per test, so the current HOME's
|
|
76
|
+
// instance registry cannot see them. Their strict environment markers make
|
|
77
|
+
// them safe to reap globally on every real restart.
|
|
78
|
+
{
|
|
79
|
+
const leakedTestDaemons = findOrphanProcesses().filter(o => o.confirmedTestDaemon);
|
|
80
|
+
if (leakedTestDaemons.length > 0) {
|
|
81
|
+
const killed = killOrphans(leakedTestDaemons);
|
|
82
|
+
log(`Cleaned ${killed.length} leaked test daemon(s): ${killed.join(', ')}`);
|
|
83
|
+
await sleep(500);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
69
86
|
// restart-pending.json 只留给新主进程发送发起会话内的“重启成功”回执。
|
|
70
87
|
const pendingFile = path.join(p.dataDir, 'restart-pending.json');
|
|
71
88
|
// 等待所有活 main 进程退出(可能不止一个)
|
|
@@ -271,6 +288,13 @@ async function spawnAndWaitReady(p, log, timeout) {
|
|
|
271
288
|
// 清理残留 instance 文件和进程
|
|
272
289
|
cleanupInstances();
|
|
273
290
|
cleanEnv();
|
|
291
|
+
const stdoutRotation = rotateStdoutLog(p.logs);
|
|
292
|
+
if (stdoutRotation.rotatedPath) {
|
|
293
|
+
log(`Rotated stdout.log -> ${path.basename(stdoutRotation.rotatedPath)}`);
|
|
294
|
+
}
|
|
295
|
+
if (stdoutRotation.removedArchives.length > 0) {
|
|
296
|
+
log(`Removed ${stdoutRotation.removedArchives.length} expired stdout archive(s)`);
|
|
297
|
+
}
|
|
274
298
|
const stdoutLog = path.join(p.logs, 'stdout.log');
|
|
275
299
|
const out = fs.openSync(stdoutLog, 'a');
|
|
276
300
|
const err = fs.openSync(stdoutLog, 'a');
|
package/dist/cli/stats.js
CHANGED
|
@@ -32,12 +32,14 @@ Usage: ec stats [options]
|
|
|
32
32
|
--context <id> 会话 context breakdown 细目
|
|
33
33
|
--budget 预算状态
|
|
34
34
|
--top-peers [--limit N] 对端排行
|
|
35
|
+
--top-models [--limit N] 模型排行
|
|
36
|
+
--traffic 消息收发条数与字节数
|
|
35
37
|
--sql "<query>" 直接执行只读 SQL
|
|
36
38
|
--rebuild 全量重建日聚合表 usage_daily(运维兜底/排查)
|
|
37
|
-
--peers [--limit N]
|
|
38
|
-
--groups [--limit N]
|
|
39
|
-
--summary
|
|
40
|
-
--peer-detail <id>
|
|
39
|
+
--peers [--limit N] 私聊对端列表(带累计 token/calls/活跃日)
|
|
40
|
+
--groups [--limit N] 群聊列表(同上)
|
|
41
|
+
--summary 指定时间范围总消耗汇总(token/USD/CNY)
|
|
42
|
+
--peer-detail <id> 指定对端 AID 或 peer_key,按天返回消耗明细
|
|
41
43
|
--task-calls <taskId> 一个 task 的逐次大模型调用明细
|
|
42
44
|
--session-calls <id> 一个会话的逐次大模型调用明细
|
|
43
45
|
|