evolcore 0.0.27 → 0.0.29-test.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -15
- package/bin/ec-safe-output.js +270 -54
- package/dist/agents/baseagent-availability.js +37 -1
- package/dist/agents/baseagent.js +29 -14
- package/dist/agents/claude-runner.js +171 -13
- package/dist/agents/codex/app-server-client.js +13 -2
- package/dist/agents/codex/catalog.js +7 -1
- package/dist/agents/codex/diagnostics.js +4 -3
- package/dist/agents/codex-runner.js +444 -106
- package/dist/agents/gemini-runner.js +35 -17
- package/dist/aun/group/history.js +130 -90
- package/dist/aun/group/operations.js +1 -3
- package/dist/aun/menu/client.js +1 -0
- package/dist/aun/menu/transport.js +5 -3
- package/dist/aun/msg/managed-operation.js +70 -0
- package/dist/aun/msg/p2p.js +1 -3
- package/dist/aun/msg/upload.js +2 -2
- package/dist/aun/outbox.js +1 -37
- package/dist/channels/aun.js +262 -86
- package/dist/channels/daemon.js +18 -1
- package/dist/channels/feishu.js +1 -2
- package/dist/cli/agent-command.js +23 -3
- package/dist/cli/agent-create.js +68 -2
- package/dist/cli/agent.js +12 -2
- package/dist/cli/aun-commands.js +87 -13
- package/dist/cli/cli-argv.js +26 -0
- package/dist/cli/daemon-commands.js +116 -149
- package/dist/cli/data-command.js +4 -4
- package/dist/cli/diag.js +1 -1
- package/dist/cli/handoff-command.js +2 -0
- package/dist/cli/index.js +18 -1
- package/dist/cli/managed-command-guard.js +10 -0
- package/dist/cli/memory-command.js +441 -0
- package/dist/cli/menu-client.js +4 -0
- package/dist/cli/restart-monitor.js +127 -23
- package/dist/cli/skill-command.js +41 -0
- package/dist/cli/task-context.js +2 -23
- package/dist/cli/trigger-command.js +9 -1
- package/dist/cli/watch-msg-diag.js +209 -0
- package/dist/config/config-field-policy.js +52 -3
- package/dist/config/config-manager.js +17 -4
- package/dist/config/contact-book-store.js +2 -2
- package/dist/config/mention-mode.js +7 -2
- package/dist/config/merge.js +28 -9
- package/dist/config/resolved-config-op.js +1 -1
- package/dist/config/runtime-env.js +137 -0
- package/dist/config/schema-registry.js +11 -1
- package/dist/config-store.js +10 -10
- package/dist/core/audit/event-key.js +3 -1
- package/dist/core/audit/log-integrity.js +4 -0
- package/dist/core/auth/agent-delegation.js +2 -1
- package/dist/core/auth/auth-gateway.js +13 -6
- package/dist/core/auth/authorization-audit.js +54 -19
- package/dist/core/auth/operation-authorizer.js +17 -0
- package/dist/core/auth/operation-catalog.js +9 -0
- package/dist/core/causation/context.js +5 -1
- package/dist/core/command/agent-control.js +1 -2
- package/dist/core/command/command-handler.js +80 -24
- package/dist/core/command/diag-service.js +292 -27
- package/dist/core/command/memory-slash.js +270 -0
- package/dist/core/command/menu-catalog.js +1 -0
- package/dist/core/command/menu-handler.js +331 -79
- package/dist/core/command/menu-protocol.js +45 -4
- package/dist/core/command/slash-gate.js +10 -10
- package/dist/core/command/slash-handler.js +230 -79
- package/dist/core/data-migration.js +282 -505
- package/dist/core/event-catalog.js +26 -0
- package/dist/core/evolagent-registry.js +6 -0
- package/dist/core/evolagent.js +0 -10
- package/dist/core/handoff/store.js +1 -20
- package/dist/core/inference/text-inference.js +57 -1
- package/dist/core/memory/consolidation-context.js +505 -0
- package/dist/core/memory/consolidation-ops-records.js +124 -0
- package/dist/core/memory/consolidation-trigger.js +394 -0
- package/dist/core/memory/index-manager.js +308 -0
- package/dist/core/memory/launch-consolidation.js +395 -0
- package/dist/core/memory/memory-admin.js +234 -0
- package/dist/core/memory/memory-document.js +100 -0
- package/dist/core/memory/memory-session-policy.js +41 -0
- package/dist/core/memory/memory-signature.js +257 -0
- package/dist/core/memory/memory-writer.js +432 -0
- package/dist/core/memory/staleness.js +117 -0
- package/dist/core/message/auto-mention-gate.js +454 -0
- package/dist/core/message/im-renderer.js +90 -20
- package/dist/core/message/message-bridge.js +333 -23
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/message-queue.js +114 -27
- package/dist/core/message/pending-hints.js +329 -161
- package/dist/core/message/response-engine.js +596 -90
- package/dist/core/permission/ec-command-parser.js +1044 -87
- package/dist/core/permission/protected-paths.js +376 -126
- package/dist/core/permission/sandbox-runtime.js +40 -12
- package/dist/core/permission/tool-error-code.js +96 -13
- package/dist/core/permission/tool-policy.js +277 -24
- package/dist/core/role/runtime-policy.js +3 -7
- package/dist/core/session/{runner-task-history.js → runner-event-summary.js} +1 -1
- package/dist/core/session/session-fs-store.js +0 -76
- package/dist/core/session/session-idle-monitor.js +355 -0
- package/dist/core/session/session-manager.js +482 -17
- package/dist/core/session/session-mapper.js +33 -16
- package/dist/core/session/session-renew.js +217 -155
- package/dist/core/session/{session-turns.js → session-transcript.js} +35 -6
- package/dist/core/skill/global-watcher.js +282 -0
- package/dist/core/skill/index-generator.js +84 -0
- package/dist/core/skill/startup.js +73 -0
- package/dist/core/skill/switch-resolver.js +115 -0
- package/dist/core/task/task-activity-store.js +219 -0
- package/dist/eck/kit-renderer.js +30 -3
- package/dist/eck/manifest-engine.js +26 -4
- package/dist/index.js +722 -171
- package/dist/ipc.js +564 -2
- package/dist/paths.js +30 -9
- package/dist/product.js +1 -0
- package/dist/response-system/engines/v1/proactive-flow.js +116 -15
- package/dist/response-system/modes/single-session/index.js +3 -0
- package/dist/trigger/feedback.js +1 -0
- package/dist/trigger/manager.js +0 -10
- package/dist/trigger/scheduler.js +11 -0
- package/dist/trigger/validation.js +22 -0
- package/dist/utils/atomic-write.js +98 -0
- package/dist/utils/avatar-upload.js +59 -18
- package/dist/utils/cross-platform.js +87 -16
- package/dist/utils/error-dict.json +6 -3
- package/dist/utils/error-utils.js +27 -0
- package/dist/utils/logger.js +32 -10
- package/dist/utils/media-cache.js +84 -0
- package/dist/utils/msg-diag.js +97 -0
- package/dist/utils/npm-ops.js +119 -4
- package/dist/utils/package-version-info.js +244 -0
- package/dist/utils/welcome.js +37 -8
- package/dist/utils/windows-shell-trust.js +37 -0
- package/kits/docs/AUTHORING.md +314 -0
- package/kits/docs/GUIDE.md +2 -0
- package/kits/docs/INDEX.md +2 -0
- package/kits/docs/aun/CHEATSHEET.md +4 -0
- package/kits/docs/aun/SDK.md +60 -0
- package/kits/docs/channels/aun.md +8 -0
- package/kits/docs/context-assembly.md +10 -6
- package/kits/docs/evolcore/INDEX.md +17 -3
- package/kits/docs/evolcore/agent-create.md +24 -0
- package/kits/docs/evolcore/agent.md +5 -2
- package/kits/docs/evolcore/config.md +1 -1
- package/kits/docs/evolcore/ec-capabilities.md +364 -0
- package/kits/docs/evolcore/group.md +34 -18
- package/kits/docs/evolcore/memory-architecture.md +78 -0
- package/kits/docs/evolcore/memory-consolidation-batches.md +133 -0
- package/kits/docs/evolcore/memory-consolidation.md +263 -0
- package/kits/docs/evolcore/memory-tags.md +63 -0
- package/kits/docs/evolcore/memory.md +110 -0
- package/kits/docs/evolcore/menu-client.md +27 -11
- package/kits/{schemas → docs/evolcore}/menu-exec-schema-commands.md +12 -6
- package/kits/docs/evolcore/menu-protocol.md +213 -0
- package/kits/docs/evolcore/msg.md +2 -0
- package/kits/docs/evolcore/trigger.md +7 -5
- package/kits/docs/path-registry.md +6 -8
- package/kits/docs/prompt-loading-architecture.md +5 -3
- package/kits/docs/venues/group.md +5 -4
- package/kits/eck_manifest.json +294 -88
- package/kits/eck_manifest.memory.json +257 -0
- package/kits/rules/03-identity.md +8 -8
- package/kits/rules/05-venue.md +4 -2
- package/kits/rules/06-channel.md +1 -1
- package/kits/schemas/_meta.json +276 -47
- package/kits/schemas/agent-config.schema.12.json +38 -2
- package/kits/schemas/agent-config.schema.13.json +591 -0
- package/kits/schemas/daemon.schema.6.json +9 -9
- package/kits/schemas/defaults.schema.5.json +29 -0
- package/kits/schemas/relation-config.schema.8.json +14 -1
- package/kits/schemas/relation-config.schema.9.json +129 -0
- package/kits/schemas/role-config.schema.1.json +3 -3
- package/kits/skills/.switches.json +3 -0
- package/kits/skills/ec-skill/SKILL.md +217 -0
- package/kits/skills/ec-skill/scripts/cli.mjs +128 -0
- package/kits/skills/ec-skill/scripts/deps.mjs +107 -0
- package/kits/skills/ec-skill/scripts/frontmatter.mjs +104 -0
- package/kits/skills/ec-skill/scripts/skill.mjs +629 -0
- package/kits/skills/ec-skill/scripts/template/SKILL.md.tmpl +30 -0
- package/kits/templates/decision/auto-mention.md +25 -0
- package/kits/templates/decision/session-renew.md +22 -0
- package/kits/templates/memory-consolidation/forget.md +104 -0
- package/kits/templates/memory-consolidation/generalize.md +76 -0
- package/kits/templates/memory-consolidation/notes.md +133 -0
- package/kits/templates/memory-consolidation/profile.md +58 -0
- package/kits/templates/memory-consolidation/promote.md +72 -0
- package/kits/templates/memory-consolidation/workflow.md +75 -0
- package/kits/templates/system-fragments/bootstrap.md +14 -5
- package/kits/templates/system-fragments/commands.md +1 -0
- package/kits/templates/system-fragments/group-history.md +6 -0
- package/kits/templates/system-fragments/identity.md +0 -3
- package/kits/templates/system-fragments/memory.md +79 -0
- package/kits/templates/system-fragments/reply.md +1 -0
- package/kits/templates/system-fragments/venue.md +1 -1
- package/package.json +4 -6
- package/dist/trigger/legacy-session-history.js +0 -19
- package/kits/templates/system-fragments/group-unread-history.md +0 -7
|
@@ -9,22 +9,23 @@ import { loadDefaults, loadAllAgents, loadDaemonConfig, saveDaemonConfig } from
|
|
|
9
9
|
import { resolveEffective } from '../config/config-manager.js';
|
|
10
10
|
import { resolveAnthropicConfig } from '../agents/baseagent.js';
|
|
11
11
|
import { migrateProject } from '../config-store.js';
|
|
12
|
-
import { ipcQuery } from '../ipc.js';
|
|
12
|
+
import { ipcQuery, IpcTransportError } from '../ipc.js';
|
|
13
13
|
import { isHelpFlag } from './help.js';
|
|
14
14
|
import { cmdInit, needsControlAidInit, initTail } from './init.js';
|
|
15
15
|
import * as platform from '../utils/cross-platform.js';
|
|
16
16
|
import { EventBus } from '../core/event-bus.js';
|
|
17
|
-
import {
|
|
17
|
+
import { tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
|
|
18
|
+
import { ensureFreshPackageVersionInfo } from '../utils/package-version-info.js';
|
|
18
19
|
import { ecwebVersionRequirementError, resolveEcwebLaunchCommand, fetchRemotePairingCode } from '../utils/ecweb-utils.js';
|
|
19
20
|
import { isHostChinese } from '../utils/locale.js';
|
|
20
|
-
import { scanInstances, cleanupInstances, findOrphanProcesses
|
|
21
|
+
import { scanInstances, cleanupInstances, findOrphanProcesses } from '../utils/instance-registry.js';
|
|
21
22
|
import { filterLogFiles, deriveLogTypes, computePreChecked, validateLogTypes, shortLogName as shortLogNameLocal, isWatchLogFile } from './watch-logs.js';
|
|
22
23
|
import { displaySessionTitle } from '../core/session/session-title.js';
|
|
23
24
|
import { isNonAgentSessionChannel } from '../core/system-channels.js';
|
|
24
25
|
import { printCodeStats } from './code-stats.js';
|
|
25
26
|
import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
|
|
26
|
-
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
27
|
-
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
|
|
27
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
28
|
+
import { RUNTIME_HOME_ENV, WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
|
|
28
29
|
import { rotateStdoutLog } from '../utils/log-writer.js';
|
|
29
30
|
import { inspectDataMigrationRequirement } from '../core/data-migration.js';
|
|
30
31
|
import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
|
|
@@ -250,39 +251,54 @@ function runSourceBuild() {
|
|
|
250
251
|
});
|
|
251
252
|
});
|
|
252
253
|
}
|
|
253
|
-
/**
|
|
254
|
-
* Spawn the restart monitor and confirm it actually reached its own code.
|
|
255
|
-
*
|
|
256
|
-
* The daemon is already stopped at this point, so a monitor that dies on
|
|
257
|
-
* startup leaves nothing running and nobody watching — the exact silent
|
|
258
|
-
* failure this mechanism exists to prevent.
|
|
259
|
-
*/
|
|
260
|
-
async function spawnRestartMonitorAndConfirm(monitorEntry, reportLine) {
|
|
261
|
-
const result = await platform.launchMonitorAndConfirm([...monitorEntry.args, 'restart-monitor'], { EVOLCORE_HOME: resolvePaths().root, ...(monitorEntry.env ?? {}) }, pid => scanInstances().restartMonitors.some(m => m.alive && m.record.pid === pid), pid => scanInstances().restartMonitors.some(m => m.alive && m.record.pid !== pid));
|
|
262
|
-
if (result.ok)
|
|
263
|
-
return { ok: true };
|
|
264
|
-
for (const line of (result.stderrTail ?? '').split(/\r?\n/).filter(Boolean).slice(-8)) {
|
|
265
|
-
reportLine(` | ${line}`);
|
|
266
|
-
}
|
|
267
|
-
return { ok: false, reason: result.reason ?? 'unknown' };
|
|
268
|
-
}
|
|
269
254
|
async function requireFreshSourceBuild() {
|
|
270
255
|
if (!sourceBuildNeedsRefresh())
|
|
271
256
|
return true;
|
|
272
257
|
return await runSourceBuild();
|
|
273
258
|
}
|
|
274
|
-
function
|
|
259
|
+
async function launchPackageLifecycle(source, log, options = {}) {
|
|
260
|
+
if (!options.prepared)
|
|
261
|
+
await ensureFreshPackageVersionInfo(undefined, { source, log });
|
|
262
|
+
const root = resolvePaths().root;
|
|
263
|
+
const launch = platform.resolveMonitorLaunch(getPackageRoot(), path.join(root, 'data', 'monitor-stage'));
|
|
264
|
+
if (launch.note)
|
|
265
|
+
log(launch.note);
|
|
266
|
+
if (!fs.existsSync(launch.entry)) {
|
|
267
|
+
if (launch.stageDir)
|
|
268
|
+
platform.cleanupMonitorStage(launch.stageDir);
|
|
269
|
+
return { ok: false, reason: 'RESTART_ENTRY_MISSING' };
|
|
270
|
+
}
|
|
271
|
+
const args = [...launch.args, 'restart-monitor', ...(options.clear ? ['--clear'] : [])];
|
|
272
|
+
const env = { ...options.env, [RUNTIME_HOME_ENV]: root, ...launch.env, [AGENT_DELEGATION_TOKEN_ENV]: '' };
|
|
273
|
+
if (options.foreground) {
|
|
274
|
+
return new Promise(resolve => {
|
|
275
|
+
const child = spawn(process.execPath, [...args, '--foreground'], {
|
|
276
|
+
stdio: 'inherit', detached: false, windowsHide: true, env: { ...process.env, ...env },
|
|
277
|
+
});
|
|
278
|
+
child.once('error', () => {
|
|
279
|
+
if (launch.stageDir)
|
|
280
|
+
platform.cleanupMonitorStage(launch.stageDir);
|
|
281
|
+
resolve({ ok: false, reason: 'Foreground monitor could not start' });
|
|
282
|
+
});
|
|
283
|
+
child.once('exit', code => {
|
|
284
|
+
process.exitCode = code ?? 1;
|
|
285
|
+
resolve({ ok: code === 0, ...(code !== 0 ? { reason: 'Foreground lifecycle exited unsuccessfully' } : {}) });
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
const result = await platform.launchMonitorAndConfirm(args, env, pid => scanInstances().restartMonitors.some(item => item.alive && item.record.pid === pid), pid => scanInstances().restartMonitors.some(item => item.alive && item.record.pid !== pid));
|
|
290
|
+
if (!result.ok && launch.stageDir)
|
|
291
|
+
platform.cleanupMonitorStage(launch.stageDir);
|
|
292
|
+
return { ok: result.ok, ...(!result.ok ? { reason: result.reason } : {}) };
|
|
293
|
+
}
|
|
294
|
+
function requireCompletedDataMigration(root) {
|
|
275
295
|
const requirement = inspectDataMigrationRequirement(root);
|
|
276
296
|
if (!requirement.required)
|
|
277
297
|
return true;
|
|
278
|
-
console.error(
|
|
279
|
-
? `❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,本次不停止当前服务。`
|
|
280
|
-
: `❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,服务未启动。`);
|
|
298
|
+
console.error(`❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,服务未启动。`);
|
|
281
299
|
console.error(' 先执行: ec data migrate --dry-run');
|
|
282
300
|
console.error(' 确认后: ec data migrate --apply');
|
|
283
|
-
console.error(' 迁移成功并校验后,再执行 ec start
|
|
284
|
-
if (action === 'restart')
|
|
285
|
-
console.error(' 本次 ec restart 仅完成只读检查,未停止当前服务。');
|
|
301
|
+
console.error(' 迁移成功并校验后,再执行 ec start。');
|
|
286
302
|
process.exitCode = 2;
|
|
287
303
|
return false;
|
|
288
304
|
}
|
|
@@ -291,7 +307,11 @@ function requireCompletedDataMigration(root, action = 'start') {
|
|
|
291
307
|
* A failed upgrade is reported, but the currently installed version remains
|
|
292
308
|
* usable and the caller continues with its normal lifecycle.
|
|
293
309
|
*/
|
|
294
|
-
export async function runUpgradeChecks(upgradeFn
|
|
310
|
+
export async function runUpgradeChecks(upgradeFn, ecwebUpgradeFn, timeoutMs = 60_000) {
|
|
311
|
+
if (!upgradeFn || !ecwebUpgradeFn) {
|
|
312
|
+
await ensureFreshPackageVersionInfo(undefined, { source: 'start', log: console.log });
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
295
315
|
console.log('📦 Checking for updates...');
|
|
296
316
|
const runWithTimeout = async (label, fn) => {
|
|
297
317
|
const controller = new AbortController();
|
|
@@ -470,7 +490,9 @@ export async function cmdStart(opts = {}) {
|
|
|
470
490
|
return;
|
|
471
491
|
// A stopped container may miss the daily upgrade trigger. Check once on
|
|
472
492
|
// every real start so the service does not stay on an old installation.
|
|
473
|
-
await (
|
|
493
|
+
const versionInfo = await ensureFreshPackageVersionInfo(undefined, { source: 'start', log: console.log });
|
|
494
|
+
if (opts.upgradeChecks)
|
|
495
|
+
await opts.upgradeChecks();
|
|
474
496
|
// 旧配置自动迁移(daemon.json → 新结构)
|
|
475
497
|
const { autoMigrateIfNeeded } = await import('../config-store.js');
|
|
476
498
|
autoMigrateIfNeeded();
|
|
@@ -595,6 +617,20 @@ export async function cmdStart(opts = {}) {
|
|
|
595
617
|
return;
|
|
596
618
|
}
|
|
597
619
|
reportOrphans(orphans);
|
|
620
|
+
if (versionInfo.some(result => result.hasUpdate)) {
|
|
621
|
+
cleanEnv();
|
|
622
|
+
const launched = await launchPackageLifecycle('start', console.log, {
|
|
623
|
+
prepared: true, foreground: opts.foreground, env: buildDaemonEnv(p, opts),
|
|
624
|
+
});
|
|
625
|
+
if (!launched.ok) {
|
|
626
|
+
console.error(`❌ 启动事务未能建立:${launched.reason}`);
|
|
627
|
+
process.exitCode = 1;
|
|
628
|
+
}
|
|
629
|
+
else if (!opts.foreground) {
|
|
630
|
+
console.log('📦 已交由 restart-monitor 应用缓存版本并启动服务');
|
|
631
|
+
}
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
598
634
|
console.log('🚀 Starting EvolCore...');
|
|
599
635
|
const stdoutRotation = rotateStdoutLog(p.logs);
|
|
600
636
|
if (stdoutRotation.rotatedPath) {
|
|
@@ -883,126 +919,17 @@ export async function cmdRestart(opts = {}) {
|
|
|
883
919
|
if (initialRuntimeOrphans.length === 0 && rejectPidIsolatedLifecycle('restart', initialStatus, ping))
|
|
884
920
|
return;
|
|
885
921
|
}
|
|
886
|
-
//
|
|
887
|
-
//
|
|
888
|
-
// restart-monitor
|
|
889
|
-
//
|
|
890
|
-
|
|
891
|
-
if (!
|
|
892
|
-
|
|
893
|
-
// 停止所有活 main 进程(可能不止一个)
|
|
894
|
-
const status = initialStatus;
|
|
895
|
-
const aliveMains = status.mains.filter(m => m.alive);
|
|
896
|
-
if (aliveMains.length > 0) {
|
|
897
|
-
if (aliveMains.length > 1) {
|
|
898
|
-
console.log(`⚠ 检测到 ${aliveMains.length} 个 main 实例,将一并停止: ${aliveMains.map(m => m.record.pid).join(', ')}`);
|
|
899
|
-
}
|
|
900
|
-
const mainPids = new Set(aliveMains.map(entry => entry.record.pid));
|
|
901
|
-
const currentPing = await probeDaemon(socketPath);
|
|
902
|
-
const gracefulPid = currentPing && mainPids.has(currentPing.pid)
|
|
903
|
-
? await requestDaemonShutdown(socketPath, DAEMON_SHUTDOWN_TIMEOUT_MS, 'ec restart', mainPids)
|
|
904
|
-
: null;
|
|
905
|
-
const stopped = await Promise.all(aliveMains.map(m => stopPid(m.record.pid, m.record.pid === gracefulPid, m.record.startedAt)));
|
|
906
|
-
if (stopped.some(result => !result)) {
|
|
907
|
-
console.error('❌ Restart aborted because an existing EvolCore process could not be stopped');
|
|
908
|
-
process.exitCode = 1;
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
await sleep(500);
|
|
912
|
-
}
|
|
913
|
-
cleanupInstances();
|
|
914
|
-
const remainingMainProcesses = scanInstances().mains.filter(entry => entry.alive);
|
|
915
|
-
if (remainingMainProcesses.length > 0) {
|
|
916
|
-
console.error(`❌ Restart aborted: EvolCore process still registered and alive (PID: ${remainingMainProcesses.map(entry => entry.record.pid).join(', ')})`);
|
|
922
|
+
// The shared launchPackageLifecycle path delegates to launchMonitorAndConfirm;
|
|
923
|
+
// the monitor retains shutdown, orphan checks, build and rollback ownership.
|
|
924
|
+
// restart-monitor performs the read-only preflight before stopping the
|
|
925
|
+
// current daemon, then applies the migration during the stopped window.
|
|
926
|
+
const launched = await launchPackageLifecycle('restart', console.log, { clear: opts.clear });
|
|
927
|
+
if (!launched.ok) {
|
|
928
|
+
console.error(`❌ 重启中止:restart-monitor 未能启动(${launched.reason});当前服务未主动停止`);
|
|
917
929
|
process.exitCode = 1;
|
|
918
930
|
return;
|
|
919
931
|
}
|
|
920
|
-
|
|
921
|
-
// 跨 HOME 的孤儿只在 --clear 时 kill,否则仅警告。findOrphanProcesses
|
|
922
|
-
// 在 Windows 上需要一次 CIM 查询;保留一个快照,避免同一阶段重复扫描。
|
|
923
|
-
{
|
|
924
|
-
const orphans = findOrphanProcesses();
|
|
925
|
-
const confirmedTestDaemons = orphans.filter(o => o.confirmedTestDaemon);
|
|
926
|
-
if (confirmedTestDaemons.length > 0) {
|
|
927
|
-
const killed = killOrphans(confirmedTestDaemons);
|
|
928
|
-
console.log(`☠ 已清理 ${killed.length} 个泄漏的测试 daemon: ${killed.join(', ')}`);
|
|
929
|
-
await sleep(500);
|
|
930
|
-
}
|
|
931
|
-
const runtimeOrphans = orphans.filter(o => isRuntimeOrphan(o));
|
|
932
|
-
if (runtimeOrphans.length > 0) {
|
|
933
|
-
console.log(`⚠ 检测到未登记的 EvolCore 进程,将一并停止: ${runtimeOrphans.map(o => o.pid).join(', ')}`);
|
|
934
|
-
const orphanPids = new Set(runtimeOrphans.map(orphan => orphan.pid));
|
|
935
|
-
const currentPing = await probeDaemon(socketPath);
|
|
936
|
-
const gracefulPid = currentPing && orphanPids.has(currentPing.pid)
|
|
937
|
-
? await requestDaemonShutdown(socketPath, DAEMON_SHUTDOWN_TIMEOUT_MS, 'ec restart', orphanPids)
|
|
938
|
-
: null;
|
|
939
|
-
const stopped = await Promise.all(runtimeOrphans.map(o => stopPid(o.pid, o.pid === gracefulPid)));
|
|
940
|
-
if (stopped.some(result => !result)) {
|
|
941
|
-
console.error('❌ Restart aborted because an unregistered EvolCore process could not be stopped');
|
|
942
|
-
process.exitCode = 1;
|
|
943
|
-
return;
|
|
944
|
-
}
|
|
945
|
-
await sleep(500);
|
|
946
|
-
}
|
|
947
|
-
// stopPid() already waited for every runtime orphan above, so avoid a
|
|
948
|
-
// second scan before handling cross-HOME records.
|
|
949
|
-
const otherHome = orphans.filter(o => !o.confirmedTestDaemon && !isRuntimeOrphan(o));
|
|
950
|
-
if (opts.clear && otherHome.length > 0) {
|
|
951
|
-
const killed = killOrphans(otherHome);
|
|
952
|
-
console.log(`☠ 已 SIGKILL ${killed.length} 个跨 HOME 孤儿进程: ${killed.join(', ')}`);
|
|
953
|
-
await sleep(500);
|
|
954
|
-
}
|
|
955
|
-
else if (otherHome.length > 0) {
|
|
956
|
-
reportOrphans(otherHome);
|
|
957
|
-
}
|
|
958
|
-
// Keep the post-stop ownership guard: a process that appeared during the
|
|
959
|
-
// cleanup window must still block replacement.
|
|
960
|
-
const remainingRuntimeOrphans = findOrphanProcesses().filter(o => isRuntimeOrphan(o));
|
|
961
|
-
if (remainingRuntimeOrphans.length > 0) {
|
|
962
|
-
console.error(`❌ Restart aborted: EvolCore process still running (PID: ${remainingRuntimeOrphans.map(o => o.pid).join(', ')})`);
|
|
963
|
-
process.exitCode = 1;
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
// 只清理 EvolCore 自己登记的 codex app-server,不能影响桌面端实例。
|
|
968
|
-
{
|
|
969
|
-
const killed = stopCodexAppServerOrphans();
|
|
970
|
-
if (killed > 0) {
|
|
971
|
-
console.log(`☠ 已清理 ${killed} 个 EvolCore codex app-server 孤儿进程`);
|
|
972
|
-
await sleep(500);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
|
|
976
|
-
// 通过 restart-monitor 启动,避免在 agent 内调用时自杀。
|
|
977
|
-
// 开发仓下 monitor 从源码跑;安装包下先复制到 stage 目录,两种情况都让看门狗
|
|
978
|
-
// 不住在会被替换的产物里。
|
|
979
|
-
const monitorEntry = platform.resolveMonitorLaunch(getPackageRoot(), path.join(resolvePaths().root, 'data', 'monitor-stage'));
|
|
980
|
-
if (monitorEntry.note)
|
|
981
|
-
console.log(`ℹ ${monitorEntry.note}`);
|
|
982
|
-
if (!fs.existsSync(monitorEntry.entry)) {
|
|
983
|
-
console.error(`❌ 重启中止:找不到 restart-monitor 入口 ${monitorEntry.entry}`);
|
|
984
|
-
console.error(' 请先执行 npm run build 重建产物');
|
|
985
|
-
process.exitCode = 1;
|
|
986
|
-
return;
|
|
987
|
-
}
|
|
988
|
-
const monitorStarted = await spawnRestartMonitorAndConfirm(monitorEntry, log => console.error(log));
|
|
989
|
-
if (!monitorStarted.ok) {
|
|
990
|
-
if (monitorEntry.stageDir)
|
|
991
|
-
platform.cleanupMonitorStage(monitorEntry.stageDir);
|
|
992
|
-
console.error(`❌ 重启中止:restart-monitor 未能启动(${monitorStarted.reason})`);
|
|
993
|
-
if (fs.existsSync(path.join(getPackageRoot(), 'src', 'cli', 'index.ts'))) {
|
|
994
|
-
console.error(' 源码可能存在语法错误导致 tsx 无法加载。请执行 npx tsc --noEmit 检查。');
|
|
995
|
-
}
|
|
996
|
-
console.error(' 服务已停止,请修复后执行 ec start。');
|
|
997
|
-
process.exitCode = 1;
|
|
998
|
-
return;
|
|
999
|
-
}
|
|
1000
|
-
console.log('🔄 Restart monitor started; service is coming back online in the background...');
|
|
1001
|
-
// 代码统计(开发环境)
|
|
1002
|
-
if (path.normalize(resolveRoot()) === path.normalize(getPackageRoot())) {
|
|
1003
|
-
console.log('');
|
|
1004
|
-
printCodeStats(getPackageRoot(), resolvePaths().logs);
|
|
1005
|
-
}
|
|
932
|
+
console.log(`🔄 Restart monitor started (${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s); service is restarting...`);
|
|
1006
933
|
}
|
|
1007
934
|
function normalizeRuntimePath(value) {
|
|
1008
935
|
return value.replace(/[\\/]+/g, '/').toLowerCase();
|
|
@@ -1310,8 +1237,13 @@ export async function cmdStatus() {
|
|
|
1310
1237
|
console.log(' 请稍后再次执行 ec status。');
|
|
1311
1238
|
}
|
|
1312
1239
|
else {
|
|
1313
|
-
|
|
1314
|
-
|
|
1240
|
+
// With no live main/monitor, a missing Windows pipe is the normal stopped
|
|
1241
|
+
// state. Preserve uncertainty for permissions, timeouts, unknown errors,
|
|
1242
|
+
// and Unix callers that may be isolated from the daemon's PID namespace.
|
|
1243
|
+
const stopped = !ipcFailure || (platform.isWindows && ipcFailure instanceof IpcTransportError
|
|
1244
|
+
&& ['ENOENT', 'ECONNREFUSED'].includes(ipcFailure.code));
|
|
1245
|
+
console.log(stopped ? '⚠ EvolCore is not running' : '⚠ 无法确认 EvolCore 运行状态:IPC 不可用,且没有可见的存活 PID。');
|
|
1246
|
+
if (!stopped && ipcFailure)
|
|
1315
1247
|
console.log(` ${ipcFailure instanceof Error ? ipcFailure.message : String(ipcFailure)}`);
|
|
1316
1248
|
}
|
|
1317
1249
|
// Session & Project statistics (从文件系统读)
|
|
@@ -1872,6 +1804,7 @@ async function cmdWatchMenu() {
|
|
|
1872
1804
|
{ key: 'log', label: 'log', desc: 'real-time log tail' },
|
|
1873
1805
|
{ key: 'aid', label: 'aid', desc: 'AID connection stats' },
|
|
1874
1806
|
{ key: 'msg', label: 'msg', desc: 'message inspector' },
|
|
1807
|
+
{ key: 'diag', label: 'diag', desc: 'message lifecycle diagnostics (AUN→queue→task)' },
|
|
1875
1808
|
{ key: 'web', label: 'web', desc: 'browser dashboard (aid/msg/session)' },
|
|
1876
1809
|
];
|
|
1877
1810
|
let index = 0;
|
|
@@ -1936,6 +1869,10 @@ async function cmdWatchMenu() {
|
|
|
1936
1869
|
const { cmdWatchMsg } = await import('./watch-msg.js');
|
|
1937
1870
|
await cmdWatchMsg();
|
|
1938
1871
|
}
|
|
1872
|
+
else if (chosen === 'diag') {
|
|
1873
|
+
const { cmdWatchMsgDiag } = await import('./watch-msg-diag.js');
|
|
1874
|
+
await cmdWatchMsgDiag([]);
|
|
1875
|
+
}
|
|
1939
1876
|
else if (chosen === 'web') {
|
|
1940
1877
|
await cmdWatchWeb();
|
|
1941
1878
|
}
|
|
@@ -3358,6 +3295,36 @@ export async function cmdWatchCommand(args) {
|
|
|
3358
3295
|
const { cmdWatchMsg } = await import('./watch-msg.js');
|
|
3359
3296
|
await cmdWatchMsg();
|
|
3360
3297
|
}
|
|
3298
|
+
else if (args[0] === 'diag' || args[0] === 'msg-diag') {
|
|
3299
|
+
if (isHelpFlag(args[1])) {
|
|
3300
|
+
console.log(`用法: ec watch diag
|
|
3301
|
+
|
|
3302
|
+
实时诊断消息生命周期,从 AUN SDK 入站到 daemon 处理全过程。
|
|
3303
|
+
|
|
3304
|
+
显示内容:
|
|
3305
|
+
✓ AUN入站 消息到达 AUN SDK
|
|
3306
|
+
→ 队列入队 消息进入 daemon 队列
|
|
3307
|
+
⚡ 任务创建 daemon 创建处理任务
|
|
3308
|
+
✓ 任务完成 任务处理完成
|
|
3309
|
+
← AUN出站 回复消息发送
|
|
3310
|
+
|
|
3311
|
+
每条消息显示:
|
|
3312
|
+
- 时间戳(精确到毫秒)
|
|
3313
|
+
- 阶段标识
|
|
3314
|
+
- AID(前12字符)
|
|
3315
|
+
- 消息ID
|
|
3316
|
+
- 内容预览(前50字符)
|
|
3317
|
+
|
|
3318
|
+
用途:
|
|
3319
|
+
排查消息丢失、处理延迟、队列阻塞等问题
|
|
3320
|
+
|
|
3321
|
+
操作:
|
|
3322
|
+
Ctrl+C 退出`);
|
|
3323
|
+
return;
|
|
3324
|
+
}
|
|
3325
|
+
const { cmdWatchMsgDiag } = await import('./watch-msg-diag.js');
|
|
3326
|
+
await cmdWatchMsgDiag(args.slice(1));
|
|
3327
|
+
}
|
|
3361
3328
|
else if (args[0] === 'log' || args[0] === 'logs') {
|
|
3362
3329
|
const requested = args.slice(1);
|
|
3363
3330
|
if (requested.length > 0) {
|
package/dist/cli/data-command.js
CHANGED
|
@@ -99,7 +99,7 @@ export async function cmdData(args) {
|
|
|
99
99
|
// when there is no legacy source to process.
|
|
100
100
|
const existing = requestedId ? readDataMigration(root, requestedId) : undefined;
|
|
101
101
|
let manifest = existing ?? planDataMigration(root);
|
|
102
|
-
if (manifest.operations.length === 0
|
|
102
|
+
if (manifest.operations.length === 0) {
|
|
103
103
|
printSummary(manifest);
|
|
104
104
|
console.log('No legacy data requires migration.');
|
|
105
105
|
return;
|
|
@@ -119,9 +119,6 @@ export async function cmdData(args) {
|
|
|
119
119
|
manifest = applyDataMigration(manifest);
|
|
120
120
|
manifest = verifyDataMigration(manifest, { strictTargetContent: true });
|
|
121
121
|
printSummary(manifest);
|
|
122
|
-
if (manifest.state !== 'completed') {
|
|
123
|
-
throw new Error(`migration is not fully verified; fix the listed operations and run ec data migrate --apply ${manifest.id}`);
|
|
124
|
-
}
|
|
125
122
|
}
|
|
126
123
|
else {
|
|
127
124
|
// A completed manifest may come from the previous copy-only workflow,
|
|
@@ -133,6 +130,9 @@ export async function cmdData(args) {
|
|
|
133
130
|
console.log(`archive: ${finalization.archivePath}`);
|
|
134
131
|
console.log(`archive-sha256: ${finalization.archiveSha256}`);
|
|
135
132
|
console.log(`removed legacy sources: ${finalization.sourcePaths.length}`);
|
|
133
|
+
if (manifest.state !== 'completed') {
|
|
134
|
+
throw new Error(`migration is not fully verified; fix the listed operations and run ec data migrate --apply ${manifest.id}`);
|
|
135
|
+
}
|
|
136
136
|
if (wasRunning) {
|
|
137
137
|
console.log('Starting daemon and Agent runtimes after data migration...');
|
|
138
138
|
await cmdStart();
|
package/dist/cli/diag.js
CHANGED
|
@@ -5,7 +5,7 @@ import { parseDiagArgs } from '../core/command/diag-service.js';
|
|
|
5
5
|
import { wantsHelp } from './help.js';
|
|
6
6
|
export async function cmdDiag(args) {
|
|
7
7
|
if (wantsHelp(args)) {
|
|
8
|
-
console.log('用法:ec diag <问题描述> [--owner <daemonOwner-aid>] [--format json]\n ec diag stop [--format json]\n未指定 --owner 时联系本机 daemon.json.owners[0]。');
|
|
8
|
+
console.log('用法:ec diag <问题描述> [--owner <daemonOwner-aid>] [--format json]\n ec diag stop [--format json]\n未指定 --owner 时联系本机 daemon.json.owners[0];有效诊断期间再次执行会追加到原 case。');
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
11
|
const json = args.at(-2) === '--format' && args.at(-1) === 'json';
|
|
@@ -5,6 +5,7 @@ import { HANDOFF_QUERY_DEFAULT_LIMIT, HANDOFF_QUERY_MAX_LIMIT, HANDOFF_STATES }
|
|
|
5
5
|
import { HANDOFF_ID_RE } from '../core/handoff/store.js';
|
|
6
6
|
import { isHelpFlag, wantsHelp } from './help.js';
|
|
7
7
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
8
|
+
import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
|
|
8
9
|
function parseLimit(value) {
|
|
9
10
|
const limit = Number(value);
|
|
10
11
|
if (!value || !Number.isInteger(limit) || limit < 1 || limit > HANDOFF_QUERY_MAX_LIMIT) {
|
|
@@ -70,6 +71,7 @@ export function parseTrace(args) {
|
|
|
70
71
|
return parsed;
|
|
71
72
|
}
|
|
72
73
|
export function parseReturn(args) {
|
|
74
|
+
args = canonicalizeEvolcoreCommandArgv(['ec', 'handoff', 'return', ...args]).slice(3);
|
|
73
75
|
const dash = args.indexOf('--');
|
|
74
76
|
if (dash >= 0) {
|
|
75
77
|
const beforeDash = args.slice(0, dash);
|
package/dist/cli/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { cmdRestartMonitor } from './restart-monitor.js';
|
|
|
14
14
|
import { cmdAid, cmdRpc, cmdStorage, cmdMsg, cmdGroup } from './aun-commands.js';
|
|
15
15
|
import { cmdAgent } from './agent-command.js';
|
|
16
16
|
import { cmdCtl } from './ctl-command.js';
|
|
17
|
+
import { cmdMemory } from './memory-command.js';
|
|
17
18
|
import { cmdQueue } from './queue-command.js';
|
|
18
19
|
import { cmdStart, cmdStop, cmdRestart, cmdStatus, cmdLogs, cmdWatchCommand, cmdMv, cmdDiagnose } from './daemon-commands.js';
|
|
19
20
|
import { logCliCommand } from './command-log.js';
|
|
@@ -80,7 +81,7 @@ function printLifecycleHelp(command) {
|
|
|
80
81
|
restart: `用法: ec restart [--clear] [--diagnose|-d]\n\n --clear 同时清理跨 HOME 残留的 EvolCore 主进程\n --diagnose, -d 以诊断模式启动新 daemon`,
|
|
81
82
|
status: '用法: ec status\n\n查看 daemon、agent、渠道与会话运行状态。',
|
|
82
83
|
logs: `用法: ec logs [选项]\n\n --level <error|warn|info|debug> 最低日志级别\n --module <name> 只显示指定模块\n --raw 原始输出\n --no-color 禁用颜色`,
|
|
83
|
-
watch: `用法: ec watch [logs|log|aid|msg|web|session]\n\n ec watch 打开监控选择菜单\n ec watch logs 选择日志类型后监控\n ec watch log <类型...> 直接监控指定日志类型\n ec watch aid 监控 AID 连接\n ec watch msg 打开消息 TUI\n ec watch web 安装/升级并启动 EC Web\n ec watch session ec watch web 的兼容别名`,
|
|
84
|
+
watch: `用法: ec watch [logs|log|aid|msg|diag|web|session]\n\n ec watch 打开监控选择菜单\n ec watch logs 选择日志类型后监控\n ec watch log <类型...> 直接监控指定日志类型\n ec watch aid 监控 AID 连接\n ec watch msg 打开消息 TUI\n ec watch diag 实时诊断消息生命周期(AUN→daemon→任务)\n ec watch web 安装/升级并启动 EC Web\n ec watch session ec watch web 的兼容别名`,
|
|
84
85
|
'restart-monitor': '用法: ec restart-monitor\n\n运行内 daemon 重启与升级监控器。',
|
|
85
86
|
diagnose: '用法: ec diagnose [--codex-hook]\n\n检查配置、数据库、进程和编译产物。\n\n --codex-hook 运行 Windows Codex managed hook 启动探针。',
|
|
86
87
|
mv: '用法: ec mv <old-directory> <new-directory>\n\n迁移项目目录以及 Claude、Codex 和 EvolCore 会话路径。',
|
|
@@ -92,6 +93,14 @@ process.removeAllListeners('warning');
|
|
|
92
93
|
process.on('warning', (w) => { if (w.name === 'ExperimentalWarning')
|
|
93
94
|
return; process.stderr.write((w.stack ?? String(w)) + '\n'); });
|
|
94
95
|
export async function main(args) {
|
|
96
|
+
// 托管任务里裸跑 `ec` 想问的是"有哪些命令",而不是要启动 daemon。
|
|
97
|
+
// 默认回落到 `start` 会让守卫抛出 "Command start is not available",
|
|
98
|
+
// 把用户引向进程生命周期,而真实意图是查用法。这里直接给帮助。
|
|
99
|
+
if (args.length === 0 && process.env.EVOLCORE_SESSION_ID) {
|
|
100
|
+
console.log(MAIN_HELP);
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
95
104
|
const cmd = args[0] || 'start';
|
|
96
105
|
try {
|
|
97
106
|
assertManagedTopLevelCommandAllowed(cmd, args);
|
|
@@ -326,6 +335,9 @@ export async function main(args) {
|
|
|
326
335
|
case 'ctl':
|
|
327
336
|
await cmdCtl(args.slice(1));
|
|
328
337
|
break;
|
|
338
|
+
case 'memory':
|
|
339
|
+
await cmdMemory(args.slice(1));
|
|
340
|
+
break;
|
|
329
341
|
case 'queue':
|
|
330
342
|
await cmdQueue(args.slice(1));
|
|
331
343
|
break;
|
|
@@ -417,6 +429,11 @@ export async function main(args) {
|
|
|
417
429
|
await cmdModel(args.slice(1));
|
|
418
430
|
break;
|
|
419
431
|
}
|
|
432
|
+
case 'skill': {
|
|
433
|
+
const { cmdSkill } = await import('./skill-command.js');
|
|
434
|
+
await cmdSkill(args.slice(1));
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
420
437
|
case 'response': {
|
|
421
438
|
const { cmdResponse } = await import('./response.js');
|
|
422
439
|
await cmdResponse(args.slice(1));
|
|
@@ -11,10 +11,20 @@ const MANAGED_TASK_COMMANDS = new Set([
|
|
|
11
11
|
'fs',
|
|
12
12
|
'group',
|
|
13
13
|
'handoff',
|
|
14
|
+
// `memory` only works inside a managed task: both subcommands require
|
|
15
|
+
// EVOLCORE_SESSION_ID and authorize through their daemon IPC entrypoints.
|
|
16
|
+
'memory',
|
|
14
17
|
'model',
|
|
15
18
|
'msg',
|
|
16
19
|
'queue',
|
|
17
20
|
'response',
|
|
21
|
+
// `skill` 管理 EC 技能(安装/开关/校验)。它的主要使用者就是 agent 自己——
|
|
22
|
+
// ec-skill 技能的 SKILL.md 明确指导 agent 调用它。脚本只读写
|
|
23
|
+
// $EVOLCORE_HOME/skills/ 与 kits/skills/ 下的技能文件,不触碰进程生命周期。
|
|
24
|
+
// 本白名单只负责让它进到脚本;具体某一级的读写权限由 skill.mjs 的
|
|
25
|
+
// assertPermission() 按会话上下文判定(群聊一律拒,Agent 级要 owner,
|
|
26
|
+
// 本机级要 daemonowner),故此处不额外收紧。
|
|
27
|
+
'skill',
|
|
18
28
|
// `stats` reads the usage database directly. It authorizes each managed call
|
|
19
29
|
// against the task's relation role in `resolveManagedStatsScope`.
|
|
20
30
|
'stats',
|