evolcore 0.0.11 → 0.0.13
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 +44 -0
- package/bin/codex-managed-hook.mjs +80 -0
- package/bin/ec-safe-output.js +26 -7
- package/dist/agents/claude-runner.js +86 -7
- package/dist/agents/codex-app-server-client.js +174 -20
- package/dist/agents/codex-runner.js +375 -92
- package/dist/agents/ecagent-runner.js +39 -4
- package/dist/agents/gemini-runner.js +1 -0
- package/dist/aun/aid/client.js +11 -21
- package/dist/aun/aid/control-aid.js +36 -13
- package/dist/aun/aid/managed-operation.js +107 -0
- package/dist/aun/aid/store.js +13 -7
- package/dist/aun/group-fs-download.js +56 -0
- package/dist/aun/group-identity.js +1 -2
- package/dist/aun/msg/group.js +91 -44
- package/dist/aun/msg/index.js +1 -2
- package/dist/aun/msg/managed-operation.js +865 -0
- package/dist/aun/msg/mention-schema.js +20 -0
- package/dist/aun/msg/p2p.js +7 -0
- package/dist/aun/msg/upload.js +16 -1
- package/dist/aun/outbox.js +31 -2
- package/dist/aun/rpc/client.js +66 -0
- package/dist/aun/rpc/index.js +1 -2
- package/dist/aun/storage/{upload.js → client.js} +11 -2
- package/dist/aun/storage/index.js +1 -2
- package/dist/channels/aun.js +655 -240
- package/dist/channels/daemon.js +13 -0
- package/dist/cli/agent-command.js +56 -8
- package/dist/cli/agent.js +108 -31
- package/dist/cli/aun-commands.js +270 -69
- package/dist/cli/bench.js +12 -3
- package/dist/cli/cli-argv.js +10 -0
- package/dist/cli/config.js +9 -17
- package/dist/cli/ctl-command.js +1 -1
- package/dist/cli/daemon-commands.js +70 -55
- package/dist/cli/fs-command.js +79 -10
- package/dist/cli/handoff-command.js +3 -0
- package/dist/cli/index.js +30 -2
- package/dist/cli/init.js +77 -8
- package/dist/cli/managed-command-guard.js +41 -0
- package/dist/cli/model.js +11 -4
- package/dist/cli/queue-command.js +53 -1
- package/dist/cli/response.js +71 -0
- package/dist/cli/restart-monitor.js +7 -32
- package/dist/cli/trigger-command.js +11 -0
- package/dist/config/access-policy.js +1 -2
- package/dist/config/builtin-roles.js +9 -0
- package/dist/config/config-manager.js +21 -1
- package/dist/config/contact-book-store.js +11 -3
- package/dist/config/contact-request-service.js +161 -15
- package/dist/config/mention-mode.js +8 -24
- package/dist/config/peer-role-resolver.js +6 -2
- package/dist/config/role-migration-startup.js +53 -0
- package/dist/config/role-store.js +1 -1
- package/dist/core/auth/agent-delegation.js +1 -2
- package/dist/core/auth/auth-gateway.js +29 -1
- package/dist/core/auth/authorization-audit.js +15 -0
- package/dist/core/auth/operation-authorizer.js +31 -7
- package/dist/core/auth/operation-catalog.js +196 -25
- package/dist/core/bootstrap-messages.js +25 -0
- package/dist/core/bootstrap-service.js +64 -4
- package/dist/core/capability/providers/claude-capability-provider.js +9 -31
- package/dist/core/capability/providers/codex-capability-provider.js +4 -15
- package/dist/core/capability/skill-discovery.js +55 -0
- package/dist/core/channel-loader.js +1 -1
- package/dist/core/command/cli-intent-parser.js +9 -0
- package/dist/core/command/command-handler.js +650 -42
- package/dist/core/command/connect-menu.js +15 -0
- package/dist/core/command/group-menu.js +4 -4
- package/dist/core/command/menu-catalog.js +370 -0
- package/dist/core/command/menu-handler.js +230 -51
- package/dist/core/command/menu-protocol.js +94 -2
- package/dist/core/command/slash-gate.js +5 -2
- package/dist/core/command/slash-handler.js +99 -31
- package/dist/core/daemon-file-cache.js +2 -1
- package/dist/core/data-migration.js +9 -2
- package/dist/core/event-catalog.js +6 -0
- package/dist/core/evolagent.js +4 -2
- package/dist/core/handoff/dispatcher.js +5 -2
- package/dist/core/handoff/runtime.js +157 -22
- package/dist/core/handoff/store.js +29 -1
- package/dist/core/handoff/types.js +1 -0
- package/dist/core/interaction-router.js +10 -0
- package/dist/core/message/im-renderer.js +19 -0
- package/dist/core/message/logical-queue-bridge.js +1 -0
- package/dist/core/message/mention-schema.js +126 -0
- package/dist/core/message/message-bridge.js +298 -88
- package/dist/core/message/message-log.js +3 -0
- package/dist/core/message/message-queue.js +268 -39
- package/dist/core/message/message-utils.js +81 -4
- package/dist/core/message/response-engine.js +161 -77
- package/dist/core/message/stream-debouncer.js +10 -2
- package/dist/core/permission/approval-gateway.js +1 -0
- package/dist/core/permission/ec-command-parser.js +243 -18
- package/dist/core/permission/index.js +1 -1
- package/dist/core/permission/mode.js +15 -0
- package/dist/core/permission/readonly-shell-query.js +148 -8
- package/dist/core/permission/sandbox-runtime.js +43 -1
- package/dist/core/permission/tool-policy.js +322 -57
- package/dist/core/protected-paths.js +114 -4
- package/dist/core/session/session-manager.js +42 -4
- package/dist/core/session/session-mapper.js +20 -1
- package/dist/eck/detect.js +18 -1
- package/dist/eck/group-rules-sync.js +15 -44
- package/dist/eck/manifest-engine.js +39 -13
- package/dist/index.js +541 -180
- package/dist/ipc.js +232 -10
- package/dist/paths.js +3 -0
- package/dist/response-system/coordinator.js +6 -4
- package/dist/response-system/engines/v1/proactive-flow.js +26 -8
- package/dist/response-system/modes/single-session/index.js +14 -1
- package/dist/response-system/selector.js +6 -5
- package/dist/trigger/anomaly-store.js +4 -0
- package/dist/trigger/feedback.js +64 -11
- package/dist/trigger/manager.js +21 -1
- package/dist/trigger/parser.js +14 -2
- package/dist/trigger/scheduler.js +1 -0
- package/dist/trigger/script-executor.js +1 -0
- package/dist/trigger/validation.js +67 -6
- package/dist/utils/codex-app-server-registry.js +90 -0
- package/dist/utils/codex-cli.js +5 -1
- package/dist/utils/cross-platform.js +15 -0
- package/dist/utils/ecweb-supervisor.js +332 -0
- package/dist/utils/error-utils.js +10 -0
- package/dist/utils/npm-ops.js +5 -12
- package/dist/utils/tool-summary.js +11 -0
- package/kits/docs/channels/aun.md +1 -1
- package/kits/docs/context-assembly.md +2 -2
- package/kits/docs/evolcore/agent.md +11 -6
- package/kits/docs/evolcore/aid.md +14 -0
- package/kits/docs/evolcore/trigger.md +17 -1
- package/kits/docs/prompt-loading-architecture.md +1 -2
- package/kits/docs/venues/group.md +1 -1
- package/kits/eck_manifest.json +0 -12
- package/kits/migrations/migrate-contact-book-v2.mjs +1 -2
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/05-venue.md +2 -2
- package/kits/schemas/role-config.schema.1.json +1 -0
- package/kits/schemas/single-session.schema.1.json +3 -3
- package/kits/schemas/single-session.schema.2.json +3 -3
- package/kits/templates/roles/admin.json +27 -0
- package/kits/templates/roles/member.json +34 -1
- package/kits/templates/roles/visitor.json +35 -3
- package/kits/templates/system-fragments/bootstrap.md +1 -1
- package/kits/templates/system-fragments/channel.md +1 -1
- package/kits/templates/system-fragments/session.md +1 -1
- package/package.json +2 -2
- package/dist/aun/msg/payload-type.js +0 -27
- package/dist/aun/rpc/caller.js +0 -42
- package/dist/aun/rpc/connection.js +0 -25
- package/dist/aun/storage/manage.js +0 -10
- package/dist/config/access-policy-domain.js +0 -18
- package/dist/config/config-batch-get.js +0 -11
- package/dist/config/owner-policy.js +0 -4
- package/dist/config/role-config-v4-startup.js +0 -32
- package/dist/config/role-config-v5-startup.js +0 -27
- package/dist/core/auth/trigger-authorization.js +0 -15
- package/dist/core/command/evol-menu-version-gate.js +0 -39
- package/dist/core/interaction-registration.js +0 -10
- package/dist/core/permission/execution-sandbox.js +0 -16
- package/dist/core/relation/peer-key.js +0 -1
- package/dist/core/session/session-key.js +0 -24
- package/dist/eck/baseagent-caps.js +0 -18
- package/dist/eck/rules-loader.js +0 -28
|
@@ -14,21 +14,21 @@ 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 { tryUpgrade,
|
|
17
|
+
import { tryUpgrade, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
|
|
18
18
|
import { ecwebVersionRequirementError, fetchEcwebPairCode, resolveEcwebLaunchCommand } from '../utils/ecweb-utils.js';
|
|
19
19
|
import { isHostChinese } from '../utils/locale.js';
|
|
20
|
-
import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
|
|
21
20
|
import { scanInstances, cleanupInstances, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
|
|
22
21
|
import { filterLogFiles, deriveLogTypes, computePreChecked, validateLogTypes, shortLogName as shortLogNameLocal } from './watch-logs.js';
|
|
23
22
|
import { displaySessionTitle } from '../core/session/session-title.js';
|
|
24
23
|
import { isNonAgentSessionChannel } from '../core/system-channels.js';
|
|
25
24
|
import { printCodeStats } from './code-stats.js';
|
|
26
|
-
import { getProcessStartTime } from '../utils/process-introspect.js';
|
|
25
|
+
import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
|
|
27
26
|
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
28
27
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
|
|
29
28
|
import { rotateStdoutLog } from '../utils/log-writer.js';
|
|
30
29
|
import { inspectDataMigrationRequirement } from '../core/data-migration.js';
|
|
31
30
|
import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
|
|
31
|
+
import { listCodexAppServerProcesses, unregisterCodexAppServerProcess } from '../utils/codex-app-server-registry.js';
|
|
32
32
|
const execFileAsync = promisify(execFile);
|
|
33
33
|
async function runAutomaticInit(action) {
|
|
34
34
|
try {
|
|
@@ -389,9 +389,6 @@ export async function cmdStart(opts = {}) {
|
|
|
389
389
|
cleanEnv();
|
|
390
390
|
// 在启动前确保 serviceProxy 配置完整(如果 ecweb 启用但 serviceProxy 未配置)
|
|
391
391
|
ensureServiceProxyConfigBeforeStart(p);
|
|
392
|
-
const ecwebStartedBeforeDaemon = serviceProxyNeedsEcweb(loadDaemonConfig())
|
|
393
|
-
? await startEcwebIfEnabled(p)
|
|
394
|
-
: false;
|
|
395
392
|
// 删除旧的 ready signal
|
|
396
393
|
try {
|
|
397
394
|
fs.unlinkSync(p.readySignal);
|
|
@@ -421,23 +418,11 @@ export async function cmdStart(opts = {}) {
|
|
|
421
418
|
console.log(` EVOLCORE_HOME: ${resolveRoot()}`);
|
|
422
419
|
console.log(` Logs: ${p.logs}/`);
|
|
423
420
|
console.log(`⏱ ready in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
})
|
|
431
|
-
.catch((err) => {
|
|
432
|
-
console.error(`⚠ ECWeb 启动检查失败: ${err instanceof Error ? err.message : String(err)}`);
|
|
433
|
-
if (shouldPrintNoSelfAgentHints) {
|
|
434
|
-
printNoSelfAgentHints({ daemonConfig: loadDaemonConfig(), ecwebStarted: false, skipped });
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
else if (shouldPrintNoSelfAgentHints) {
|
|
439
|
-
printNoSelfAgentHints({ daemonConfig: loadDaemonConfig(), ecwebStarted: true, skipped });
|
|
440
|
-
}
|
|
421
|
+
void waitForExistingEcweb(p).then((ecweb) => {
|
|
422
|
+
if (shouldPrintNoSelfAgentHints) {
|
|
423
|
+
printNoSelfAgentHints({ daemonConfig: loadDaemonConfig(), ecwebStarted: ecweb !== null, skipped });
|
|
424
|
+
}
|
|
425
|
+
});
|
|
441
426
|
}, 500);
|
|
442
427
|
let forwardingShutdown = false;
|
|
443
428
|
const forwardSignal = (signal) => {
|
|
@@ -536,8 +521,9 @@ export async function cmdStart(opts = {}) {
|
|
|
536
521
|
printCodeStats(getPackageRoot(), p.logs);
|
|
537
522
|
}
|
|
538
523
|
console.log(`⏱ done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s`);
|
|
539
|
-
// ECWeb
|
|
540
|
-
|
|
524
|
+
// ECWeb lifecycle belongs to the daemon; the CLI only reports whether
|
|
525
|
+
// the supervised instance became healthy.
|
|
526
|
+
const ecwebStarted = await waitForExistingEcweb(p) !== null;
|
|
541
527
|
if (shouldPrintNoSelfAgentHints) {
|
|
542
528
|
printNoSelfAgentHints({ daemonConfig: loadDaemonConfig(), ecwebStarted, skipped });
|
|
543
529
|
}
|
|
@@ -668,19 +654,7 @@ export async function cmdRestart(opts = {}) {
|
|
|
668
654
|
console.log(`⚠ Upgrade failed (${upgrade.from} → ${upgrade.to}), continuing with current version`);
|
|
669
655
|
break;
|
|
670
656
|
}
|
|
671
|
-
//
|
|
672
|
-
const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
|
|
673
|
-
switch (aunUpgrade.status) {
|
|
674
|
-
case 'upgraded':
|
|
675
|
-
console.log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
|
|
676
|
-
break;
|
|
677
|
-
case 'no-update':
|
|
678
|
-
break; // silent
|
|
679
|
-
case 'failed':
|
|
680
|
-
console.log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to})`);
|
|
681
|
-
break;
|
|
682
|
-
}
|
|
683
|
-
// EC Web 版本检查与升级(已安装才检查,与 AUN SDK 同级)
|
|
657
|
+
// EC Web 是独立全局包,已安装时单独检查升级。
|
|
684
658
|
const ecwebUpgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
|
|
685
659
|
switch (ecwebUpgrade.status) {
|
|
686
660
|
case 'upgraded':
|
|
@@ -753,22 +727,20 @@ export async function cmdRestart(opts = {}) {
|
|
|
753
727
|
reportOrphans(otherHome);
|
|
754
728
|
}
|
|
755
729
|
}
|
|
756
|
-
//
|
|
730
|
+
// 只清理 EvolCore 自己登记的 codex app-server,不能影响桌面端实例。
|
|
757
731
|
{
|
|
758
732
|
const killed = stopCodexAppServerOrphans();
|
|
759
733
|
if (killed > 0) {
|
|
760
|
-
console.log(`☠ 已清理 ${killed} 个 codex app-server 孤儿进程`);
|
|
734
|
+
console.log(`☠ 已清理 ${killed} 个 EvolCore codex app-server 孤儿进程`);
|
|
761
735
|
await sleep(500);
|
|
762
736
|
}
|
|
763
737
|
}
|
|
764
738
|
console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
|
|
765
739
|
// 通过 restart-monitor 启动,避免在 agent 内调用时自杀
|
|
766
740
|
const appCli = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
env: { ...process.env, EVOLCORE_HOME: resolvePaths().root }
|
|
771
|
-
}).unref();
|
|
741
|
+
platform.spawnDetachedNode([appCli, 'restart-monitor'], {
|
|
742
|
+
EVOLCORE_HOME: resolvePaths().root,
|
|
743
|
+
});
|
|
772
744
|
console.log('🔄 Restart monitor started, waiting for service to come back online...');
|
|
773
745
|
await sleep(2000);
|
|
774
746
|
// 代码统计(开发环境)
|
|
@@ -2436,6 +2408,24 @@ async function probeEcwebReady(port) {
|
|
|
2436
2408
|
return false;
|
|
2437
2409
|
}
|
|
2438
2410
|
}
|
|
2411
|
+
/**
|
|
2412
|
+
* Wait briefly for an already-launched ECWeb to become healthy. `ec start`,
|
|
2413
|
+
* restart-monitor, and the daemon can overlap by a few milliseconds; treating
|
|
2414
|
+
* a healthy instance as an adoption target avoids killing/replacing it.
|
|
2415
|
+
*/
|
|
2416
|
+
async function waitForExistingEcweb(p, timeoutMs = 3_000) {
|
|
2417
|
+
const deadline = Date.now() + timeoutMs;
|
|
2418
|
+
do {
|
|
2419
|
+
for (const entry of findAliveEcwebs(p)) {
|
|
2420
|
+
if (await probeEcwebReady(entry.port))
|
|
2421
|
+
return entry;
|
|
2422
|
+
}
|
|
2423
|
+
if (Date.now() >= deadline)
|
|
2424
|
+
break;
|
|
2425
|
+
await sleep(250);
|
|
2426
|
+
} while (true);
|
|
2427
|
+
return null;
|
|
2428
|
+
}
|
|
2439
2429
|
/**
|
|
2440
2430
|
* 输出 ECWeb 状态。判定口径:
|
|
2441
2431
|
* 1. 进程是否存活(instance/ 下的 pid 文件 + isProcessRunning)
|
|
@@ -2513,15 +2503,29 @@ function removeEcwebInstanceFiles(p) {
|
|
|
2513
2503
|
catch { }
|
|
2514
2504
|
}
|
|
2515
2505
|
}
|
|
2516
|
-
/**
|
|
2517
|
-
function stopCodexAppServerOrphans() {
|
|
2518
|
-
|
|
2519
|
-
const codexProcs = platform.findProcesses('codex app-server');
|
|
2506
|
+
/** 清理 EvolCore 登记的 codex app-server 孤儿进程,返回清理的进程数。 */
|
|
2507
|
+
export function stopCodexAppServerOrphans() {
|
|
2508
|
+
const codexProcs = new Set(platform.findProcesses('codex app-server'));
|
|
2520
2509
|
let killed = 0;
|
|
2521
|
-
for (const
|
|
2510
|
+
for (const entry of listCodexAppServerProcesses()) {
|
|
2511
|
+
const { pid, startedAt } = entry.record;
|
|
2512
|
+
if (!platform.isProcessRunning(pid)) {
|
|
2513
|
+
unregisterCodexAppServerProcess(entry.filePath);
|
|
2514
|
+
continue;
|
|
2515
|
+
}
|
|
2516
|
+
// PID 复用时丢弃登记,不发送信号;命令行探测失败则保留登记,等待下次重试。
|
|
2517
|
+
const actualStartedAt = getProcessStartTime(pid);
|
|
2518
|
+
if (!startTimeMatches(startedAt, actualStartedAt)) {
|
|
2519
|
+
unregisterCodexAppServerProcess(entry.filePath);
|
|
2520
|
+
continue;
|
|
2521
|
+
}
|
|
2522
|
+
if (!codexProcs.has(pid))
|
|
2523
|
+
continue;
|
|
2522
2524
|
try {
|
|
2523
|
-
platform.killProcess(pid, true)
|
|
2524
|
-
|
|
2525
|
+
if (platform.killProcess(pid, true)) {
|
|
2526
|
+
killed++;
|
|
2527
|
+
unregisterCodexAppServerProcess(entry.filePath);
|
|
2528
|
+
}
|
|
2525
2529
|
}
|
|
2526
2530
|
catch { }
|
|
2527
2531
|
}
|
|
@@ -2633,10 +2637,21 @@ function ensureServiceProxyConfig(cfg, port) {
|
|
|
2633
2637
|
* Kept public for restart-monitor, which launches the daemon directly and
|
|
2634
2638
|
* therefore cannot rely on cmdStart's post-ready ECWeb startup path.
|
|
2635
2639
|
*/
|
|
2636
|
-
export async function startEcwebIfEnabled(p) {
|
|
2640
|
+
export async function startEcwebIfEnabled(p, options = {}) {
|
|
2637
2641
|
const cfg = loadDaemonConfig();
|
|
2638
2642
|
if (!cfg.ecweb?.enabled)
|
|
2639
2643
|
return false;
|
|
2644
|
+
// The daemon is the lifecycle owner. CLI callers normally only need to
|
|
2645
|
+
// ensure ECWeb is available, so adopt a healthy process instead of killing
|
|
2646
|
+
// it. `ec watch web` passes forceRestart explicitly for an intentional
|
|
2647
|
+
// manual replacement.
|
|
2648
|
+
if (!options.forceRestart) {
|
|
2649
|
+
const existing = await waitForExistingEcweb(p);
|
|
2650
|
+
if (existing) {
|
|
2651
|
+
console.log(`✓ ECWeb 已在运行 (PID: ${existing.pid}) http://localhost:${existing.port}`);
|
|
2652
|
+
return true;
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2640
2655
|
const installedPkg = resolveGlobalPkg(WEB_PACKAGE_NAME);
|
|
2641
2656
|
if (!installedPkg) {
|
|
2642
2657
|
console.log(`⚠ EC Web 未安装,跳过启动(运行 npm i -g ${WEB_PACKAGE_NAME}@latest 后可用)`);
|
|
@@ -2777,7 +2792,7 @@ async function cmdWatchWeb() {
|
|
|
2777
2792
|
}
|
|
2778
2793
|
}
|
|
2779
2794
|
else {
|
|
2780
|
-
//
|
|
2795
|
+
// 已安装:检查并自动升级独立的 EC Web 全局包。
|
|
2781
2796
|
const upgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
|
|
2782
2797
|
switch (upgrade.status) {
|
|
2783
2798
|
case 'upgraded':
|
|
@@ -2795,7 +2810,7 @@ async function cmdWatchWeb() {
|
|
|
2795
2810
|
saveDaemonConfig({ ...cfg, ecweb: { ...(cfg.ecweb ?? {}), enabled: true, port } });
|
|
2796
2811
|
// 自动配置 serviceProxy(如果控制 AID 已配置)
|
|
2797
2812
|
ensureServiceProxyConfigBeforeStart(p);
|
|
2798
|
-
const ok = await startEcwebIfEnabled(p);
|
|
2813
|
+
const ok = await startEcwebIfEnabled(p, { forceRestart: true });
|
|
2799
2814
|
if (!ok)
|
|
2800
2815
|
process.exit(1); // 失败原因已由 startEcwebIfEnabled 打印
|
|
2801
2816
|
// 启动成功的访问信息已由 startEcwebIfEnabled 打印,无需 printEcwebAccess 重复输出
|
package/dist/cli/fs-command.js
CHANGED
|
@@ -3,6 +3,10 @@ import path from 'path';
|
|
|
3
3
|
import { TextDecoder } from 'util';
|
|
4
4
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
5
5
|
import { agentmdGet, getAidStore, isValidAid, loadClient, SLOT } from '../aun/aid/index.js';
|
|
6
|
+
import { ipcQuery } from '../ipc.js';
|
|
7
|
+
import { resolvePaths } from '../paths.js';
|
|
8
|
+
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
9
|
+
import { downloadGroupFsBytes } from '../aun/group-fs-download.js';
|
|
6
10
|
class FsCliError extends Error {
|
|
7
11
|
code;
|
|
8
12
|
suggestion;
|
|
@@ -130,6 +134,10 @@ export async function cmdFs(args) {
|
|
|
130
134
|
console.log(HELP);
|
|
131
135
|
return;
|
|
132
136
|
}
|
|
137
|
+
if (process.env.EVOLCORE_SESSION_ID) {
|
|
138
|
+
await runManagedFs(args, opts.formatJson);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
133
141
|
try {
|
|
134
142
|
switch (sub) {
|
|
135
143
|
case 'ls':
|
|
@@ -199,6 +207,74 @@ export async function cmdFs(args) {
|
|
|
199
207
|
process.exit(1);
|
|
200
208
|
}
|
|
201
209
|
}
|
|
210
|
+
async function runManagedFs(args, formatJson) {
|
|
211
|
+
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
212
|
+
const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
|
|
213
|
+
const fail = (code, message) => {
|
|
214
|
+
if (formatJson)
|
|
215
|
+
console.log(JSON.stringify({ ok: false, code, error: message }));
|
|
216
|
+
else
|
|
217
|
+
console.error(`❌ ${message}`);
|
|
218
|
+
process.exit(1);
|
|
219
|
+
};
|
|
220
|
+
if (!sessionId)
|
|
221
|
+
fail('NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
|
|
222
|
+
if (!delegationToken)
|
|
223
|
+
fail('DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
|
|
224
|
+
const response = await ipcQuery(resolvePaths().socket, {
|
|
225
|
+
type: 'fs.op',
|
|
226
|
+
argv: ['fs', ...args],
|
|
227
|
+
sessionId,
|
|
228
|
+
delegationToken,
|
|
229
|
+
}, 30_000);
|
|
230
|
+
if (!response)
|
|
231
|
+
return fail('DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
|
|
232
|
+
if (!response.ok || !response.result)
|
|
233
|
+
fail(String(response.code || 'FS_OPERATION_FAILED'), response.error || 'Filesystem operation failed');
|
|
234
|
+
const result = response.result;
|
|
235
|
+
if (formatJson) {
|
|
236
|
+
console.log(JSON.stringify(result));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
switch (result.command) {
|
|
240
|
+
case 'cat':
|
|
241
|
+
if (result.binary)
|
|
242
|
+
console.log(JSON.stringify({ path: result.path, size: result.size, binary: true, head: result.head }, null, 2));
|
|
243
|
+
else
|
|
244
|
+
process.stdout.write(String(result.text ?? '').endsWith('\n') ? result.text : `${result.text ?? ''}\n`);
|
|
245
|
+
return;
|
|
246
|
+
case 'df': {
|
|
247
|
+
const usage = result.usage ?? {};
|
|
248
|
+
console.log(`Filesystem: ${result.path}`);
|
|
249
|
+
console.log(JSON.stringify(usage, null, 2));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
case 'stat':
|
|
253
|
+
case 'lstat':
|
|
254
|
+
console.log(JSON.stringify(result.node ?? {}, null, 2));
|
|
255
|
+
return;
|
|
256
|
+
case 'ls':
|
|
257
|
+
case 'find':
|
|
258
|
+
for (const item of result.items ?? [])
|
|
259
|
+
console.log(JSON.stringify(item));
|
|
260
|
+
return;
|
|
261
|
+
case 'mkdir':
|
|
262
|
+
console.log(`✓ 已创建目录: ${result.path}`);
|
|
263
|
+
return;
|
|
264
|
+
case 'upload':
|
|
265
|
+
console.log(`✓ 已上传: ${result.localPath} -> ${result.path}`);
|
|
266
|
+
return;
|
|
267
|
+
case 'copy':
|
|
268
|
+
console.log(`✓ 已复制: ${result.src} -> ${result.path}`);
|
|
269
|
+
return;
|
|
270
|
+
case 'move':
|
|
271
|
+
console.log(`✓ 已移动: ${result.src} -> ${result.path}`);
|
|
272
|
+
return;
|
|
273
|
+
case 'remove':
|
|
274
|
+
console.log(`✓ 已删除: ${result.path}`);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
202
278
|
function parseCommonOptions(args) {
|
|
203
279
|
const maxCatBytesRaw = getArgValue(args, '--max-bytes');
|
|
204
280
|
const maxCatBytes = maxCatBytesRaw === undefined ? 1024 * 1024 : Number(maxCatBytesRaw);
|
|
@@ -325,8 +401,9 @@ async function fsCat(args, opts) {
|
|
|
325
401
|
if (route.backend === 'group') {
|
|
326
402
|
statInfo = await client.group.fs.stat(remoteRef(target));
|
|
327
403
|
const size = numberFrom(statInfo, ['size', 'size_bytes', 'bytes']);
|
|
328
|
-
const downloaded = await client
|
|
329
|
-
bytes =
|
|
404
|
+
const downloaded = await downloadGroupFsBytes(client, remoteRef(target));
|
|
405
|
+
bytes = downloaded.bytes;
|
|
406
|
+
statInfo = { ...statInfo, ...downloaded.ticket };
|
|
330
407
|
statInfo = { ...statInfo, size: bytes.byteLength };
|
|
331
408
|
if (size !== undefined && size > opts.maxCatBytes) {
|
|
332
409
|
binaryHeadOnly = true;
|
|
@@ -1360,14 +1437,6 @@ function contentTypeFrom(value) {
|
|
|
1360
1437
|
const raw = value?.contentType ?? value?.content_type ?? value?.mime ?? value?.mime_type;
|
|
1361
1438
|
return raw ? String(raw).toLowerCase() : undefined;
|
|
1362
1439
|
}
|
|
1363
|
-
function bytesFromDownload(value) {
|
|
1364
|
-
const data = value?.data;
|
|
1365
|
-
if (data instanceof Uint8Array)
|
|
1366
|
-
return data;
|
|
1367
|
-
if (data instanceof ArrayBuffer)
|
|
1368
|
-
return new Uint8Array(data);
|
|
1369
|
-
throw new FsCliError('BACKEND_ERROR', '下载接口未返回字节内容', undefined, value);
|
|
1370
|
-
}
|
|
1371
1440
|
function looksBinary(bytes, contentType) {
|
|
1372
1441
|
if (contentType) {
|
|
1373
1442
|
if (contentType.startsWith('text/'))
|
|
@@ -203,6 +203,7 @@ Commands:
|
|
|
203
203
|
}
|
|
204
204
|
const result = await ipcQuery(resolvePaths().socket, {
|
|
205
205
|
type: 'handoff-status', sessionId: process.env.EVOLCORE_SESSION_ID, handoffId,
|
|
206
|
+
delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
|
|
206
207
|
}, 5000);
|
|
207
208
|
if (!result) {
|
|
208
209
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -234,6 +235,7 @@ Commands:
|
|
|
234
235
|
state: parsed.state,
|
|
235
236
|
filterSessionId: parsed.sessionId,
|
|
236
237
|
limit: parsed.limit,
|
|
238
|
+
delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
|
|
237
239
|
}, 5000);
|
|
238
240
|
if (!result) {
|
|
239
241
|
console.error('✗ daemon 暂时不可用');
|
|
@@ -276,6 +278,7 @@ Commands:
|
|
|
276
278
|
agent: parsed.agent,
|
|
277
279
|
handoffId: parsed.handoffId,
|
|
278
280
|
limit: parsed.limit,
|
|
281
|
+
delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
|
|
279
282
|
}, 5000);
|
|
280
283
|
if (!result) {
|
|
281
284
|
console.error('✗ daemon 暂时不可用');
|
package/dist/cli/index.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
process.env.AUN_LOG_INI_DISABLE = '1';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { getPackageRoot } from '../paths.js';
|
|
6
|
+
import { getPackageRoot, resolvePaths } from '../paths.js';
|
|
7
|
+
import { ipcQuery } from '../ipc.js';
|
|
8
|
+
import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
|
|
7
9
|
import { cmdInit } from './init.js';
|
|
8
10
|
import { cmdInitWechat, cmdInitFeishu, cmdInitDingtalk, cmdInitQQBot, cmdInitWecom, cmdInitAun } from './init-channel.js';
|
|
9
11
|
import { isHelpFlag, wantsHelp, getArgValue } from './help.js';
|
|
@@ -16,6 +18,7 @@ import { cmdQueue } from './queue-command.js';
|
|
|
16
18
|
import { cmdStart, cmdStop, cmdRestart, cmdStatus, cmdLogs, cmdWatchCommand, cmdMv, cmdDiagnose } from './daemon-commands.js';
|
|
17
19
|
import { logCliCommand } from './command-log.js';
|
|
18
20
|
import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
|
|
21
|
+
import { assertManagedTopLevelCommandAllowed, ManagedCommandNotAllowedError } from './managed-command-guard.js';
|
|
19
22
|
const MAIN_HELP = `用法: ec <command> [选项]
|
|
20
23
|
|
|
21
24
|
服务:
|
|
@@ -87,6 +90,16 @@ process.on('warning', (w) => { if (w.name === 'ExperimentalWarning')
|
|
|
87
90
|
return; process.stderr.write((w.stack ?? String(w)) + '\n'); });
|
|
88
91
|
export async function main(args) {
|
|
89
92
|
const cmd = args[0] || 'start';
|
|
93
|
+
try {
|
|
94
|
+
assertManagedTopLevelCommandAllowed(cmd, args);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (!(error instanceof ManagedCommandNotAllowedError))
|
|
98
|
+
throw error;
|
|
99
|
+
console.error(`❌ [${error.code}] ${error.message}`);
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
90
103
|
logCliCommand(cmd, args);
|
|
91
104
|
if (cmd === '--version' || cmd === '-v' || cmd === '-V') {
|
|
92
105
|
const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
|
|
@@ -229,7 +242,22 @@ export async function main(args) {
|
|
|
229
242
|
printLifecycleHelp('status');
|
|
230
243
|
break;
|
|
231
244
|
}
|
|
232
|
-
|
|
245
|
+
if (process.env.EVOLCORE_SESSION_ID) {
|
|
246
|
+
const sessionId = process.env.EVOLCORE_SESSION_ID;
|
|
247
|
+
const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
|
|
248
|
+
const result = await ipcQuery(resolvePaths().socket, {
|
|
249
|
+
type: 'status.auth', sessionId, delegationToken,
|
|
250
|
+
});
|
|
251
|
+
if (!result?.ok) {
|
|
252
|
+
console.error(`❌ ${result?.error || 'status is not allowed in this task'}`);
|
|
253
|
+
process.exitCode = 1;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
await cmdStatus();
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
await cmdStatus();
|
|
260
|
+
}
|
|
233
261
|
break;
|
|
234
262
|
case 'logs':
|
|
235
263
|
if (wantsHelp(args.slice(1))) {
|
package/dist/cli/init.js
CHANGED
|
@@ -7,7 +7,7 @@ import { commandExists } from '../utils/cross-platform.js';
|
|
|
7
7
|
import { scanInstances } from '../utils/instance-registry.js';
|
|
8
8
|
import { saveDefaultsSafe, loadAllAgents, loadDaemonConfig, saveDaemonConfig } from '../config-store.js';
|
|
9
9
|
import { generateControlAid, resolveControlAidDomain } from '../aun/aid/control-aid.js';
|
|
10
|
-
import { getCodexAppServerAvailability
|
|
10
|
+
import { getCodexAppServerAvailability } from '../agents/codex-runner.js';
|
|
11
11
|
import { resolveEcagentConfig } from '../agents/baseagent.js';
|
|
12
12
|
import { defaultProjectsRoot } from '../utils/project-path.js';
|
|
13
13
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST } from '../product.js';
|
|
@@ -28,15 +28,44 @@ export function expandLeadingTildePath(value, homeDir = os.homedir()) {
|
|
|
28
28
|
}
|
|
29
29
|
const BASEAGENT_CANDIDATES = ['claude', 'codex', 'gemini', 'ecagent'];
|
|
30
30
|
const AUTO_BASEAGENT_CANDIDATES = ['claude', 'codex', 'gemini'];
|
|
31
|
-
function isBaseagentAvailable(baseagent) {
|
|
31
|
+
function isBaseagentAvailable(baseagent, codexAvailability) {
|
|
32
32
|
if (baseagent === 'codex')
|
|
33
|
-
return
|
|
33
|
+
return (codexAvailability ?? getCodexAppServerAvailability()).available;
|
|
34
34
|
if (baseagent === 'ecagent')
|
|
35
35
|
return true;
|
|
36
36
|
return commandExists(baseagent);
|
|
37
37
|
}
|
|
38
|
-
function detectAvailable() {
|
|
39
|
-
return BASEAGENT_CANDIDATES.filter(isBaseagentAvailable);
|
|
38
|
+
function detectAvailable(codexAvailability = getCodexAppServerAvailability()) {
|
|
39
|
+
return BASEAGENT_CANDIDATES.filter(baseagent => isBaseagentAvailable(baseagent, codexAvailability));
|
|
40
|
+
}
|
|
41
|
+
/** Offer installation only when the probe positively identified an old CLI. */
|
|
42
|
+
export async function maybeUpgradeCodexForInit(availability, dependencies) {
|
|
43
|
+
if (!availability.requiresUpgrade) {
|
|
44
|
+
return { availability, offered: false, accepted: false };
|
|
45
|
+
}
|
|
46
|
+
const accepted = await dependencies.confirm();
|
|
47
|
+
if (!accepted)
|
|
48
|
+
return { availability, offered: true, accepted: false };
|
|
49
|
+
try {
|
|
50
|
+
const install = dependencies.install ?? (async () => {
|
|
51
|
+
const { npmInstallGlobal } = await import('../utils/npm-ops.js');
|
|
52
|
+
await npmInstallGlobal('@openai/codex@latest');
|
|
53
|
+
});
|
|
54
|
+
await install();
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
availability,
|
|
59
|
+
offered: true,
|
|
60
|
+
accepted: true,
|
|
61
|
+
error: installErrorMessage(error),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
availability: (dependencies.probe ?? getCodexAppServerAvailability)(),
|
|
66
|
+
offered: true,
|
|
67
|
+
accepted: true,
|
|
68
|
+
};
|
|
40
69
|
}
|
|
41
70
|
function pickDefault(available) {
|
|
42
71
|
return AUTO_BASEAGENT_CANDIDATES.find(candidate => available.includes(candidate));
|
|
@@ -192,7 +221,45 @@ export async function cmdInit(options) {
|
|
|
192
221
|
return false;
|
|
193
222
|
}
|
|
194
223
|
// ── 2. 探测 baseagent ──
|
|
195
|
-
|
|
224
|
+
let codexAvailability = getCodexAppServerAvailability();
|
|
225
|
+
if (!options?.nonInteractive && codexAvailability.version) {
|
|
226
|
+
console.log(`检测到 Codex CLI: ${codexAvailability.version}`);
|
|
227
|
+
}
|
|
228
|
+
if (!options?.nonInteractive && codexAvailability.requiresUpgrade) {
|
|
229
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
230
|
+
let result;
|
|
231
|
+
try {
|
|
232
|
+
result = await maybeUpgradeCodexForInit(codexAvailability, {
|
|
233
|
+
confirm: async () => {
|
|
234
|
+
console.log(`⚠ ${codexAvailability.reason}`);
|
|
235
|
+
const answer = (await ask(rl, '是否立即升级 Codex CLI?[Y/n] ')).trim().toLowerCase();
|
|
236
|
+
return answer === '' || answer === 'y' || answer === 'yes';
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
try {
|
|
242
|
+
rl.close();
|
|
243
|
+
}
|
|
244
|
+
catch { /* ignore */ }
|
|
245
|
+
}
|
|
246
|
+
if (!result.accepted) {
|
|
247
|
+
console.log(' 已跳过 Codex CLI 升级');
|
|
248
|
+
}
|
|
249
|
+
else if (result.error) {
|
|
250
|
+
console.log(` ⚠ Codex CLI 升级失败: ${result.error}`);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
codexAvailability = result.availability;
|
|
254
|
+
if (codexAvailability.available) {
|
|
255
|
+
console.log(` ✓ Codex CLI 已升级至 ${codexAvailability.version}`);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
console.log(` ⚠ Codex CLI 升级后仍不可用: ${codexAvailability.reason ?? '未知原因'}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
const available = detectAvailable(codexAvailability);
|
|
196
263
|
if (available.length === 0 || (available.length === 1 && available[0] === 'ecagent' && ecagentUnavailableReason())) {
|
|
197
264
|
console.log('❌ 未检测到可用 baseagent。请安装至少一款:');
|
|
198
265
|
console.log(' - claude CLI');
|
|
@@ -202,8 +269,10 @@ export async function cmdInit(options) {
|
|
|
202
269
|
return false;
|
|
203
270
|
}
|
|
204
271
|
console.log('检测到可用的 baseagent:');
|
|
205
|
-
for (const b of available)
|
|
206
|
-
|
|
272
|
+
for (const b of available) {
|
|
273
|
+
const version = b === 'codex' ? codexAvailability.version : undefined;
|
|
274
|
+
console.log(` ● ${b}${version ? ` (CLI ${version})` : ''}`);
|
|
275
|
+
}
|
|
207
276
|
console.log('');
|
|
208
277
|
const defaultsPath = p.defaultsConfig;
|
|
209
278
|
const defaultsExisted = fs.existsSync(defaultsPath);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { wantsHelp } from './help.js';
|
|
2
|
+
const MANAGED_TASK_COMMANDS = new Set([
|
|
3
|
+
'aid',
|
|
4
|
+
'agent',
|
|
5
|
+
'config',
|
|
6
|
+
'contact',
|
|
7
|
+
'ctl',
|
|
8
|
+
'fs',
|
|
9
|
+
'group',
|
|
10
|
+
'handoff',
|
|
11
|
+
'model',
|
|
12
|
+
'msg',
|
|
13
|
+
'queue',
|
|
14
|
+
'response',
|
|
15
|
+
'status',
|
|
16
|
+
'storage',
|
|
17
|
+
'trigger',
|
|
18
|
+
'version',
|
|
19
|
+
'-v',
|
|
20
|
+
'-V',
|
|
21
|
+
'--version',
|
|
22
|
+
]);
|
|
23
|
+
export class ManagedCommandNotAllowedError extends Error {
|
|
24
|
+
command;
|
|
25
|
+
code = 'NOT_ALLOWED';
|
|
26
|
+
constructor(command) {
|
|
27
|
+
super(`Command ${command} is not available in a managed Agent task`);
|
|
28
|
+
this.command = command;
|
|
29
|
+
this.name = 'ManagedCommandNotAllowedError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Local maintenance commands do not have daemon authorization entrypoints.
|
|
34
|
+
* Keep them outside managed tasks so they cannot read or mutate host state.
|
|
35
|
+
*/
|
|
36
|
+
export function assertManagedTopLevelCommandAllowed(command, args, env = process.env) {
|
|
37
|
+
if (!env.EVOLCORE_SESSION_ID || wantsHelp(args.slice(1)) || command === '--help' || command === '-h')
|
|
38
|
+
return;
|
|
39
|
+
if (!MANAGED_TASK_COMMANDS.has(command))
|
|
40
|
+
throw new ManagedCommandNotAllowedError(command);
|
|
41
|
+
}
|
package/dist/cli/model.js
CHANGED
|
@@ -46,10 +46,8 @@ function fail(formatJson, code, message, data) {
|
|
|
46
46
|
process.exit(1);
|
|
47
47
|
}
|
|
48
48
|
function isManagedSessionEnv(args) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
&& !getArgValue(args, '--peer')
|
|
52
|
-
&& !getArgValue(args, '--role');
|
|
49
|
+
void args;
|
|
50
|
+
return !!process.env.EVOLCORE_SESSION_ID;
|
|
53
51
|
}
|
|
54
52
|
function isManagedTargetedWriteEnv(args) {
|
|
55
53
|
return !!process.env.EVOLCORE_SESSION_ID
|
|
@@ -368,6 +366,11 @@ async function cmdInfo(args, formatJson) {
|
|
|
368
366
|
const modelId = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
|
|
369
367
|
if (!modelId)
|
|
370
368
|
fail(formatJson, 'MISSING_MODEL_ID', 'info 需要 <model-id>');
|
|
369
|
+
if (isManagedSessionEnv(args)) {
|
|
370
|
+
const out = await runCtlCommand(`/model info ${modelId}`, formatJson);
|
|
371
|
+
printCtlResult(out, formatJson);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
371
374
|
const sel = parseSelector(args, formatJson);
|
|
372
375
|
const self = getArgValue(args, '--self');
|
|
373
376
|
const info = await getModelInfo(modelId, self);
|
|
@@ -587,5 +590,9 @@ export async function cmdModel(args) {
|
|
|
587
590
|
console.log(HELP);
|
|
588
591
|
return;
|
|
589
592
|
}
|
|
593
|
+
if (process.env.EVOLCORE_SESSION_ID
|
|
594
|
+
&& (getArgValue(args, '--self') || getArgValue(args, '--peer') || getArgValue(args, '--role'))) {
|
|
595
|
+
fail(formatJson, 'NOT_ALLOWED', 'Managed model commands cannot select --self, --peer, or --role; they always use the authenticated current relation');
|
|
596
|
+
}
|
|
590
597
|
await dispatch(sub, args, formatJson);
|
|
591
598
|
}
|