evolcore 0.0.25 → 0.0.27
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 +632 -565
- package/LICENSE +21 -21
- package/README.md +455 -455
- package/bin/codex-managed-acl.ps1 +203 -160
- package/bin/codex-managed-hook.mjs +208 -208
- package/bin/ec-safe-output.js +327 -327
- package/bin/ec.js +40 -29
- package/bin/install-codex-managed-hooks.mjs +582 -555
- package/dist/agents/baseagent-availability.js +68 -0
- package/dist/agents/baseagent.js +96 -46
- package/dist/agents/claude-runner.js +172 -33
- package/dist/agents/codex/app-server-client.js +76 -31
- package/dist/agents/codex/catalog.js +1 -1
- package/dist/agents/codex/diagnostics.js +34 -1
- package/dist/agents/codex-runner.js +434 -446
- package/dist/agents/ecagent-runner.js +174 -34
- package/dist/agents/gemini-runner.js +8 -7
- package/dist/agents/runner-types.js +75 -19
- package/dist/aun/aid/agentmd.js +151 -36
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/control-aid.js +180 -1
- package/dist/aun/aid/identity.js +4 -4
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/store.js +17 -13
- package/dist/aun/group/history.js +303 -0
- package/dist/aun/group/identity.js +43 -0
- package/dist/aun/group/index.js +5 -0
- package/dist/aun/{msg/group.js → group/operations.js} +162 -39
- package/dist/aun/{menu-client.js → menu/client.js} +85 -6
- package/dist/aun/menu/index.js +2 -0
- package/dist/aun/menu/transport.js +49 -0
- package/dist/aun/msg/index.js +2 -1
- package/dist/aun/msg/managed-operation.js +85 -19
- package/dist/aun/msg/mention-schema.js +51 -0
- package/dist/aun/msg/p2p.js +19 -9
- package/dist/aun/msg/upload.js +43 -80
- package/dist/aun/outbox.js +29 -7
- package/dist/aun/rpc/client.js +1 -0
- package/dist/aun/storage/client.js +39 -50
- package/dist/channels/aun.js +842 -318
- package/dist/channels/daemon.js +10 -6
- package/dist/cli/agent-command.js +212 -89
- package/dist/cli/agent-create.js +626 -11
- package/dist/cli/agent.js +125 -13
- package/dist/cli/aun-commands.js +487 -337
- package/dist/cli/bench.js +20 -20
- package/dist/cli/config.js +55 -33
- package/dist/cli/contact.js +72 -15
- package/dist/cli/ctl-command.js +24 -24
- package/dist/cli/daemon-commands.js +140 -63
- package/dist/cli/diag.js +31 -0
- package/dist/cli/fs-command.js +70 -70
- package/dist/cli/handoff-command.js +46 -14
- package/dist/cli/index.js +91 -79
- package/dist/cli/init.js +34 -1
- package/dist/cli/link-rules.js +21 -21
- package/dist/cli/managed-command-guard.js +5 -1
- package/dist/cli/menu-client.js +51 -32
- package/dist/cli/model.js +3 -3
- package/dist/cli/net-check.js +22 -22
- package/dist/cli/queue-command.js +31 -31
- package/dist/cli/response.js +32 -32
- package/dist/cli/restart-monitor.js +103 -42
- package/dist/cli/stats.js +51 -51
- package/dist/cli/task-command.js +59 -0
- package/dist/cli/task-context.js +97 -49
- package/dist/cli/trigger-command.js +74 -64
- package/dist/config/builtin-roles.js +11 -0
- package/dist/config/config-field-policy.js +11 -0
- package/dist/config/config-manager.js +32 -4
- package/dist/config/config-operation-service.js +160 -0
- package/dist/config/contact-book-store.js +1 -1
- package/dist/config/contact-book.js +1 -1
- package/dist/config/contact-operation-service.js +97 -8
- package/dist/config/peer-role-resolver.js +1 -1
- package/dist/config/resolved-config-op.js +30 -7
- package/dist/config-store.js +1 -1
- package/dist/core/agent-application-service.js +7 -1
- package/dist/core/audit/event-key.js +17 -2
- package/dist/core/audit/log-integrity.js +34 -8
- package/dist/core/auth/agent-delegation.js +48 -14
- package/dist/core/auth/auth-gateway.js +2 -0
- package/dist/core/auth/authorization-audit.js +53 -49
- package/dist/core/auth/operation-authorizer.js +90 -7
- package/dist/core/auth/operation-catalog.js +145 -4
- package/dist/core/auth/remote-access-store.js +155 -10
- package/dist/core/bootstrap-messages.js +66 -7
- package/dist/core/bootstrap-service.js +111 -20
- package/dist/core/command/agent-control.js +88 -7
- package/dist/core/command/agent-storage-menu.js +443 -0
- package/dist/core/command/cli-intent-parser.js +19 -0
- package/dist/core/command/command-handler.js +159 -65
- package/dist/core/command/data-root-resolver.js +273 -0
- package/dist/core/command/diag-service.js +118 -0
- package/dist/core/command/group-menu.js +7 -2
- package/dist/core/command/menu-catalog.js +46 -7
- package/dist/core/command/menu-handler.js +392 -100
- package/dist/core/command/menu-protocol.js +45 -6
- package/dist/core/command/menu-token-store.js +41 -8
- package/dist/core/command/role-menu.js +2 -2
- package/dist/core/command/slash-gate.js +34 -4
- package/dist/core/command/slash-handler.js +123 -43
- package/dist/core/event-catalog.js +4 -0
- package/dist/core/evolagent-registry.js +28 -2
- package/dist/core/group/invite-service.js +924 -0
- package/dist/core/handoff/runtime.js +205 -27
- package/dist/core/handoff/store.js +193 -4
- package/dist/core/interaction-router.js +22 -8
- package/dist/core/message/im-renderer.js +146 -34
- package/dist/core/message/message-bridge.js +163 -20
- package/dist/core/message/message-log.js +5 -3
- package/dist/core/message/message-queue.js +99 -41
- package/dist/core/message/message-utils.js +1 -0
- package/dist/core/message/response-engine.js +755 -144
- package/dist/core/model/catalog-service.js +79 -49
- package/dist/core/model/context-window-suffix.js +33 -0
- package/dist/core/model/model-catalog.js +1 -1
- package/dist/core/model/model-permission.js +12 -3
- package/dist/core/permission/approval-gateway.js +36 -3
- package/dist/core/permission/ec-command-parser.js +112 -41
- package/dist/core/permission/protected-paths.js +134 -16
- package/dist/core/permission/sandbox-runtime.js +108 -17
- package/dist/core/permission/tool-error-code.js +15 -0
- package/dist/core/permission/tool-policy.js +9 -8
- package/dist/core/relation/peer-identity.js +57 -6
- package/dist/core/relation/shared-data.js +106 -0
- package/dist/core/role/runtime-policy.js +64 -0
- package/dist/core/runtime-lock.js +10 -26
- package/dist/core/session/runner-task-history.js +170 -0
- package/dist/core/session/session-manager.js +34 -6
- package/dist/core/session/session-mapper.js +41 -0
- package/dist/core/session/session-turn-coordinator.js +37 -7
- package/dist/core/session/session-turns.js +48 -7
- package/dist/core/task/task-recovery-service.js +176 -0
- package/dist/core/task/task-resume-operation.js +32 -0
- package/dist/eck/group-rules-sync.js +5 -3
- package/dist/eck/kit-renderer.js +1 -0
- package/dist/index.js +588 -217
- package/dist/ipc.js +193 -15
- package/dist/paths.js +17 -4
- package/dist/product.js +2 -0
- package/dist/response-system/engines/v1/proactive-flow.js +59 -2
- package/dist/stats/billing.js +41 -15
- package/dist/stats/db.js +159 -159
- package/dist/stats/eck-vars.js +9 -9
- package/dist/stats/price-resolver.js +28 -10
- package/dist/stats/query.js +139 -139
- package/dist/stats/role-budget.js +6 -6
- package/dist/stats/writer.js +51 -51
- package/dist/trigger/event-source.js +19 -0
- package/dist/trigger/feedback.js +233 -40
- package/dist/trigger/parser.js +55 -5
- package/dist/trigger/patch.js +9 -0
- package/dist/trigger/scheduler.js +30 -4
- package/dist/trigger/validation.js +20 -3
- package/dist/utils/cross-platform.js +30 -1
- package/dist/utils/ecweb-utils.js +1 -0
- package/dist/utils/error-dict.json +160 -160
- package/dist/utils/error-utils.js +61 -2
- package/dist/utils/evolcore-version.js +129 -0
- package/dist/utils/logger.js +26 -14
- package/dist/utils/macos-autostart.js +22 -22
- package/dist/utils/model-prices.jsonl +23 -23
- package/dist/utils/npm-ops.js +176 -35
- package/dist/utils/tool-summary.js +59 -3
- package/dist/utils/welcome.js +196 -23
- package/ecagent/LICENSE +21 -21
- package/ecagent/NOTICE +11 -11
- package/ecagent/README.md +61 -61
- package/ecagent/dist/harness/agent-harness.js +3 -0
- package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
- package/ecagent/dist/harness/compaction/compaction.js +83 -83
- package/ecagent/dist/harness/messages.js +7 -7
- package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
- package/kits/docs/GUIDE.md +20 -20
- package/kits/docs/INDEX.md +60 -66
- package/kits/docs/aun/CHEATSHEET.md +19 -19
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
- package/kits/docs/channels/aun.md +69 -56
- package/kits/docs/channels/feishu.md +56 -56
- package/kits/docs/context-assembly.md +379 -367
- package/kits/docs/eck_templates/GUIDE.template.md +22 -22
- package/kits/docs/eck_templates/INDEX.template.md +28 -28
- package/kits/docs/eck_templates/path-registry.template.md +33 -33
- package/kits/docs/eck_templates/runtime.template.md +19 -19
- package/kits/docs/evolcore/INDEX.md +76 -71
- package/kits/docs/evolcore/agent-create.md +202 -165
- package/kits/docs/evolcore/agent.md +99 -67
- package/kits/docs/evolcore/aid.md +68 -60
- package/kits/docs/evolcore/codex-windows-sandbox.md +146 -146
- package/kits/docs/evolcore/config.md +241 -195
- package/kits/docs/evolcore/contact.md +75 -68
- package/kits/docs/evolcore/ctl.md +46 -46
- package/kits/docs/evolcore/event.md +216 -216
- package/kits/docs/evolcore/fs-architecture.md +1215 -1215
- package/kits/docs/evolcore/fs.md +110 -110
- package/kits/docs/evolcore/group-collaboration.md +244 -244
- package/kits/docs/evolcore/group-fs.md +17 -17
- package/kits/docs/evolcore/group-rules.md +251 -251
- package/kits/docs/evolcore/group.md +267 -152
- package/kits/docs/evolcore/menu-client.md +58 -34
- package/kits/docs/evolcore/model.md +50 -50
- package/kits/docs/evolcore/msg.md +169 -165
- package/kits/docs/evolcore/response.md +75 -75
- package/kits/docs/evolcore/rpc.md +37 -37
- package/kits/docs/evolcore/self-summary.md +29 -29
- package/kits/docs/evolcore/stats.md +83 -83
- package/kits/docs/evolcore/storage.md +53 -50
- package/kits/docs/evolcore/task.md +14 -0
- package/kits/docs/evolcore/trigger.md +623 -575
- package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
- package/kits/docs/identity/PATH_OPS.md +16 -16
- package/kits/docs/identity/ROLE_DETAIL.md +25 -25
- package/kits/docs/identity/identity-tools.md +26 -26
- package/kits/docs/path-registry.md +62 -62
- package/kits/docs/prompt-loading-architecture.md +269 -269
- package/kits/docs/venues/aun-group.md +45 -45
- package/kits/docs/venues/aun-private.md +10 -10
- package/kits/docs/venues/client-desktop.md +10 -10
- package/kits/docs/venues/client-mobile.md +10 -10
- package/kits/docs/venues/feishu-group.md +13 -13
- package/kits/docs/venues/feishu-private.md +9 -9
- package/kits/docs/venues/group.md +42 -25
- package/kits/docs/venues/private.md +10 -10
- package/kits/eck_manifest.auxiliary.json +43 -43
- package/kits/eck_manifest.json +217 -190
- package/kits/eck_message_manifest.json +74 -74
- package/kits/migrations/README-role-config-v4.md +32 -32
- package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
- package/kits/migrations/migrate-role-config-v4.mjs +614 -614
- package/kits/migrations/migrate-role-config-v5.mjs +365 -365
- package/kits/migrations/rename-config-file.mjs +99 -99
- package/kits/rules/01-overview.md +166 -162
- package/kits/rules/02-navigation.md +96 -96
- package/kits/rules/03-identity.md +36 -36
- package/kits/rules/04-relation.md +76 -75
- package/kits/rules/05-venue.md +60 -60
- package/kits/rules/06-channel.md +65 -63
- package/kits/schemas/_meta.json +53 -53
- package/kits/schemas/agent-config.schema.1.json +177 -177
- package/kits/schemas/agent-config.schema.10.json +395 -395
- package/kits/schemas/agent-config.schema.11.json +421 -421
- package/kits/schemas/agent-config.schema.12.json +451 -427
- package/kits/schemas/agent-config.schema.2.json +239 -239
- package/kits/schemas/agent-config.schema.3.json +119 -119
- package/kits/schemas/agent-config.schema.4.json +208 -208
- package/kits/schemas/agent-config.schema.5.json +326 -326
- package/kits/schemas/agent-config.schema.6.json +322 -322
- package/kits/schemas/agent-config.schema.7.json +303 -303
- package/kits/schemas/agent-config.schema.8.json +304 -304
- package/kits/schemas/agent-config.schema.9.json +364 -364
- package/kits/schemas/contact-book.schema.1.json +36 -36
- package/kits/schemas/contact-book.schema.2.json +43 -43
- package/kits/schemas/contact-book.schema.3.json +67 -67
- package/kits/schemas/daemon.schema.1.json +91 -91
- package/kits/schemas/daemon.schema.2.json +101 -101
- package/kits/schemas/daemon.schema.3.json +123 -123
- package/kits/schemas/daemon.schema.4.json +136 -136
- package/kits/schemas/daemon.schema.5.json +135 -135
- package/kits/schemas/daemon.schema.6.json +131 -131
- package/kits/schemas/defaults.schema.1.json +81 -81
- package/kits/schemas/defaults.schema.2.json +85 -85
- package/kits/schemas/defaults.schema.3.json +73 -73
- package/kits/schemas/defaults.schema.4.json +107 -107
- package/kits/schemas/defaults.schema.5.json +119 -119
- package/kits/schemas/menu-exec-schema-commands.md +208 -208
- package/kits/schemas/migrations/README.md +30 -30
- package/kits/schemas/relation-config.schema.1.json +158 -158
- package/kits/schemas/relation-config.schema.2.json +73 -73
- package/kits/schemas/relation-config.schema.3.json +50 -50
- package/kits/schemas/relation-config.schema.4.json +47 -47
- package/kits/schemas/relation-config.schema.5.json +47 -47
- package/kits/schemas/relation-config.schema.6.json +46 -46
- package/kits/schemas/relation-config.schema.7.json +59 -59
- package/kits/schemas/relation-config.schema.8.json +103 -103
- package/kits/schemas/role-config.schema.1.json +215 -201
- package/kits/schemas/role-registry.schema.1.json +35 -35
- package/kits/schemas/single-session.schema.1.json +31 -31
- package/kits/schemas/single-session.schema.2.json +57 -57
- package/kits/schemas/single-session.schema.3.json +32 -32
- package/kits/templates/bootstrap-welcome.md +17 -17
- package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
- package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
- package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
- package/kits/templates/message-fragments/inject-default.md +2 -2
- package/kits/templates/message-fragments/item.md +2 -2
- package/kits/templates/roles/admin.json +92 -92
- package/kits/templates/roles/member.json +101 -96
- package/kits/templates/roles/owner.json +9 -9
- package/kits/templates/roles/visitor.json +90 -85
- package/kits/templates/system-fragments/baseagent.md +14 -14
- package/kits/templates/system-fragments/bootstrap.md +53 -34
- package/kits/templates/system-fragments/channel.md +28 -64
- package/kits/templates/system-fragments/commands.md +36 -28
- package/kits/templates/system-fragments/group-unread-history.md +7 -0
- package/kits/templates/system-fragments/identity.md +13 -13
- package/kits/templates/system-fragments/relation.md +19 -19
- package/kits/templates/system-fragments/reply.md +56 -0
- package/kits/templates/system-fragments/session.md +59 -59
- package/kits/templates/system-fragments/venue.md +31 -31
- package/package.json +104 -98
- package/dist/aun/group-identity.js +0 -9
- /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
- /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
|
@@ -23,11 +23,12 @@ import { displaySessionTitle } from '../core/session/session-title.js';
|
|
|
23
23
|
import { isNonAgentSessionChannel } from '../core/system-channels.js';
|
|
24
24
|
import { printCodeStats } from './code-stats.js';
|
|
25
25
|
import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
|
|
26
|
-
import {
|
|
26
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
27
27
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
|
|
28
28
|
import { rotateStdoutLog } from '../utils/log-writer.js';
|
|
29
29
|
import { inspectDataMigrationRequirement } from '../core/data-migration.js';
|
|
30
30
|
import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
|
|
31
|
+
import { computeBuildId } from '../utils/evolcore-version.js';
|
|
31
32
|
import { listCodexAppServerProcesses, unregisterCodexAppServerProcess } from '../agents/codex/app-server-registry.js';
|
|
32
33
|
import { DEFAULT_ECWEB_PORT, ecwebService, setEcwebEnabled } from '../config/daemon-services.js';
|
|
33
34
|
import { checkCodexProjectPath, inspectCodexManagedHook, ensureCodexManagedHook, runCodexHookLaunchDiagnostic, } from '../agents/codex/diagnostics.js';
|
|
@@ -39,6 +40,8 @@ export function ensureCodexHookBeforeLifecycle(onRepaired) {
|
|
|
39
40
|
try {
|
|
40
41
|
const usesCodex = loadDefaults()?.active_baseagent === 'codex'
|
|
41
42
|
|| loadAllAgents().agents.some(agent => {
|
|
43
|
+
if (agent.enabled === false)
|
|
44
|
+
return false;
|
|
42
45
|
try {
|
|
43
46
|
return resolveEffective({ self: agent.aid }).active_baseagent === 'codex';
|
|
44
47
|
}
|
|
@@ -145,7 +148,7 @@ function rejectPidIsolatedLifecycle(action, status, ping) {
|
|
|
145
148
|
}
|
|
146
149
|
async function tryDelegatedDaemonRestart(socketPath) {
|
|
147
150
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
148
|
-
const delegationToken =
|
|
151
|
+
const delegationToken = readDelegationCredential();
|
|
149
152
|
if (!sessionId || !delegationToken)
|
|
150
153
|
return false;
|
|
151
154
|
const response = await ipcQuery(socketPath, {
|
|
@@ -312,7 +315,10 @@ export async function runUpgradeChecks(upgradeFn = signal => tryUpgrade({ signal
|
|
|
312
315
|
clearTimeout(timer);
|
|
313
316
|
}
|
|
314
317
|
};
|
|
315
|
-
const upgrade = await
|
|
318
|
+
const [upgrade, ecwebUpgrade] = await Promise.all([
|
|
319
|
+
runWithTimeout('EvolCore', upgradeFn),
|
|
320
|
+
runWithTimeout(WEB_PACKAGE_NAME, ecwebUpgradeFn),
|
|
321
|
+
]);
|
|
316
322
|
switch (upgrade.status) {
|
|
317
323
|
case 'upgraded':
|
|
318
324
|
console.log(`✅ Upgraded: ${upgrade.from} → ${upgrade.to}`);
|
|
@@ -329,7 +335,6 @@ export async function runUpgradeChecks(upgradeFn = signal => tryUpgrade({ signal
|
|
|
329
335
|
console.log(`⚠ Upgrade failed${upgrade.from && upgrade.to ? ` (${upgrade.from} → ${upgrade.to})` : ''}, continuing with current version${upgrade.error ? `: ${upgrade.error}` : ''}`);
|
|
330
336
|
break;
|
|
331
337
|
}
|
|
332
|
-
const ecwebUpgrade = await runWithTimeout(WEB_PACKAGE_NAME, ecwebUpgradeFn);
|
|
333
338
|
switch (ecwebUpgrade.status) {
|
|
334
339
|
case 'upgraded':
|
|
335
340
|
console.log(`✅ ${WEB_PACKAGE_NAME} upgraded: ${ecwebUpgrade.from} → ${ecwebUpgrade.to}`);
|
|
@@ -769,21 +774,50 @@ export async function cmdStart(opts = {}) {
|
|
|
769
774
|
};
|
|
770
775
|
setTimeout(checkReady, 1000);
|
|
771
776
|
}
|
|
772
|
-
|
|
777
|
+
function isPidReused(pid, expectedStartedAt) {
|
|
778
|
+
if (expectedStartedAt === undefined)
|
|
779
|
+
return false;
|
|
780
|
+
const actualStartedAt = getProcessStartTime(pid);
|
|
781
|
+
return actualStartedAt !== null && !startTimeMatches(expectedStartedAt, actualStartedAt);
|
|
782
|
+
}
|
|
783
|
+
function reportPidReused(pid) {
|
|
784
|
+
console.log(`ℹ EvolCore PID ${pid} no longer refers to the recorded process; treating it as stopped`);
|
|
785
|
+
}
|
|
786
|
+
async function stopPid(pid, gracefulRequested = false, expectedStartedAt) {
|
|
773
787
|
console.log(`🛑 Stopping EvolCore (PID: ${pid})...`);
|
|
788
|
+
if (isPidReused(pid, expectedStartedAt)) {
|
|
789
|
+
reportPidReused(pid);
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
774
792
|
if (!gracefulRequested)
|
|
775
793
|
platform.killProcess(pid);
|
|
776
794
|
if (await platform.waitForProcessExit(pid, gracefulRequested ? 30_000 : 10_000)) {
|
|
777
795
|
console.log('✓ EvolCore stopped');
|
|
778
796
|
return true;
|
|
779
797
|
}
|
|
780
|
-
|
|
798
|
+
if (isPidReused(pid, expectedStartedAt)) {
|
|
799
|
+
reportPidReused(pid);
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
const state = platform.getProcessState(pid);
|
|
803
|
+
const stateSuffix = state ? ` (state=${state})` : '';
|
|
804
|
+
console.log(`⚠ EvolCore PID ${pid} did not exit gracefully${stateSuffix}; forcing termination...`);
|
|
805
|
+
if (isPidReused(pid, expectedStartedAt)) {
|
|
806
|
+
reportPidReused(pid);
|
|
807
|
+
return true;
|
|
808
|
+
}
|
|
781
809
|
platform.killProcess(pid, true);
|
|
782
810
|
if (await platform.waitForProcessExit(pid, 5_000)) {
|
|
783
811
|
console.log('✓ EvolCore stopped (forced)');
|
|
784
812
|
return true;
|
|
785
813
|
}
|
|
786
|
-
|
|
814
|
+
if (isPidReused(pid, expectedStartedAt)) {
|
|
815
|
+
reportPidReused(pid);
|
|
816
|
+
return true;
|
|
817
|
+
}
|
|
818
|
+
const finalState = platform.getProcessState(pid);
|
|
819
|
+
const finalStateSuffix = finalState ? ` (state=${finalState})` : '';
|
|
820
|
+
console.error(`❌ EvolCore PID ${pid} is still running${finalStateSuffix}; restart aborted`);
|
|
787
821
|
return false;
|
|
788
822
|
}
|
|
789
823
|
function isRuntimeOrphan(orphan, currentHome = resolveRoot()) {
|
|
@@ -813,13 +847,14 @@ export async function cmdStop() {
|
|
|
813
847
|
return;
|
|
814
848
|
}
|
|
815
849
|
const pids = new Set([...aliveMains.map(entry => entry.record.pid), ...runtimeOrphans.map(orphan => orphan.pid)]);
|
|
850
|
+
const expectedStarts = new Map(aliveMains.map(entry => [entry.record.pid, entry.record.startedAt]));
|
|
816
851
|
if (runtimeOrphans.length > 0) {
|
|
817
852
|
console.log(`⚠ 检测到未登记的 EvolCore 进程,将一并停止: ${runtimeOrphans.map(orphan => orphan.pid).join(', ')}`);
|
|
818
853
|
}
|
|
819
854
|
const gracefulPid = ping && pids.has(ping.pid)
|
|
820
855
|
? await requestDaemonShutdown(p.socket, DAEMON_SHUTDOWN_TIMEOUT_MS, 'ec stop', pids)
|
|
821
856
|
: null;
|
|
822
|
-
const stopped = await Promise.all([...pids].map(pid => stopPid(pid, pid === gracefulPid)));
|
|
857
|
+
const stopped = await Promise.all([...pids].map(pid => stopPid(pid, pid === gracefulPid, expectedStarts.get(pid))));
|
|
823
858
|
if (stopped.some(result => !result)) {
|
|
824
859
|
process.exitCode = 1;
|
|
825
860
|
return;
|
|
@@ -836,11 +871,13 @@ export async function cmdRestart(opts = {}) {
|
|
|
836
871
|
if (!ensureCodexHookBeforeLifecycle())
|
|
837
872
|
return;
|
|
838
873
|
const initialStatus = scanInstances();
|
|
839
|
-
const initialOrphans = findOrphanProcesses();
|
|
840
|
-
const initialRuntimeOrphans = initialOrphans.filter(orphan => isRuntimeOrphan(orphan));
|
|
841
874
|
const socketPath = resolvePaths().socket;
|
|
842
875
|
const ping = await probeDaemon(socketPath);
|
|
843
876
|
if (ping && !hasVisibleDaemonPid(initialStatus, ping)) {
|
|
877
|
+
// Only pay for a cross-host process-table scan when the IPC PID is not
|
|
878
|
+
// present in our registry. This is the exceptional PID-namespace case;
|
|
879
|
+
// healthy restarts no longer scan every Node process before stopping.
|
|
880
|
+
const initialRuntimeOrphans = findOrphanProcesses().filter(orphan => isRuntimeOrphan(orphan));
|
|
844
881
|
if (await tryDelegatedDaemonRestart(socketPath))
|
|
845
882
|
return;
|
|
846
883
|
if (initialRuntimeOrphans.length === 0 && rejectPidIsolatedLifecycle('restart', initialStatus, ping))
|
|
@@ -848,13 +885,13 @@ export async function cmdRestart(opts = {}) {
|
|
|
848
885
|
}
|
|
849
886
|
// 构建交给 restart-monitor:它在 daemon 停止之后才编译,dist/ 不会被活进程
|
|
850
887
|
// 占用,失败还能回滚到上一份产物。这里再编译一次会落在事务保护之外。
|
|
851
|
-
//
|
|
852
|
-
//
|
|
853
|
-
|
|
888
|
+
// restart-monitor owns upgrade checks. Running them here as well caused a
|
|
889
|
+
// normal restart to perform every registry lookup twice, and in installed
|
|
890
|
+
// mode could race the monitor while it was preparing its rollback point.
|
|
854
891
|
if (!requireCompletedDataMigration(resolveRoot(), 'restart'))
|
|
855
892
|
return;
|
|
856
893
|
// 停止所有活 main 进程(可能不止一个)
|
|
857
|
-
const status =
|
|
894
|
+
const status = initialStatus;
|
|
858
895
|
const aliveMains = status.mains.filter(m => m.alive);
|
|
859
896
|
if (aliveMains.length > 0) {
|
|
860
897
|
if (aliveMains.length > 1) {
|
|
@@ -865,7 +902,7 @@ export async function cmdRestart(opts = {}) {
|
|
|
865
902
|
const gracefulPid = currentPing && mainPids.has(currentPing.pid)
|
|
866
903
|
? await requestDaemonShutdown(socketPath, DAEMON_SHUTDOWN_TIMEOUT_MS, 'ec restart', mainPids)
|
|
867
904
|
: null;
|
|
868
|
-
const stopped = await Promise.all(aliveMains.map(m => stopPid(m.record.pid, m.record.pid === gracefulPid)));
|
|
905
|
+
const stopped = await Promise.all(aliveMains.map(m => stopPid(m.record.pid, m.record.pid === gracefulPid, m.record.startedAt)));
|
|
869
906
|
if (stopped.some(result => !result)) {
|
|
870
907
|
console.error('❌ Restart aborted because an existing EvolCore process could not be stopped');
|
|
871
908
|
process.exitCode = 1;
|
|
@@ -881,7 +918,8 @@ export async function cmdRestart(opts = {}) {
|
|
|
881
918
|
return;
|
|
882
919
|
}
|
|
883
920
|
// 孤儿处理:同 HOME/同安装包的孤儿属于本运行时,先确认退出再替换;
|
|
884
|
-
// 跨 HOME 的孤儿只在 --clear 时 kill,否则仅警告。
|
|
921
|
+
// 跨 HOME 的孤儿只在 --clear 时 kill,否则仅警告。findOrphanProcesses
|
|
922
|
+
// 在 Windows 上需要一次 CIM 查询;保留一个快照,避免同一阶段重复扫描。
|
|
885
923
|
{
|
|
886
924
|
const orphans = findOrphanProcesses();
|
|
887
925
|
const confirmedTestDaemons = orphans.filter(o => o.confirmedTestDaemon);
|
|
@@ -890,7 +928,7 @@ export async function cmdRestart(opts = {}) {
|
|
|
890
928
|
console.log(`☠ 已清理 ${killed.length} 个泄漏的测试 daemon: ${killed.join(', ')}`);
|
|
891
929
|
await sleep(500);
|
|
892
930
|
}
|
|
893
|
-
const runtimeOrphans =
|
|
931
|
+
const runtimeOrphans = orphans.filter(o => isRuntimeOrphan(o));
|
|
894
932
|
if (runtimeOrphans.length > 0) {
|
|
895
933
|
console.log(`⚠ 检测到未登记的 EvolCore 进程,将一并停止: ${runtimeOrphans.map(o => o.pid).join(', ')}`);
|
|
896
934
|
const orphanPids = new Set(runtimeOrphans.map(orphan => orphan.pid));
|
|
@@ -906,13 +944,9 @@ export async function cmdRestart(opts = {}) {
|
|
|
906
944
|
}
|
|
907
945
|
await sleep(500);
|
|
908
946
|
}
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
process.exitCode = 1;
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
const otherHome = findOrphanProcesses().filter(o => !o.confirmedTestDaemon && !isRuntimeOrphan(o));
|
|
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));
|
|
916
950
|
if (opts.clear && otherHome.length > 0) {
|
|
917
951
|
const killed = killOrphans(otherHome);
|
|
918
952
|
console.log(`☠ 已 SIGKILL ${killed.length} 个跨 HOME 孤儿进程: ${killed.join(', ')}`);
|
|
@@ -921,6 +955,14 @@ export async function cmdRestart(opts = {}) {
|
|
|
921
955
|
else if (otherHome.length > 0) {
|
|
922
956
|
reportOrphans(otherHome);
|
|
923
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
|
+
}
|
|
924
966
|
}
|
|
925
967
|
// 只清理 EvolCore 自己登记的 codex app-server,不能影响桌面端实例。
|
|
926
968
|
{
|
|
@@ -955,8 +997,7 @@ export async function cmdRestart(opts = {}) {
|
|
|
955
997
|
process.exitCode = 1;
|
|
956
998
|
return;
|
|
957
999
|
}
|
|
958
|
-
console.log('🔄 Restart monitor started
|
|
959
|
-
await sleep(2000);
|
|
1000
|
+
console.log('🔄 Restart monitor started; service is coming back online in the background...');
|
|
960
1001
|
// 代码统计(开发环境)
|
|
961
1002
|
if (path.normalize(resolveRoot()) === path.normalize(getPackageRoot())) {
|
|
962
1003
|
console.log('');
|
|
@@ -1125,6 +1166,7 @@ export async function cmdStatus() {
|
|
|
1125
1166
|
const p = resolvePaths();
|
|
1126
1167
|
const status = scanInstances();
|
|
1127
1168
|
const aliveMains = status.mains.filter(m => m.alive);
|
|
1169
|
+
const aliveRestartMonitors = status.restartMonitors.filter(m => m.alive);
|
|
1128
1170
|
// Start all read-only daemon queries together. On a busy Windows host each
|
|
1129
1171
|
// query can otherwise wait behind the same IPC/event-loop delay and make the
|
|
1130
1172
|
// total `ec status` time the sum of several individual timeouts.
|
|
@@ -1263,6 +1305,10 @@ export async function cmdStatus() {
|
|
|
1263
1305
|
catch { }
|
|
1264
1306
|
}
|
|
1265
1307
|
}
|
|
1308
|
+
else if (aliveRestartMonitors.length > 0) {
|
|
1309
|
+
console.log(`🔄 EvolCore 正在重启,daemon 尚未就绪(monitor PID: ${aliveRestartMonitors.map(m => m.record.pid).join(', ')})`);
|
|
1310
|
+
console.log(' 请稍后再次执行 ec status。');
|
|
1311
|
+
}
|
|
1266
1312
|
else {
|
|
1267
1313
|
console.log(ipcFailure ? '⚠ 无法确认 EvolCore 运行状态:IPC 不可用,且没有可见的存活 PID。' : '⚠ EvolCore is not running');
|
|
1268
1314
|
if (ipcFailure)
|
|
@@ -1312,6 +1358,24 @@ export async function cmdStatus() {
|
|
|
1312
1358
|
]);
|
|
1313
1359
|
agentsResponse = agentResponse;
|
|
1314
1360
|
if (statusResponse) {
|
|
1361
|
+
if (statusResponse.build) {
|
|
1362
|
+
if (statusResponse.build.runtimeMode === 'source') {
|
|
1363
|
+
console.log(` Build ID: runtime=source dist=${statusResponse.build.diskDistId || '?'}`);
|
|
1364
|
+
console.log(' ℹ daemon 当前由源码入口运行,dist build ID 不参与一致性比较。');
|
|
1365
|
+
}
|
|
1366
|
+
else {
|
|
1367
|
+
const runtimeBuildId = statusResponse.build.runtimeId || '?';
|
|
1368
|
+
const diskDistBuildId = statusResponse.build.diskDistId || '?';
|
|
1369
|
+
console.log(` Build ID: runtime=${runtimeBuildId} dist=${diskDistBuildId}`);
|
|
1370
|
+
if (runtimeBuildId !== '?' && diskDistBuildId !== '?' && runtimeBuildId !== diskDistBuildId) {
|
|
1371
|
+
console.log(' ⚠ 运行进程 build ID 与磁盘 dist 不一致;请重启 daemon 后再判断源码行为。');
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
else {
|
|
1376
|
+
console.log(` Build ID: runtime=unavailable (daemon 未提供 build identity) dist=${computeBuildId(path.join(getPackageRoot(), 'dist')) ?? '?'}`);
|
|
1377
|
+
console.log(' ⚠ 当前 daemon 未提供 build ID;请重启到包含 build identity 的版本后再判断源码行为。');
|
|
1378
|
+
}
|
|
1315
1379
|
// 🔑 AUN AIDs 表格(详细 AUN 实例状态)
|
|
1316
1380
|
try {
|
|
1317
1381
|
if (aidsResponse?.ok && aidsResponse.aids?.length > 0) {
|
|
@@ -2658,17 +2722,18 @@ function findAliveEcweb(p) {
|
|
|
2658
2722
|
return alive[0] ?? null;
|
|
2659
2723
|
}
|
|
2660
2724
|
/**
|
|
2661
|
-
* 轻量 HTTP 就绪探测:
|
|
2662
|
-
* 不走 /api/pair-code
|
|
2663
|
-
* 根路径由 serveStatic 处理,返回 index.html,无副作用。
|
|
2725
|
+
* 轻量 HTTP 就绪探测:ECWeb 的健康端点必须返回明确的服务标识。
|
|
2726
|
+
* 不走 /api/pair-code(会触发配对码刷新副作用),也不依赖静态页面内容。
|
|
2664
2727
|
*/
|
|
2665
2728
|
async function probeEcwebReady(port) {
|
|
2666
2729
|
try {
|
|
2667
|
-
const res = await fetch(`http://127.0.0.1:${port}
|
|
2668
|
-
method: 'GET',
|
|
2730
|
+
const res = await fetch(`http://127.0.0.1:${port}/api/health`, {
|
|
2669
2731
|
signal: AbortSignal.timeout(2000),
|
|
2670
2732
|
});
|
|
2671
|
-
|
|
2733
|
+
if (!res.ok)
|
|
2734
|
+
return false;
|
|
2735
|
+
const body = await res.json();
|
|
2736
|
+
return body.ok === true && body.service === 'ecweb';
|
|
2672
2737
|
}
|
|
2673
2738
|
catch {
|
|
2674
2739
|
return false;
|
|
@@ -2694,8 +2759,9 @@ async function waitForExistingEcweb(p, timeoutMs = 3_000) {
|
|
|
2694
2759
|
}
|
|
2695
2760
|
/**
|
|
2696
2761
|
* 输出 ECWeb 状态。判定口径:
|
|
2697
|
-
* 1.
|
|
2698
|
-
* 2.
|
|
2762
|
+
* 1. HTTP 是否就绪——探测 ECWeb 专用 /api/health 端点。
|
|
2763
|
+
* 2. 进程是否存活(instance/ 下的 pid 文件 + isProcessRunning)仅用于补充诊断;
|
|
2764
|
+
* 某些 CLI 运行在隔离 PID namespace 中,看不到宿主 ECWeb PID 是正常情况。
|
|
2699
2765
|
*/
|
|
2700
2766
|
async function printEcwebStatus(p) {
|
|
2701
2767
|
try {
|
|
@@ -2711,6 +2777,15 @@ async function printEcwebStatus(p) {
|
|
|
2711
2777
|
// still provide an authoritative runtime status without local config access.
|
|
2712
2778
|
}
|
|
2713
2779
|
const entries = readEcwebInstanceEntries(p);
|
|
2780
|
+
// Probe before consulting PID visibility. The daemon and CLI can be in
|
|
2781
|
+
// different PID namespaces while sharing the host network namespace.
|
|
2782
|
+
let readyEntry;
|
|
2783
|
+
for (const entry of entries) {
|
|
2784
|
+
if (await probeEcwebReady(entry.record.port)) {
|
|
2785
|
+
readyEntry = entry;
|
|
2786
|
+
break;
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2714
2789
|
const aliveEntries = [];
|
|
2715
2790
|
for (const entry of entries) {
|
|
2716
2791
|
if (platform.isProcessRunning(entry.record.pid)) {
|
|
@@ -2719,22 +2794,21 @@ async function printEcwebStatus(p) {
|
|
|
2719
2794
|
else {
|
|
2720
2795
|
// A stale EC Web record must never be used to report the PID of an
|
|
2721
2796
|
// unrelated process that later inherited the port.
|
|
2722
|
-
|
|
2723
|
-
|
|
2797
|
+
// Keep a record whose dedicated health endpoint just proved live: the
|
|
2798
|
+
// PID may be hidden by a namespace boundary rather than actually dead.
|
|
2799
|
+
if (entry.filePath !== readyEntry?.filePath) {
|
|
2800
|
+
try {
|
|
2801
|
+
fs.unlinkSync(entry.filePath);
|
|
2802
|
+
}
|
|
2803
|
+
catch { }
|
|
2724
2804
|
}
|
|
2725
|
-
catch { }
|
|
2726
|
-
}
|
|
2727
|
-
}
|
|
2728
|
-
let readyEntry;
|
|
2729
|
-
for (const entry of aliveEntries) {
|
|
2730
|
-
if (await probeEcwebReady(entry.record.port)) {
|
|
2731
|
-
readyEntry = entry;
|
|
2732
|
-
break;
|
|
2733
2805
|
}
|
|
2734
2806
|
}
|
|
2735
2807
|
if (readyEntry) {
|
|
2736
2808
|
console.log('');
|
|
2737
|
-
|
|
2809
|
+
const pidVisible = aliveEntries.some(entry => entry.filePath === readyEntry.filePath);
|
|
2810
|
+
const pidText = pidVisible ? `PID: ${readyEntry.record.pid}` : `PID: ${readyEntry.record.pid}(当前 namespace 不可见)`;
|
|
2811
|
+
console.log(`🔭 ECWeb: 运行中 (${pidText}) http://localhost:${readyEntry.record.port}`);
|
|
2738
2812
|
return;
|
|
2739
2813
|
}
|
|
2740
2814
|
const occupiedPids = new Set();
|
|
@@ -2771,9 +2845,12 @@ function removeEcwebInstanceFiles(p) {
|
|
|
2771
2845
|
}
|
|
2772
2846
|
/** 清理 EvolCore 登记的 codex app-server 孤儿进程,返回清理的进程数。 */
|
|
2773
2847
|
export function stopCodexAppServerOrphans() {
|
|
2848
|
+
const entries = listCodexAppServerProcesses();
|
|
2849
|
+
if (entries.length === 0)
|
|
2850
|
+
return 0;
|
|
2774
2851
|
const codexProcs = new Set(platform.findProcesses('codex app-server'));
|
|
2775
2852
|
let killed = 0;
|
|
2776
|
-
for (const entry of
|
|
2853
|
+
for (const entry of entries) {
|
|
2777
2854
|
const { pid, startedAt } = entry.record;
|
|
2778
2855
|
if (!platform.isProcessRunning(pid)) {
|
|
2779
2856
|
unregisterCodexAppServerProcess(entry.filePath);
|
|
@@ -2926,7 +3003,7 @@ export async function startEcwebIfEnabled(p, options = {}) {
|
|
|
2926
3003
|
console.log(`✓ ECWeb ${actionLabel} (PID: ${pid}) http://localhost:${port}`);
|
|
2927
3004
|
if (pair) {
|
|
2928
3005
|
const mins = Math.max(0, Math.round((pair.expiresAt - Date.now()) / 60000));
|
|
2929
|
-
console.log(` 配对码: ${pair.code} (约 ${mins}
|
|
3006
|
+
console.log(` 配对码: ${pair.code} (约 ${mins} 分钟内有效,仅可配对一次,已配对过的浏览器无需重新配对)`);
|
|
2930
3007
|
}
|
|
2931
3008
|
else {
|
|
2932
3009
|
console.log(' daemon 尚未提供配对码;EvolCore 启动后可通过 /pair 或 ECWeb 页面获取');
|
|
@@ -2962,7 +3039,7 @@ async function printEcwebAccess(port) {
|
|
|
2962
3039
|
}
|
|
2963
3040
|
if (pair) {
|
|
2964
3041
|
const mins = Math.max(0, Math.round((pair.expiresAt - Date.now()) / 60000));
|
|
2965
|
-
console.log(` 配对码: ${pair.code} (约 ${mins}
|
|
3042
|
+
console.log(` 配对码: ${pair.code} (约 ${mins} 分钟内有效,仅可配对一次,token 缓存 7 天,有访问自动续期)`);
|
|
2966
3043
|
}
|
|
2967
3044
|
else {
|
|
2968
3045
|
console.log(' 配对码: 暂不可用(稍后重试 ec watch web,或查看 logs/watch-web.log)');
|
|
@@ -3260,21 +3337,21 @@ export async function cmdWatchCommand(args) {
|
|
|
3260
3337
|
}
|
|
3261
3338
|
else if (args[0] === 'msg') {
|
|
3262
3339
|
if (isHelpFlag(args[1])) {
|
|
3263
|
-
console.log(`用法: ec watch msg
|
|
3264
|
-
|
|
3265
|
-
三面板交互式消息监控 TUI。
|
|
3266
|
-
|
|
3267
|
-
面板:
|
|
3268
|
-
左 (Scope) 本地 AID 列表,显示收发统计和对端数量
|
|
3269
|
-
中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
|
|
3270
|
-
右 (Messages) 消息流,带滚动条
|
|
3271
|
-
|
|
3272
|
-
操作:
|
|
3273
|
-
↑↓ 当前面板内导航
|
|
3274
|
-
←→ / Tab 切换面板
|
|
3275
|
-
Enter 选中 AID / 选中对端
|
|
3276
|
-
Backspace 返回上一级
|
|
3277
|
-
Page Up/Down 消息滚动
|
|
3340
|
+
console.log(`用法: ec watch msg
|
|
3341
|
+
|
|
3342
|
+
三面板交互式消息监控 TUI。
|
|
3343
|
+
|
|
3344
|
+
面板:
|
|
3345
|
+
左 (Scope) 本地 AID 列表,显示收发统计和对端数量
|
|
3346
|
+
中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
|
|
3347
|
+
右 (Messages) 消息流,带滚动条
|
|
3348
|
+
|
|
3349
|
+
操作:
|
|
3350
|
+
↑↓ 当前面板内导航
|
|
3351
|
+
←→ / Tab 切换面板
|
|
3352
|
+
Enter 选中 AID / 选中对端
|
|
3353
|
+
Backspace 返回上一级
|
|
3354
|
+
Page Up/Down 消息滚动
|
|
3278
3355
|
ESC 退出`);
|
|
3279
3356
|
return;
|
|
3280
3357
|
}
|
package/dist/cli/diag.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ipcQuery } from '../ipc.js';
|
|
2
|
+
import { resolvePaths } from '../paths.js';
|
|
3
|
+
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
|
+
import { parseDiagArgs } from '../core/command/diag-service.js';
|
|
5
|
+
import { wantsHelp } from './help.js';
|
|
6
|
+
export async function cmdDiag(args) {
|
|
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]。');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const json = args.at(-2) === '--format' && args.at(-1) === 'json';
|
|
12
|
+
const argv = json ? args.slice(0, -2) : args;
|
|
13
|
+
let result;
|
|
14
|
+
try {
|
|
15
|
+
parseDiagArgs(argv);
|
|
16
|
+
result = await ipcQuery(resolvePaths().socket, {
|
|
17
|
+
type: 'diag', argv,
|
|
18
|
+
...(process.env.EVOLCORE_SESSION_ID ? {
|
|
19
|
+
sessionId: process.env.EVOLCORE_SESSION_ID,
|
|
20
|
+
delegationToken: readDelegationCredential(),
|
|
21
|
+
} : {}),
|
|
22
|
+
}, 30_000) ?? { ok: false, code: 'DAEMON_UNAVAILABLE', message: 'daemon 未返回结果,请检查其运行状态;发送结果尚未确认' };
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
result = { ok: false, code: 'INVALID_ARGUMENT', message: error.message };
|
|
26
|
+
}
|
|
27
|
+
result.message ??= result.error ?? '诊断请求未完成';
|
|
28
|
+
console.log(json ? JSON.stringify(result, null, 2) : result.message);
|
|
29
|
+
if (!result.ok)
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
}
|
package/dist/cli/fs-command.js
CHANGED
|
@@ -5,8 +5,8 @@ import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
|
5
5
|
import { agentmdGet, getAidStore, isValidAid, loadClient, SLOT } from '../aun/aid/index.js';
|
|
6
6
|
import { ipcQuery } from '../ipc.js';
|
|
7
7
|
import { resolvePaths } from '../paths.js';
|
|
8
|
-
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
9
|
-
import { downloadGroupFsBytes } from '../aun/group
|
|
8
|
+
import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
9
|
+
import { downloadGroupFsBytes } from '../aun/group/index.js';
|
|
10
10
|
class FsCliError extends Error {
|
|
11
11
|
code;
|
|
12
12
|
suggestion;
|
|
@@ -19,73 +19,73 @@ class FsCliError extends Error {
|
|
|
19
19
|
this.details = details;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
const HELP = `用法: ec fs <command> [args...] [options]
|
|
23
|
-
|
|
24
|
-
Commands:
|
|
25
|
-
ls <AID>:<path> 列目录
|
|
26
|
-
stat [-L] <AID>:<path> 查看节点元数据(默认不跟随软链;-L 跟随)
|
|
27
|
-
lstat <AID>:<path> 查看节点本身(不跟随末级软链)
|
|
28
|
-
cat <AID>:<path> 输出文本文件内容;二进制/大文件返回头部摘要
|
|
29
|
-
cp <local> <AID>:<path> 上传本地文件
|
|
30
|
-
cp <AID>:<path> <local> 下载远程文件
|
|
31
|
-
cp <AID>:<path> <AID>:<path> 远程复制(同后端)
|
|
32
|
-
mv <AID>:<path> <AID>:<path> 移动/改名(同后端)
|
|
33
|
-
rm [-r] <AID>:<path> 删除文件或目录
|
|
34
|
-
mkdir [-p] <AID>:<path> 创建目录
|
|
35
|
-
ln -s <target> <AID>:<path> 创建软链(personal storage)
|
|
36
|
-
chmod [mode] <AID>:<path> 切换公开/私有(personal storage)
|
|
37
|
-
setfacl <AID>:<path> -m|-x ... 设置/移除 ACL(群路径使用 role:member|role:admin)
|
|
38
|
-
getfacl <AID>:<path> 查看 ACL
|
|
39
|
-
token issue|revoke|ls <path> 管理访问 token(personal storage)
|
|
40
|
-
find <AID>:<path> [filters] 查找节点
|
|
41
|
-
df <AID>: 查看容量/配额
|
|
42
|
-
mount <target> --volume <id> 挂载实体卷
|
|
43
|
-
mount <target> --source <src> 挂载远程子树
|
|
44
|
-
approve <AID>:<path> 批准待审挂载(personal storage)
|
|
45
|
-
reject <AID>:<path> 拒绝待审挂载(personal storage)
|
|
46
|
-
umount <AID>:<path> 卸载挂载点
|
|
47
|
-
|
|
48
|
-
Options:
|
|
49
|
-
--as <aid> 操作者 AID;也可由 EVOLCORE_SELF_AID 注入
|
|
50
|
-
--format json 输出 JSON
|
|
51
|
-
--overwrite, --force 覆盖目标(用于 cp/mv/ln)或强制删除(用于 rm)
|
|
52
|
-
-r, --recursive 递归(用于 rm/cp)
|
|
53
|
-
-p, --parents 自动创建父目录(用于 mkdir/group 上传)
|
|
54
|
-
-L, --follow stat 跟随末级软链
|
|
55
|
-
--token <token> 读取时携带访问 token(personal storage)
|
|
56
|
-
--content-type <mime> 上传时指定内容类型
|
|
57
|
-
--public 上传后公开可读(personal storage)
|
|
58
|
-
--visibility <public|private> chmod 可见性
|
|
59
|
-
--allow-roles <roles> chmod 角色约束,逗号分隔
|
|
60
|
-
-m aid:<aid>:<perms> setfacl 新增/更新 ACL
|
|
61
|
-
-x aid:<aid> setfacl 移除 ACL
|
|
62
|
-
--source <AID>:<path> mount 虚拟卷来源
|
|
63
|
-
--volume <id> mount 实体卷 ID
|
|
64
|
-
--require-approval mount 需要来源 owner 审批
|
|
65
|
-
--expires <time> mount/token/ACL 过期时间,Unix 秒或 ISO 日期
|
|
66
|
-
--max-uses <n> ACL 最大使用次数
|
|
67
|
-
--max-reads <n> token 最大读取次数
|
|
68
|
-
--readonly, --readwrite mount 只读/读写
|
|
69
|
-
--name <glob> find 名称过滤
|
|
70
|
-
--type <f|d|l> find 类型过滤
|
|
71
|
-
--size <expr> find 大小过滤,如 +1M
|
|
72
|
-
--mtime <expr> find 修改时间过滤
|
|
73
|
-
--head-bytes <n> cat 二进制头部字节数,默认 256
|
|
74
|
-
--max-bytes <n> cat 最大直接输出字节数,默认 1048576
|
|
75
|
-
--aun-path <path> 指定 AUN keystore 根
|
|
76
|
-
--app <name> 指定 AUN app slot
|
|
77
|
-
|
|
78
|
-
示例:
|
|
79
|
-
ec fs ls alice.agentid.pub:/private/
|
|
80
|
-
ec fs cp ./report.md alice.agentid.pub:/private/report.md --as alice.agentid.pub
|
|
81
|
-
ec fs cp alice.agentid.pub:/private/report.md ./report.md --as alice.agentid.pub
|
|
82
|
-
ec fs cp alice.agentid.pub:/private/a.md bob.agentid.pub:/inbox/a.md --as alice.agentid.pub
|
|
83
|
-
ec fs cat alice.agentid.pub:/private/report.md --as alice.agentid.pub
|
|
84
|
-
ec fs ln -s alice.agentid.pub:/private/report.md alice.agentid.pub:/public/report.md --as alice.agentid.pub
|
|
85
|
-
ec fs chmod +r alice.agentid.pub:/public/report.md --as alice.agentid.pub
|
|
86
|
-
ec fs setfacl alice.agentid.pub:/private/report.md -m aid:bob.agentid.pub:r --as alice.agentid.pub
|
|
87
|
-
ec fs token issue alice.agentid.pub:/public/report.md --expires 2026-12-31 --as alice.agentid.pub
|
|
88
|
-
ec fs find alice.agentid.pub:/private/ --name "*.md" --as alice.agentid.pub
|
|
22
|
+
const HELP = `用法: ec fs <command> [args...] [options]
|
|
23
|
+
|
|
24
|
+
Commands:
|
|
25
|
+
ls <AID>:<path> 列目录
|
|
26
|
+
stat [-L] <AID>:<path> 查看节点元数据(默认不跟随软链;-L 跟随)
|
|
27
|
+
lstat <AID>:<path> 查看节点本身(不跟随末级软链)
|
|
28
|
+
cat <AID>:<path> 输出文本文件内容;二进制/大文件返回头部摘要
|
|
29
|
+
cp <local> <AID>:<path> 上传本地文件
|
|
30
|
+
cp <AID>:<path> <local> 下载远程文件
|
|
31
|
+
cp <AID>:<path> <AID>:<path> 远程复制(同后端)
|
|
32
|
+
mv <AID>:<path> <AID>:<path> 移动/改名(同后端)
|
|
33
|
+
rm [-r] <AID>:<path> 删除文件或目录
|
|
34
|
+
mkdir [-p] <AID>:<path> 创建目录
|
|
35
|
+
ln -s <target> <AID>:<path> 创建软链(personal storage)
|
|
36
|
+
chmod [mode] <AID>:<path> 切换公开/私有(personal storage)
|
|
37
|
+
setfacl <AID>:<path> -m|-x ... 设置/移除 ACL(群路径使用 role:member|role:admin)
|
|
38
|
+
getfacl <AID>:<path> 查看 ACL
|
|
39
|
+
token issue|revoke|ls <path> 管理访问 token(personal storage)
|
|
40
|
+
find <AID>:<path> [filters] 查找节点
|
|
41
|
+
df <AID>: 查看容量/配额
|
|
42
|
+
mount <target> --volume <id> 挂载实体卷
|
|
43
|
+
mount <target> --source <src> 挂载远程子树
|
|
44
|
+
approve <AID>:<path> 批准待审挂载(personal storage)
|
|
45
|
+
reject <AID>:<path> 拒绝待审挂载(personal storage)
|
|
46
|
+
umount <AID>:<path> 卸载挂载点
|
|
47
|
+
|
|
48
|
+
Options:
|
|
49
|
+
--as <aid> 操作者 AID;也可由 EVOLCORE_SELF_AID 注入
|
|
50
|
+
--format json 输出 JSON
|
|
51
|
+
--overwrite, --force 覆盖目标(用于 cp/mv/ln)或强制删除(用于 rm)
|
|
52
|
+
-r, --recursive 递归(用于 rm/cp)
|
|
53
|
+
-p, --parents 自动创建父目录(用于 mkdir/group 上传)
|
|
54
|
+
-L, --follow stat 跟随末级软链
|
|
55
|
+
--token <token> 读取时携带访问 token(personal storage)
|
|
56
|
+
--content-type <mime> 上传时指定内容类型
|
|
57
|
+
--public 上传后公开可读(personal storage)
|
|
58
|
+
--visibility <public|private> chmod 可见性
|
|
59
|
+
--allow-roles <roles> chmod 角色约束,逗号分隔
|
|
60
|
+
-m aid:<aid>:<perms> setfacl 新增/更新 ACL
|
|
61
|
+
-x aid:<aid> setfacl 移除 ACL
|
|
62
|
+
--source <AID>:<path> mount 虚拟卷来源
|
|
63
|
+
--volume <id> mount 实体卷 ID
|
|
64
|
+
--require-approval mount 需要来源 owner 审批
|
|
65
|
+
--expires <time> mount/token/ACL 过期时间,Unix 秒或 ISO 日期
|
|
66
|
+
--max-uses <n> ACL 最大使用次数
|
|
67
|
+
--max-reads <n> token 最大读取次数
|
|
68
|
+
--readonly, --readwrite mount 只读/读写
|
|
69
|
+
--name <glob> find 名称过滤
|
|
70
|
+
--type <f|d|l> find 类型过滤
|
|
71
|
+
--size <expr> find 大小过滤,如 +1M
|
|
72
|
+
--mtime <expr> find 修改时间过滤
|
|
73
|
+
--head-bytes <n> cat 二进制头部字节数,默认 256
|
|
74
|
+
--max-bytes <n> cat 最大直接输出字节数,默认 1048576
|
|
75
|
+
--aun-path <path> 指定 AUN keystore 根
|
|
76
|
+
--app <name> 指定 AUN app slot
|
|
77
|
+
|
|
78
|
+
示例:
|
|
79
|
+
ec fs ls alice.agentid.pub:/private/
|
|
80
|
+
ec fs cp ./report.md alice.agentid.pub:/private/report.md --as alice.agentid.pub
|
|
81
|
+
ec fs cp alice.agentid.pub:/private/report.md ./report.md --as alice.agentid.pub
|
|
82
|
+
ec fs cp alice.agentid.pub:/private/a.md bob.agentid.pub:/inbox/a.md --as alice.agentid.pub
|
|
83
|
+
ec fs cat alice.agentid.pub:/private/report.md --as alice.agentid.pub
|
|
84
|
+
ec fs ln -s alice.agentid.pub:/private/report.md alice.agentid.pub:/public/report.md --as alice.agentid.pub
|
|
85
|
+
ec fs chmod +r alice.agentid.pub:/public/report.md --as alice.agentid.pub
|
|
86
|
+
ec fs setfacl alice.agentid.pub:/private/report.md -m aid:bob.agentid.pub:r --as alice.agentid.pub
|
|
87
|
+
ec fs token issue alice.agentid.pub:/public/report.md --expires 2026-12-31 --as alice.agentid.pub
|
|
88
|
+
ec fs find alice.agentid.pub:/private/ --name "*.md" --as alice.agentid.pub
|
|
89
89
|
ec fs df alice.agentid.pub: --as alice.agentid.pub`;
|
|
90
90
|
const VALUE_FLAGS = new Set([
|
|
91
91
|
'--as',
|
|
@@ -209,7 +209,7 @@ export async function cmdFs(args) {
|
|
|
209
209
|
}
|
|
210
210
|
async function runManagedFs(args, formatJson) {
|
|
211
211
|
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
212
|
-
const delegationToken =
|
|
212
|
+
const delegationToken = readDelegationCredential();
|
|
213
213
|
const fail = (code, message) => {
|
|
214
214
|
if (formatJson)
|
|
215
215
|
console.log(JSON.stringify({ ok: false, code, error: message }));
|