evolcore 0.0.35 → 0.0.37
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 +42 -0
- package/README.md +6 -0
- package/bin/install-codex-managed-hooks.mjs +20 -3
- package/dist/agents/baseagent-availability.js +1 -1
- package/dist/agents/baseagent.js +88 -0
- package/dist/agents/claude-runner.js +59 -12
- package/dist/agents/codex/app-server-client.js +18 -1
- package/dist/agents/codex-runner.js +262 -21
- package/dist/agents/ecagent-runner.js +47 -11
- package/dist/agents/gemini-runner.js +36 -12
- package/dist/aun/aid/client.js +4 -3
- package/dist/aun/aid/control-aid.js +270 -8
- package/dist/aun/aid/identity.js +6 -3
- package/dist/aun/aid/ownership-operation.js +58 -0
- package/dist/aun/aid/store.js +1 -0
- package/dist/aun/group/fs-download.js +67 -2
- package/dist/aun/group/history.js +20 -5
- package/dist/aun/group/operations.js +8 -2
- package/dist/aun/menu/client.js +39 -2
- package/dist/aun/menu/transport.js +1 -1
- package/dist/aun/msg/history.js +43 -4
- package/dist/aun/msg/managed-operation.js +30 -53
- package/dist/aun/msg/p2p.js +51 -15
- package/dist/aun/outbox.js +4 -0
- package/dist/channels/aun.js +260 -73
- package/dist/channels/daemon.js +6 -4
- package/dist/channels/feishu.js +3 -0
- package/dist/cli/agent-command.js +161 -223
- package/dist/cli/agent-create.js +190 -223
- package/dist/cli/agent.js +3 -1
- package/dist/cli/aid-bind-command.js +53 -0
- package/dist/cli/aun-commands.js +384 -91
- package/dist/cli/bench.js +1 -1
- package/dist/cli/cli-argv.js +74 -0
- package/dist/cli/daemon-commands.js +105 -74
- package/dist/cli/diag.js +1 -1
- package/dist/cli/fs-command.js +18 -19
- package/dist/cli/getmeta-command.js +159 -6
- package/dist/cli/index.js +6 -12
- package/dist/cli/init-channel.js +8 -55
- package/dist/cli/init.js +125 -218
- package/dist/cli/queue-command.js +11 -8
- package/dist/cli/restart-monitor.js +177 -85
- package/dist/cli/session-command.js +1 -1
- package/dist/cli/stats.js +7 -5
- package/dist/cli/thread-command.js +103 -30
- package/dist/cli/trigger-command.js +1 -1
- package/dist/cli/watch-msg-diag.js +1 -0
- package/dist/config/access-policy.js +2 -2
- package/dist/config/boot-log.js +14 -11
- package/dist/config/config-field-policy.js +9 -1
- package/dist/config/config-manager.js +176 -90
- package/dist/config/config-operation-service.js +7 -14
- package/dist/config/contact-book-store.js +142 -26
- package/dist/config/contact-book.js +4 -2
- package/dist/config/lifecycle.js +1 -1
- package/dist/config/owner-config.js +96 -0
- package/dist/config/peer-role-resolver.js +12 -18
- package/dist/config/providers-config.js +382 -0
- package/dist/config/providers-import.js +74 -0
- package/dist/config/providers-management.js +328 -0
- package/dist/config/providers.js +22 -0
- package/dist/config/resolved-config-op.js +17 -14
- package/dist/config/snapshot.js +28 -16
- package/dist/config-store.js +18 -14
- package/dist/core/agent-ipc-registration.js +21 -63
- package/dist/core/agent-runtime.js +16 -5
- package/dist/core/auth/agent-delegation.js +199 -25
- package/dist/core/auth/auth-gateway.js +44 -2
- package/dist/core/auth/authorization-denial.js +1 -1
- package/dist/core/auth/debug-context.js +2 -1
- package/dist/core/auth/delegation-authorization.js +2 -2
- package/dist/core/auth/delegation-diagnostics.js +4 -1
- package/dist/core/auth/operation-authorizer.js +10 -1
- package/dist/core/auth/operation-catalog.js +19 -1
- package/dist/core/bootstrap-service.js +43 -20
- package/dist/core/channel-loader.js +0 -1
- package/dist/core/channel-runtime.js +30 -4
- package/dist/core/command/agent-control.js +196 -37
- package/dist/core/command/cli-intent-parser.js +60 -4
- package/dist/core/command/command-handler.js +212 -60
- package/dist/core/command/connect-menu.js +1 -0
- package/dist/core/command/diag-service.js +5 -4
- package/dist/core/command/file-search.js +368 -0
- package/dist/core/command/menu-catalog.js +2 -1
- package/dist/core/command/menu-handler.js +292 -107
- package/dist/core/command/menu-protocol.js +23 -0
- package/dist/core/command/role-menu.js +7 -19
- package/dist/core/command/skill-slash.js +130 -25
- package/dist/core/command/slash-handler.js +101 -53
- package/dist/core/command/topic-slash.js +16 -5
- package/dist/core/daemon-bootstrap.js +7 -1
- package/dist/core/daemon-control.js +19 -1
- package/dist/core/daemon-lifecycle.js +2 -1
- package/dist/core/event-catalog.js +2 -0
- package/dist/core/evolagent-registry.js +13 -2
- package/dist/core/evolagent.js +3 -6
- package/dist/core/handoff/ipc-registration.js +2 -2
- package/dist/core/handoff/runtime.js +40 -6
- package/dist/core/handoff/store.js +1 -0
- package/dist/core/inference/text-inference.js +95 -6
- package/dist/core/ipc-registration.js +43 -24
- package/dist/core/memory/consolidation-context.js +4 -1
- package/dist/core/memory/consolidation.js +25 -14
- package/dist/core/message/aun-ipc-sender.js +296 -88
- package/dist/core/message/aun-request-registry.js +226 -0
- package/dist/core/message/create-status.js +33 -4
- package/dist/core/message/message-bridge.js +62 -13
- package/dist/core/message/message-log.js +0 -1
- package/dist/core/message/message-queue.js +4 -1
- package/dist/core/message/message-utils.js +8 -1
- package/dist/core/message/peer-mode.js +17 -9
- package/dist/core/message/response-engine.js +266 -124
- package/dist/core/message/retry-scheduler.js +11 -8
- package/dist/core/model/catalog-service.js +60 -18
- package/dist/core/model/model-catalog.js +112 -9
- package/dist/core/model/model-fallback.js +94 -26
- package/dist/core/ownership/owner-resolver.js +687 -0
- package/dist/core/permission/approval-gateway.js +196 -62
- package/dist/core/permission/ec-command-parser.js +138 -25
- package/dist/core/permission/filesystem-approval-scope.js +141 -0
- package/dist/core/permission/protected-paths.js +14 -1
- package/dist/core/permission/sandbox-runtime.js +171 -18
- package/dist/core/permission/tool-policy.js +13 -2
- package/dist/core/role/runtime-policy.js +3 -4
- package/dist/core/session/session-idle-monitor.js +10 -8
- package/dist/core/session/session-manager.js +72 -45
- package/dist/core/session/session-mapper.js +18 -7
- package/dist/core/session/session-renew.js +5 -4
- package/dist/core/session/session-title.js +2 -1
- package/dist/core/session/session-turn-coordinator.js +4 -2
- package/dist/core/skill/index-generator.js +2 -16
- package/dist/core/task/task-recovery-service.js +15 -2
- package/dist/core/thread/command-parser.js +28 -13
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +11 -8
- package/dist/core/thread/thread-operation.js +79 -44
- package/dist/core/thread/thread-route.js +54 -6
- package/dist/core/thread/thread-service.js +236 -45
- package/dist/core/thread/topic-id.js +248 -0
- package/dist/eck/kit-renderer.js +1 -1
- package/dist/eck/message-renderer.js +12 -2
- package/dist/index.js +50 -27
- package/dist/ipc.js +59 -6
- package/dist/paths.js +1 -0
- package/dist/product.js +1 -0
- package/dist/response-system/engines/v1/proactive-flow.js +10 -3
- package/dist/stats/db.js +8 -0
- package/dist/stats/writer.js +26 -4
- package/dist/trigger/authorization.js +48 -3
- package/dist/trigger/feedback.js +28 -10
- package/dist/trigger/ipc-service.js +86 -10
- package/dist/trigger/local-files.js +55 -23
- package/dist/trigger/scheduler.js +57 -11
- package/dist/trigger/system-definitions.js +1 -0
- package/dist/trigger/validation.js +44 -15
- package/dist/utils/aid-bind.js +17 -297
- package/dist/utils/avatar-upload.js +16 -4
- package/dist/utils/cross-platform.js +115 -36
- package/dist/utils/ecweb-supervisor.js +1 -1
- package/dist/utils/ecweb-utils.js +8 -1
- package/dist/utils/error-utils.js +44 -6
- package/dist/utils/instance-registry.js +12 -2
- package/dist/utils/npm-ops.js +102 -27
- package/dist/utils/package-version-info.js +72 -27
- package/dist/utils/restart-safety.js +50 -0
- package/dist/utils/upgrade-jobs.js +304 -0
- package/dist/utils/windows-autostart.js +17 -10
- package/kits/docs/INDEX.md +5 -0
- package/kits/docs/aun/ABILITY_CALLING.md +239 -0
- package/kits/docs/evolcore/INDEX.md +14 -3
- package/kits/docs/evolcore/agent-create.md +55 -141
- package/kits/docs/evolcore/agent.md +38 -16
- package/kits/docs/evolcore/aid.md +34 -0
- package/kits/docs/evolcore/config.md +20 -1
- package/kits/docs/evolcore/event.md +2 -2
- package/kits/docs/evolcore/fs.md +18 -2
- package/kits/docs/evolcore/group-collaboration.md +13 -246
- package/kits/docs/evolcore/group.md +2 -1
- package/kits/docs/evolcore/memory-consolidation-batches.md +1 -1
- package/kits/docs/evolcore/menu-protocol.md +65 -1
- package/kits/docs/evolcore/msg.md +64 -2
- package/kits/docs/evolcore/skill.md +86 -0
- package/kits/docs/evolcore/stats.md +6 -0
- package/kits/docs/evolcore/task.md +2 -0
- package/kits/docs/evolcore/thread-chain.md +145 -51
- package/kits/docs/evolcore/trigger.md +48 -3
- package/kits/eck_manifest.json +21 -0
- package/kits/eck_message_manifest.json +4 -4
- package/kits/migrations/migrate-role-config-v5.mjs +20 -7
- package/kits/rules/01-overview.md +2 -1
- package/kits/rules/03-identity.md +3 -1
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/07-memory-and-thread.md +1 -1
- package/kits/schemas/_meta.json +16 -1
- package/kits/schemas/agent-config.schema.13.json +44 -2
- package/kits/schemas/contact-book.schema.3.json +5 -0
- package/kits/schemas/daemon.schema.6.json +3 -1
- package/kits/schemas/daemon.schema.8.json +329 -0
- package/kits/schemas/defaults.schema.5.json +39 -3
- package/kits/schemas/providers.schema.1.json +76 -0
- package/kits/schemas/relation-config.schema.9.json +5 -1
- package/kits/skills/.switches.json +28 -0
- package/kits/skills/aid-ability/SKILL.md +214 -0
- package/kits/skills/ec-agent-create/SKILL.md +162 -0
- package/kits/skills/ec-group/SKILL.md +2 -1
- package/kits/skills/ec-group-collaboration/SKILL.md +228 -0
- package/kits/skills/ec-identity/SKILL.md +143 -0
- package/kits/skills/ec-skill/scripts/cli.mjs +36 -3
- package/kits/skills/ec-skill/scripts/skill.mjs +202 -15
- package/kits/skills/ec-trigger/SKILL.md +167 -0
- package/kits/skills/ec-trigger/references/examples.md +153 -0
- package/kits/skills/thread-ops/SKILL.md +108 -420
- package/kits/templates/message-fragments/thread-context.md +1 -2
- package/kits/templates/message-fragments/trigger-thread-check.md +1 -1
- package/kits/templates/roles/member.json +1 -1
- package/kits/templates/roles/visitor.json +1 -0
- package/kits/templates/system-fragments/bootstrap.md +1 -0
- package/kits/templates/system-fragments/channel.md +2 -1
- package/kits/templates/system-fragments/commands.md +5 -4
- package/kits/templates/system-fragments/identity.md +2 -0
- package/kits/templates/system-fragments/session.md +1 -1
- package/kits/templates/system-fragments/venue.md +1 -1
- package/package.json +4 -3
package/dist/cli/init.js
CHANGED
|
@@ -7,14 +7,15 @@ 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 { ecwebService, setEcwebEnabled } from '../config/daemon-services.js';
|
|
10
|
-
import { ensureControlAgentMd, generateControlAid, resolveControlAidDomain } from '../aun/aid/control-aid.js';
|
|
10
|
+
import { ensureControlAgentMd, generateControlAid, resolveControlAidDomain, submitControlAidRegistration, } from '../aun/aid/control-aid.js';
|
|
11
|
+
import { isValidAid } from '../aun/aid/validation.js';
|
|
11
12
|
import { getCodexAppServerAvailability } from '../agents/codex-runner.js';
|
|
12
|
-
import {
|
|
13
|
+
import { resolveCodexCliPath, resolveCodexPowerShellShimPath, } from '../agents/baseagent.js';
|
|
13
14
|
import { defaultProjectsRoot } from '../utils/project-path.js';
|
|
14
15
|
import { WEB_CLI_BIN, WEB_PACKAGE_LATEST } from '../product.js';
|
|
15
16
|
import { autostartInstalled, autostartPlatformLabel, configureAutostart } from '../utils/autostart.js';
|
|
16
|
-
import { askInit,
|
|
17
|
-
import { AUTO_BASEAGENT_CANDIDATES, BASEAGENT_CANDIDATES, detectAvailableBaseagents, } from '../agents/baseagent-availability.js';
|
|
17
|
+
import { askInit, printInitCancelHint } from './init-cancel.js';
|
|
18
|
+
import { AUTO_BASEAGENT_CANDIDATES, BASEAGENT_CANDIDATES, detectAvailableBaseagents, detectBaseagentDetails, } from '../agents/baseagent-availability.js';
|
|
18
19
|
// ==================== Helpers ====================
|
|
19
20
|
function ask(rl, question) {
|
|
20
21
|
return askInit(rl, question);
|
|
@@ -28,7 +29,7 @@ export function expandLeadingTildePath(value, homeDir = os.homedir()) {
|
|
|
28
29
|
}
|
|
29
30
|
return value;
|
|
30
31
|
}
|
|
31
|
-
function detectAvailable(codexAvailability = getCodexAppServerAvailability()) {
|
|
32
|
+
async function detectAvailable(codexAvailability = getCodexAppServerAvailability()) {
|
|
32
33
|
return detectAvailableBaseagents(codexAvailability);
|
|
33
34
|
}
|
|
34
35
|
/** Offer installation only when the probe positively identified an old CLI. */
|
|
@@ -63,23 +64,23 @@ export async function maybeUpgradeCodexForInit(availability, dependencies) {
|
|
|
63
64
|
function pickDefault(available) {
|
|
64
65
|
return AUTO_BASEAGENT_CANDIDATES.find(candidate => available.includes(candidate));
|
|
65
66
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
67
|
+
function pickInteractiveDefault(available) {
|
|
68
|
+
return available.includes('ecagent') ? 'ecagent' : pickDefault(available);
|
|
69
|
+
}
|
|
70
|
+
function hasConfiguredProcessOwner(config) {
|
|
71
|
+
const controlAid = config.aid?.toLowerCase();
|
|
72
|
+
return [config.owner, ...(config.owners ?? [])].some(owner => (typeof owner === 'string'
|
|
73
|
+
&& isValidAid(owner)
|
|
74
|
+
&& owner.toLowerCase() !== controlAid));
|
|
74
75
|
}
|
|
75
|
-
function buildDefaults(chosen, available, projectsDefaultPath
|
|
76
|
+
function buildDefaults(chosen, available, projectsDefaultPath) {
|
|
76
77
|
const baseagents = {};
|
|
77
78
|
for (const b of available) {
|
|
78
79
|
baseagents[b] = {};
|
|
79
80
|
}
|
|
80
81
|
// ecagent is bundled with EvolCore, so declare it even when the caller
|
|
81
82
|
// supplies a reduced availability list (for example, a test probe).
|
|
82
|
-
baseagents.ecagent =
|
|
83
|
+
baseagents.ecagent = baseagents.ecagent ?? {};
|
|
83
84
|
return {
|
|
84
85
|
$schema_version: 1,
|
|
85
86
|
active_baseagent: chosen,
|
|
@@ -87,13 +88,13 @@ function buildDefaults(chosen, available, projectsDefaultPath, ecagentConfig) {
|
|
|
87
88
|
...(projectsDefaultPath ? { projects: { defaultPath: projectsDefaultPath } } : {}),
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
|
-
function writeDefaults(chosen, available, projectsDefaultPath
|
|
91
|
-
saveDefaultsSafe(buildDefaults(chosen, available, projectsDefaultPath
|
|
91
|
+
function writeDefaults(chosen, available, projectsDefaultPath) {
|
|
92
|
+
saveDefaultsSafe(buildDefaults(chosen, available, projectsDefaultPath));
|
|
92
93
|
}
|
|
93
94
|
function hasCompletedInitConfig() {
|
|
94
95
|
const p = resolvePaths();
|
|
95
96
|
const daemon = loadDaemonConfig();
|
|
96
|
-
if (!daemon.aid
|
|
97
|
+
if (!daemon.aid)
|
|
97
98
|
return false;
|
|
98
99
|
try {
|
|
99
100
|
const defaults = JSON.parse(fs.readFileSync(p.defaultsConfig, 'utf8'));
|
|
@@ -132,23 +133,6 @@ function applyExplicitAutostart(enabled, runtimeRoot) {
|
|
|
132
133
|
export function needsControlAidInit(aid, isTty) {
|
|
133
134
|
return !aid && isTty;
|
|
134
135
|
}
|
|
135
|
-
/** 解析用户输入的 owner AID 列表:按空白/逗号分隔,去空、去重、按 isValid 分流。
|
|
136
|
-
* 空输入 → valid:[](视为跳过)。 */
|
|
137
|
-
export function parseOwnerAids(raw, isValid) {
|
|
138
|
-
const tokens = raw.split(/[\s,]+/).map(t => t.trim()).filter(Boolean);
|
|
139
|
-
const valid = [];
|
|
140
|
-
const invalid = [];
|
|
141
|
-
for (const t of tokens) {
|
|
142
|
-
if (isValid(t)) {
|
|
143
|
-
if (!valid.includes(t))
|
|
144
|
-
valid.push(t);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
invalid.push(t);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return { valid, invalid };
|
|
151
|
-
}
|
|
152
136
|
function installErrorMessage(e) {
|
|
153
137
|
return String(e?.stderr || e?.message || e).trim();
|
|
154
138
|
}
|
|
@@ -255,7 +239,7 @@ export async function cmdInit(options) {
|
|
|
255
239
|
}
|
|
256
240
|
}
|
|
257
241
|
}
|
|
258
|
-
const available = detectAvailable(codexAvailability);
|
|
242
|
+
const available = await detectAvailable(codexAvailability);
|
|
259
243
|
if (available.length === 0) {
|
|
260
244
|
console.log('❌ 未检测到可用 baseagent。请安装至少一款:');
|
|
261
245
|
console.log(' - claude CLI');
|
|
@@ -264,21 +248,32 @@ export async function cmdInit(options) {
|
|
|
264
248
|
console.log('\n安装后重新运行 ec init');
|
|
265
249
|
return false;
|
|
266
250
|
}
|
|
267
|
-
console.log('
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
251
|
+
console.log('baseagent 检测结果:');
|
|
252
|
+
const detections = detectBaseagentDetails(codexAvailability);
|
|
253
|
+
for (const detection of detections) {
|
|
254
|
+
if (detection.detected) {
|
|
255
|
+
const version = detection.version ? `,CLI ${detection.version}` : '';
|
|
256
|
+
const source = detection.detectionSource.includes('内置') ? '内置' : `可用${version}`;
|
|
257
|
+
console.log(` ● ${detection.id} (${source})`);
|
|
258
|
+
}
|
|
259
|
+
else if (detection.version || (detection.id === 'codex'
|
|
260
|
+
&& (resolveCodexCliPath() || resolveCodexPowerShellShimPath()))) {
|
|
261
|
+
console.log(` ○ ${detection.id} (已安装但不可用:${detection.reason ?? '未知原因'})`);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
console.log(` ○ ${detection.id} (未安装)`);
|
|
265
|
+
}
|
|
271
266
|
}
|
|
272
267
|
console.log('');
|
|
273
268
|
const defaultsPath = p.defaultsConfig;
|
|
274
269
|
const defaultsExisted = fs.existsSync(defaultsPath);
|
|
275
270
|
// “已初始化”以 daemon.json 为准:文件存在且控制 AID 已生成。
|
|
276
|
-
// 删除 daemon.json(aid 丢失)即视为未初始化,向导会重新补全 aid
|
|
271
|
+
// 删除 daemon.json(aid 丢失)即视为未初始化,向导会重新补全 aid。
|
|
277
272
|
const initialized = fs.existsSync(p.daemonConfig) && !!loadDaemonConfig().aid;
|
|
278
273
|
// ── 3. 非交互式分支 ──
|
|
279
274
|
if (options?.nonInteractive) {
|
|
280
275
|
if (defaultsExisted && !options.force) {
|
|
281
|
-
// defaults 已存在且未 --force:不重写 defaults,但仍落到共享 tail(幂等补全控制 AID
|
|
276
|
+
// defaults 已存在且未 --force:不重写 defaults,但仍落到共享 tail(幂等补全控制 AID)。
|
|
282
277
|
console.log(`配置已存在: ${defaultsPath}(加 --force 可覆盖)`);
|
|
283
278
|
}
|
|
284
279
|
else {
|
|
@@ -295,19 +290,12 @@ export async function cmdInit(options) {
|
|
|
295
290
|
console.log(`❌ ${options.baseagent} 当前环境不可用${reason ? `:${reason}` : `(可用: ${available.join('/')})`}`);
|
|
296
291
|
return false; // 硬错误:不落 tail
|
|
297
292
|
}
|
|
298
|
-
if (options.baseagent === 'ecagent') {
|
|
299
|
-
const reason = ecagentUnavailableReason();
|
|
300
|
-
if (reason) {
|
|
301
|
-
console.log(`❌ ecagent 当前环境不可用:${reason}`);
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
293
|
chosen = options.baseagent;
|
|
306
294
|
}
|
|
307
295
|
else {
|
|
308
296
|
const defaultBaseagent = pickDefault(available);
|
|
309
297
|
if (!defaultBaseagent) {
|
|
310
|
-
console.log('❌ ecagent 为可选 baseagent,请显式使用 --baseagent ecagent
|
|
298
|
+
console.log('❌ ecagent 为可选 baseagent,请显式使用 --baseagent ecagent');
|
|
311
299
|
return false;
|
|
312
300
|
}
|
|
313
301
|
chosen = defaultBaseagent;
|
|
@@ -333,11 +321,7 @@ export async function cmdInit(options) {
|
|
|
333
321
|
async function runInteractive() {
|
|
334
322
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
335
323
|
async function askBaseagent() {
|
|
336
|
-
const defaultBa =
|
|
337
|
-
if (available.length === 1 && defaultBa) {
|
|
338
|
-
console.log(` baseagent: ${defaultBa}`);
|
|
339
|
-
return defaultBa;
|
|
340
|
-
}
|
|
324
|
+
const defaultBa = pickInteractiveDefault(available);
|
|
341
325
|
let chosen = null;
|
|
342
326
|
while (chosen === null) {
|
|
343
327
|
const defaultHint = defaultBa ? ` [${defaultBa}]` : '';
|
|
@@ -391,59 +375,13 @@ export async function cmdInit(options) {
|
|
|
391
375
|
return resolved;
|
|
392
376
|
}
|
|
393
377
|
}
|
|
394
|
-
async function askEcagentConfig() {
|
|
395
|
-
let configured;
|
|
396
|
-
try {
|
|
397
|
-
const raw = JSON.parse(fs.readFileSync(defaultsPath, 'utf8'));
|
|
398
|
-
const candidate = raw?.baseagents?.ecagent;
|
|
399
|
-
if (candidate && typeof candidate === 'object' && !Array.isArray(candidate)) {
|
|
400
|
-
configured = candidate;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
catch {
|
|
404
|
-
// A malformed or missing defaults file should not prevent the user
|
|
405
|
-
// from supplying a fresh ecagent configuration during init.
|
|
406
|
-
configured = undefined;
|
|
407
|
-
}
|
|
408
|
-
const usable = (value) => {
|
|
409
|
-
if (typeof value !== 'string')
|
|
410
|
-
return false;
|
|
411
|
-
const normalized = value.trim();
|
|
412
|
-
if (!normalized)
|
|
413
|
-
return false;
|
|
414
|
-
const lower = normalized.toLowerCase();
|
|
415
|
-
return !lower.includes('your-') && !lower.includes('placeholder');
|
|
416
|
-
};
|
|
417
|
-
const configuredBaseUrl = [
|
|
418
|
-
configured?.baseUrl,
|
|
419
|
-
process.env.ECAGENT_BASE_URL,
|
|
420
|
-
DEFAULT_ECAGENT_BASE_URL,
|
|
421
|
-
].find(usable) || DEFAULT_ECAGENT_BASE_URL;
|
|
422
|
-
const baseUrl = (await ask(rl, `ecagent Base URL [${configuredBaseUrl}]: `)).trim() || configuredBaseUrl;
|
|
423
|
-
const configuredApiKey = usable(configured?.apiKey) ? configured.apiKey.trim() : undefined;
|
|
424
|
-
const environmentApiKeyName = !configuredApiKey
|
|
425
|
-
? (usable(process.env.ECAGENT_API_KEY)
|
|
426
|
-
? 'ECAGENT_API_KEY'
|
|
427
|
-
: usable(process.env.OPENAI_API_KEY) ? 'OPENAI_API_KEY' : undefined)
|
|
428
|
-
: undefined;
|
|
429
|
-
let apiKey = '';
|
|
430
|
-
while (!apiKey) {
|
|
431
|
-
const suffix = configuredApiKey || environmentApiKeyName ? '(回车保留当前配置)' : '(必填)';
|
|
432
|
-
const input = (await ask(rl, `ecagent API Key ${suffix}: `)).trim();
|
|
433
|
-
apiKey = input || configuredApiKey || (environmentApiKeyName ? '${' + environmentApiKeyName + '}' : '');
|
|
434
|
-
if (!apiKey)
|
|
435
|
-
console.log(' API Key 不能为空,请重新输入');
|
|
436
|
-
}
|
|
437
|
-
return { apiKey, baseUrl };
|
|
438
|
-
}
|
|
439
378
|
try {
|
|
440
379
|
if (defaultsExisted) {
|
|
441
380
|
const ans = (await ask(rl, `配置文件已存在: ${defaultsPath}\n 是否覆盖?[y/N] `)).trim().toLowerCase();
|
|
442
381
|
if (ans === 'y' || ans === 'yes') {
|
|
443
382
|
const chosen = await askBaseagent();
|
|
444
|
-
const ecagentConfig = chosen === 'ecagent' ? await askEcagentConfig() : undefined;
|
|
445
383
|
const projectsDefaultPath = await askProjectsDefaultPath();
|
|
446
|
-
writeDefaults(chosen, available, projectsDefaultPath
|
|
384
|
+
writeDefaults(chosen, available, projectsDefaultPath);
|
|
447
385
|
console.log(`\n✓ 已覆盖: ${defaultsPath}`);
|
|
448
386
|
console.log(` active_baseagent: ${chosen}\n`);
|
|
449
387
|
}
|
|
@@ -453,9 +391,8 @@ export async function cmdInit(options) {
|
|
|
453
391
|
}
|
|
454
392
|
else {
|
|
455
393
|
const chosen = await askBaseagent();
|
|
456
|
-
const ecagentConfig = chosen === 'ecagent' ? await askEcagentConfig() : undefined;
|
|
457
394
|
const projectsDefaultPath = await askProjectsDefaultPath();
|
|
458
|
-
writeDefaults(chosen, available, projectsDefaultPath
|
|
395
|
+
writeDefaults(chosen, available, projectsDefaultPath);
|
|
459
396
|
console.log(`\n✓ 已创建: ${defaultsPath}`);
|
|
460
397
|
console.log(` active_baseagent: ${chosen}\n`);
|
|
461
398
|
}
|
|
@@ -468,7 +405,7 @@ export async function cmdInit(options) {
|
|
|
468
405
|
}
|
|
469
406
|
}
|
|
470
407
|
}
|
|
471
|
-
/** 补全控制 AID +
|
|
408
|
+
/** 补全控制 AID + owner(可单独调用,不走 baseagent 向导)。 */
|
|
472
409
|
export async function initTail(options = {}) {
|
|
473
410
|
// 提示创建 agent(两分支汇合后执行一次)
|
|
474
411
|
const { agents } = loadAllAgents();
|
|
@@ -481,7 +418,6 @@ export async function initTail(options = {}) {
|
|
|
481
418
|
let controlAidReady = !!daemonConfig.aid;
|
|
482
419
|
let autoStartReady = true;
|
|
483
420
|
const autoStartExplicit = options.autoStart !== undefined;
|
|
484
|
-
let ownerBindingInterrupted = false;
|
|
485
421
|
if (daemonConfig.aid) {
|
|
486
422
|
console.log(`✓ 控制 AID 已存在: ${daemonConfig.aid}`);
|
|
487
423
|
try {
|
|
@@ -508,11 +444,10 @@ export async function initTail(options = {}) {
|
|
|
508
444
|
if (!options.nonInteractive && process.stdin.isTTY) {
|
|
509
445
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
510
446
|
try {
|
|
511
|
-
await handleOwnersPrompt(rl)
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
447
|
+
if (!await handleOwnersPrompt(rl))
|
|
448
|
+
return false;
|
|
449
|
+
await handleEcwebPrompt();
|
|
450
|
+
await handleAutostartPrompt();
|
|
516
451
|
}
|
|
517
452
|
finally {
|
|
518
453
|
try {
|
|
@@ -521,12 +456,16 @@ export async function initTail(options = {}) {
|
|
|
521
456
|
catch { /* ignore */ }
|
|
522
457
|
}
|
|
523
458
|
}
|
|
524
|
-
else
|
|
525
|
-
|
|
459
|
+
else {
|
|
460
|
+
if (!hasConfiguredProcessOwner(loadDaemonConfig())) {
|
|
461
|
+
console.error('❌ 未配置有效的进程级管理者 AID;请在交互式终端运行 ec init 完成配置。');
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
if (options.autoStart !== undefined) {
|
|
465
|
+
autoStartReady = applyAutostart(options.autoStart);
|
|
466
|
+
}
|
|
526
467
|
}
|
|
527
|
-
|
|
528
|
-
return false;
|
|
529
|
-
async function handleAutostartPrompt(rl) {
|
|
468
|
+
async function handleAutostartPrompt() {
|
|
530
469
|
if (options.autoStart !== undefined) {
|
|
531
470
|
autoStartReady = applyAutostart(options.autoStart);
|
|
532
471
|
return;
|
|
@@ -537,12 +476,7 @@ export async function initTail(options = {}) {
|
|
|
537
476
|
console.log(`✓ ${autostartPlatformLabel()} 登录自启已启用`);
|
|
538
477
|
return;
|
|
539
478
|
}
|
|
540
|
-
|
|
541
|
-
const answer = (await ask(rl, `\n是否启用 ${platform} 登录自启?[y/N] `)).trim().toLowerCase();
|
|
542
|
-
if (answer === 'y' || answer === 'yes')
|
|
543
|
-
autoStartReady = applyAutostart(true);
|
|
544
|
-
else
|
|
545
|
-
console.log(` 已跳过 ${platform} 登录自启(可日后重新运行 ec init 开启)`);
|
|
479
|
+
autoStartReady = applyAutostart(true);
|
|
546
480
|
}
|
|
547
481
|
function applyAutostart(enabled) {
|
|
548
482
|
const result = configureAutostart(enabled, resolvePaths().root);
|
|
@@ -560,84 +494,50 @@ export async function initTail(options = {}) {
|
|
|
560
494
|
}
|
|
561
495
|
async function handleOwnersPrompt(rl) {
|
|
562
496
|
const daemonConfigForOwners = loadDaemonConfig();
|
|
563
|
-
if (
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const result = await runDaemonOwnerQrBindFlow();
|
|
572
|
-
if (result.action === 'bound') {
|
|
573
|
-
console.log(` ✓ 已配置管理者: ${result.boundAid}`);
|
|
574
|
-
}
|
|
575
|
-
else if (result.action === 'manual') {
|
|
576
|
-
// QR 流程失败,恢复 rl 并提示手动输入
|
|
577
|
-
rl.resume();
|
|
578
|
-
await promptOwnersManually(rl);
|
|
579
|
-
}
|
|
580
|
-
else {
|
|
581
|
-
ownerBindingInterrupted = true;
|
|
582
|
-
}
|
|
497
|
+
if (!hasConfiguredProcessOwner(daemonConfigForOwners)) {
|
|
498
|
+
let ownerAid = '';
|
|
499
|
+
while (!ownerAid) {
|
|
500
|
+
const input = (await ask(rl, '请输入 EvolCore 管理者 AID: ')).trim();
|
|
501
|
+
if (!isValidAid(input)) {
|
|
502
|
+
console.log(` ⚠ 跳过非法 AID: ${input}`);
|
|
503
|
+
console.log(' 未输入合法 AID,不可跳过,请重新输入');
|
|
504
|
+
continue;
|
|
583
505
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
console.log(` ⚠ 扫码绑定不可用: ${e?.message || e}`);
|
|
588
|
-
rl.resume();
|
|
589
|
-
await promptOwnersManually(rl);
|
|
506
|
+
if (daemonConfigForOwners.aid && input.toLowerCase() === daemonConfigForOwners.aid.toLowerCase()) {
|
|
507
|
+
console.log(' ⚠ 管理者 AID 不能与本机 EvolCore 控制 AID 相同,请重新输入');
|
|
508
|
+
continue;
|
|
590
509
|
}
|
|
591
|
-
|
|
592
|
-
rl.resume();
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
console.log(' 已跳过 owners 配置(可日后编辑 daemon.json 或重跑 ec init)');
|
|
510
|
+
ownerAid = input;
|
|
596
511
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
async function promptOwnersManually(rl) {
|
|
600
|
-
const { isValidAid } = await import('../aun/aid/index.js');
|
|
601
|
-
const raw = (await ask(rl, '\n请输入 EvolCore 管理者 AID: ')).trim();
|
|
602
|
-
if (raw) {
|
|
603
|
-
const { valid, invalid } = parseOwnerAids(raw, isValidAid);
|
|
604
|
-
if (invalid.length > 0)
|
|
605
|
-
console.log(` ⚠ 跳过非法 AID: ${invalid.join(', ')}`);
|
|
606
|
-
if (valid.length > 0) {
|
|
607
|
-
saveDaemonConfig({ ...loadDaemonConfig(), owners: valid });
|
|
608
|
-
console.log(` ✓ 已配置管理者: ${valid.join(', ')}`);
|
|
512
|
+
try {
|
|
513
|
+
saveDaemonConfig({ ...daemonConfigForOwners, owner: ownerAid });
|
|
609
514
|
}
|
|
610
|
-
|
|
611
|
-
console.
|
|
515
|
+
catch (error) {
|
|
516
|
+
console.error(` ❌ 进程级管理者配置失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
517
|
+
return false;
|
|
612
518
|
}
|
|
519
|
+
console.log(`✓ 已配置进程级管理者: ${ownerAid}`);
|
|
613
520
|
}
|
|
614
|
-
|
|
615
|
-
console.log('
|
|
521
|
+
if (daemonConfigForOwners.aid) {
|
|
522
|
+
console.log('\nℹ️ 一期不在 ec init 中执行 Evol App 扫码绑定。');
|
|
523
|
+
console.log(' 请先启动 EvolCore,发起绑定后由外部 Owner SDK 明确审批:');
|
|
524
|
+
console.log(' ec aid bind <ownerAid>');
|
|
525
|
+
console.log(' 使用 ec aid bind status 查看共识与运行态同步。');
|
|
616
526
|
}
|
|
527
|
+
return true;
|
|
617
528
|
}
|
|
618
|
-
async function handleEcwebPrompt(
|
|
529
|
+
async function handleEcwebPrompt() {
|
|
619
530
|
const daemonConfigForEcweb = loadDaemonConfig();
|
|
620
531
|
if (ecwebService(daemonConfigForEcweb.services)?.enabled === undefined) {
|
|
621
|
-
const
|
|
622
|
-
if (
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
console.log(' ✓ 已启用 ECWeb(ec start 将自动在后台启动)');
|
|
631
|
-
console.log(' 提示:首次访问运行 ec watch web 查看配对码和 URL');
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
const cfg = loadDaemonConfig();
|
|
635
|
-
saveDaemonConfig({
|
|
636
|
-
...cfg,
|
|
637
|
-
services: setEcwebEnabled(cfg.services, false),
|
|
638
|
-
});
|
|
639
|
-
console.log(' 提示:安装完成后运行 ec start;如需立即打开控制台,运行 ec watch web');
|
|
640
|
-
}
|
|
532
|
+
const installResult = await ensureEcwebInstalledForInit();
|
|
533
|
+
if (installResult.ok) {
|
|
534
|
+
const cfg = loadDaemonConfig();
|
|
535
|
+
saveDaemonConfig({
|
|
536
|
+
...cfg,
|
|
537
|
+
services: setEcwebEnabled(cfg.services, true),
|
|
538
|
+
});
|
|
539
|
+
console.log(' ✓ 已启用 ECWeb(ec start 将自动在后台启动)');
|
|
540
|
+
console.log(' 提示:首次访问运行 ec watch web 查看配对码和 URL');
|
|
641
541
|
}
|
|
642
542
|
else {
|
|
643
543
|
const cfg = loadDaemonConfig();
|
|
@@ -645,7 +545,7 @@ export async function initTail(options = {}) {
|
|
|
645
545
|
...cfg,
|
|
646
546
|
services: setEcwebEnabled(cfg.services, false),
|
|
647
547
|
});
|
|
648
|
-
console.log('
|
|
548
|
+
console.log(' 提示:安装完成后运行 ec start;如需立即打开控制台,运行 ec watch web');
|
|
649
549
|
}
|
|
650
550
|
}
|
|
651
551
|
}
|
|
@@ -665,7 +565,7 @@ export async function initTail(options = {}) {
|
|
|
665
565
|
console.log('\n✓ EvolCore 初始化完成');
|
|
666
566
|
const finalCfg = loadDaemonConfig();
|
|
667
567
|
console.log(` 控制 AID: ${finalCfg.aid || '(未配置)'}`);
|
|
668
|
-
console.log(
|
|
568
|
+
console.log(' 协议 Owner: 启动后使用 ec aid bind status 核验');
|
|
669
569
|
console.log(` ECWeb 自启动: ${ecwebService(finalCfg.services)?.enabled ? '已启用' : '已禁用'}`);
|
|
670
570
|
const { agents: finalAgents } = loadAllAgents();
|
|
671
571
|
if (finalAgents.length === 0) {
|
|
@@ -737,7 +637,8 @@ function emitResult(result, format) {
|
|
|
737
637
|
process.stdout.write(JSON.stringify(result) + '\n');
|
|
738
638
|
}
|
|
739
639
|
else if (result.success) {
|
|
740
|
-
console.log(`✓ 初始化成功: controlAid=${result.controlAid}
|
|
640
|
+
console.log(`✓ 初始化成功: controlAid=${result.controlAid},Owner 绑定: ${result.bindingStatus}`);
|
|
641
|
+
console.log(` 启动服务后查询: ec aid bind status --subject ${result.controlAid}`);
|
|
741
642
|
}
|
|
742
643
|
else {
|
|
743
644
|
console.error(`❌ ${result.error.code}: ${result.error.message}`);
|
|
@@ -768,7 +669,7 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
768
669
|
if (!isValidAid(opts.owner)) {
|
|
769
670
|
fail('INVALID_OWNER', `invalid owner AID: ${opts.owner}`, EXIT_USAGE, format);
|
|
770
671
|
}
|
|
771
|
-
const ownerAid = opts.owner;
|
|
672
|
+
const ownerAid = opts.owner.toLowerCase();
|
|
772
673
|
// ── 2. 单进程互斥 ──
|
|
773
674
|
const aliveMains = scanInstances().mains.filter(m => m.alive);
|
|
774
675
|
if (aliveMains.length > 0) {
|
|
@@ -776,9 +677,9 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
776
677
|
fail('DAEMON_RUNNING', `EvolCore daemon is running (PID: ${pids}); run 'ec stop' first`, EXIT_USAGE, format);
|
|
777
678
|
}
|
|
778
679
|
// ── 3. baseagent 探测 + 校验 ──
|
|
779
|
-
const available = dependencies.availableBaseagents ?? detectAvailable();
|
|
780
|
-
if (available.length === 0
|
|
781
|
-
fail('BASEAGENT_UNAVAILABLE', 'no usable baseagent detected (install claude/codex/gemini or
|
|
680
|
+
const available = dependencies.availableBaseagents ?? await detectAvailable();
|
|
681
|
+
if (available.length === 0) {
|
|
682
|
+
fail('BASEAGENT_UNAVAILABLE', 'no usable baseagent detected (install claude/codex/gemini or use bundled ecagent)', EXIT_USAGE, format);
|
|
782
683
|
}
|
|
783
684
|
let chosenBaseagent;
|
|
784
685
|
if (opts.baseagent) {
|
|
@@ -789,17 +690,12 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
789
690
|
const reason = opts.baseagent === 'codex' ? getCodexAppServerAvailability().reason : undefined;
|
|
790
691
|
fail('BASEAGENT_UNAVAILABLE', `${opts.baseagent} not available${reason ? `: ${reason}` : ''}`, EXIT_USAGE, format);
|
|
791
692
|
}
|
|
792
|
-
if (opts.baseagent === 'ecagent') {
|
|
793
|
-
const reason = ecagentUnavailableReason();
|
|
794
|
-
if (reason)
|
|
795
|
-
fail('BASEAGENT_UNAVAILABLE', reason, EXIT_USAGE, format);
|
|
796
|
-
}
|
|
797
693
|
chosenBaseagent = opts.baseagent;
|
|
798
694
|
}
|
|
799
695
|
else {
|
|
800
696
|
const defaultBaseagent = pickDefault(available);
|
|
801
697
|
if (!defaultBaseagent) {
|
|
802
|
-
fail('BASEAGENT_UNAVAILABLE', 'ecagent is optional; pass --baseagent ecagent
|
|
698
|
+
fail('BASEAGENT_UNAVAILABLE', 'ecagent is optional; pass --baseagent ecagent to select it explicitly', EXIT_USAGE, format);
|
|
803
699
|
}
|
|
804
700
|
chosenBaseagent = defaultBaseagent;
|
|
805
701
|
}
|
|
@@ -819,16 +715,8 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
819
715
|
}
|
|
820
716
|
projectsDefaultPath = opts.projectpath;
|
|
821
717
|
}
|
|
822
|
-
// ── 5.
|
|
718
|
+
// ── 5. 读取现有配置;协议冲突由 SDK 注册意图及共识判定 ──
|
|
823
719
|
const existingCfg = loadDaemonConfig();
|
|
824
|
-
const existingOwners = existingCfg.owners ?? [];
|
|
825
|
-
const sameOwner = existingOwners.length === 1 && existingOwners[0] === ownerAid;
|
|
826
|
-
const differentOwner = existingOwners.length > 0 && !sameOwner;
|
|
827
|
-
if (differentOwner && !opts.force) {
|
|
828
|
-
fail('OWNER_EXISTS', `owners already set to [${existingOwners.join(', ')}]; use --force to override`, EXIT_USAGE, format);
|
|
829
|
-
}
|
|
830
|
-
const forced = differentOwner && !!opts.force;
|
|
831
|
-
const previousOwners = forced ? [...existingOwners] : undefined;
|
|
832
720
|
// ── 6. EC Web 安装(先安装成功,再写 enabled 配置)──
|
|
833
721
|
if (opts.ecweb === true) {
|
|
834
722
|
const ensureEcweb = dependencies.ensureEcweb ?? (() => ensureEcwebInstalledForInit({ quiet: true }));
|
|
@@ -860,13 +748,14 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
860
748
|
if (!controlAid) {
|
|
861
749
|
try {
|
|
862
750
|
const aidDomain = resolveControlAidDomain(existingCfg.aun?.defaultAidDomain);
|
|
863
|
-
const { aid } = await generateControlAid(aidDomain);
|
|
751
|
+
const { aid } = await generateControlAid(aidDomain, { silent: format === 'json' });
|
|
864
752
|
controlAid = aid;
|
|
865
753
|
}
|
|
866
754
|
catch (e) {
|
|
867
755
|
fail('CONTROL_AID_CREATE_FAILED', `control AID creation failed: ${e?.message || e}`, EXIT_RUNTIME, format);
|
|
868
756
|
}
|
|
869
757
|
}
|
|
758
|
+
let controlAgentMdError;
|
|
870
759
|
if (controlAid) {
|
|
871
760
|
const certPath = path.join(resolvePaths().root, 'AIDs', controlAid, 'public', 'cert.pem');
|
|
872
761
|
if (!fs.existsSync(certPath)) {
|
|
@@ -874,6 +763,7 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
874
763
|
// cannot be signed or uploaded by this process. Avoid entering the SDK
|
|
875
764
|
// network path during non-interactive init; later daemon startup can
|
|
876
765
|
// retry once the identity material is provisioned.
|
|
766
|
+
controlAgentMdError = `Local certificate not found for ${controlAid}`;
|
|
877
767
|
console.error(`control AID agent.md publish skipped: local certificate not found for ${controlAid}`);
|
|
878
768
|
}
|
|
879
769
|
else {
|
|
@@ -881,6 +771,7 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
881
771
|
await ensureControlAgentMd(controlAid);
|
|
882
772
|
}
|
|
883
773
|
catch (e) {
|
|
774
|
+
controlAgentMdError = installErrorMessage(e);
|
|
884
775
|
// A registered control AID remains usable when the Name Service is
|
|
885
776
|
// temporarily unavailable; startup and the next init retry publication.
|
|
886
777
|
if (format === 'json') {
|
|
@@ -894,13 +785,12 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
894
785
|
}
|
|
895
786
|
}
|
|
896
787
|
}
|
|
897
|
-
// ── 9.
|
|
788
|
+
// ── 9. 先保存控制身份,再调用 Owner 绑定服务;不写本地 Owner 授权 ──
|
|
898
789
|
try {
|
|
899
790
|
const next = {
|
|
900
791
|
...existingCfg,
|
|
901
792
|
$schema_version: existingCfg.$schema_version ?? 1,
|
|
902
793
|
aid: controlAid,
|
|
903
|
-
owners: [ownerAid],
|
|
904
794
|
...(opts.ecweb === true
|
|
905
795
|
? { services: setEcwebEnabled(existingCfg.services, true) }
|
|
906
796
|
: {}),
|
|
@@ -924,13 +814,21 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
924
814
|
}
|
|
925
815
|
autostartWarning = autostart.warning;
|
|
926
816
|
}
|
|
927
|
-
// ── 10.
|
|
817
|
+
// ── 10. 复用 Agent 创建流程的显式 Owner 绑定;不等待人工审批 ──
|
|
818
|
+
let binding;
|
|
819
|
+
try {
|
|
820
|
+
binding = await (dependencies.submitRegistration ?? submitControlAidRegistration)(controlAid, ownerAid, {
|
|
821
|
+
...(controlAgentMdError ? { agentMdError: controlAgentMdError } : {}),
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
catch (error) {
|
|
825
|
+
binding = { status: 'failed', error: { code: 'BIND_SUBMIT_FAILED', message: installErrorMessage(error) } };
|
|
826
|
+
}
|
|
928
827
|
const result = {
|
|
929
828
|
type: 'init.result',
|
|
930
829
|
success: true,
|
|
931
830
|
controlAid: controlAid,
|
|
932
831
|
ownerAid,
|
|
933
|
-
owners: [ownerAid],
|
|
934
832
|
ecwebEnabled: opts.ecweb === true || ecwebService(existingCfg.services)?.enabled === true,
|
|
935
833
|
baseagent: chosenBaseagent,
|
|
936
834
|
projectsDefaultPath: projectsDefaultPath ?? null,
|
|
@@ -938,7 +836,16 @@ export async function cmdInitNonInteractive(opts, dependencies = {}) {
|
|
|
938
836
|
daemonConfigPath: p.daemonConfig,
|
|
939
837
|
...(autostartBackend ? { autoStartBackend: autostartBackend } : {}),
|
|
940
838
|
...(autostartWarning ? { autoStartWarning: autostartWarning } : {}),
|
|
941
|
-
|
|
839
|
+
bindingStatus: binding.status,
|
|
840
|
+
binding,
|
|
841
|
+
bindingCommand: `ec aid bind ${ownerAid} --subject ${controlAid}`,
|
|
942
842
|
};
|
|
843
|
+
if (binding.status === 'failed' || binding.status === 'unknown') {
|
|
844
|
+
const error = binding.error ?? { code: 'BIND_SUBMIT_FAILED', message: 'Registration invitation was not confirmed' };
|
|
845
|
+
emitResult({ ...result, success: false, initialized: true, error }, format);
|
|
846
|
+
process.exitCode = ['INVALID_OWNER', 'OWNER_INTENT_CONFLICT', 'OWNER_ALREADY_BOUND', 'BIND_CONFLICT'].includes(error.code)
|
|
847
|
+
? EXIT_USAGE : EXIT_RUNTIME;
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
943
850
|
emitResult(result, format);
|
|
944
851
|
}
|
|
@@ -3,6 +3,7 @@ import { ipcQuery } from '../ipc.js';
|
|
|
3
3
|
import { readDelegationCredential } from '../core/auth/agent-delegation.js';
|
|
4
4
|
import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
|
|
5
5
|
import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
|
|
6
|
+
import { parseTimeArg, TIME_ARG_FORMATS } from './cli-argv.js';
|
|
6
7
|
export async function cmdQueue(args) {
|
|
7
8
|
args = canonicalizeEvolcoreCommandArgv(['ec', 'queue', ...args]).slice(2);
|
|
8
9
|
if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
|
|
@@ -12,8 +13,10 @@ export async function cmdQueue(args) {
|
|
|
12
13
|
|
|
13
14
|
查询:
|
|
14
15
|
--agent <aid> 必填,目标 agent(如 mybot.agentid.pub)
|
|
15
|
-
--after <time> 只显示 adapter
|
|
16
|
-
--before <time> 只显示 adapter
|
|
16
|
+
--after <time> 只显示 adapter 接收时间晚于该值的消息
|
|
17
|
+
--before <time> 只显示 adapter 接收时间早于该值的消息
|
|
18
|
+
<time>:epoch 毫秒/秒、ISO 8601、YYYY-MM-DD HH:mm:ss [+08:00]、
|
|
19
|
+
YYYY/MM/DD HH:mm:ss、相对时间 30s/5m/2h/1d、now
|
|
17
20
|
--showid 显示 messageId
|
|
18
21
|
--full 显示完整消息内容(不截断)
|
|
19
22
|
--format json 以 JSON 格式输出
|
|
@@ -143,9 +146,9 @@ JSON 时间字段:
|
|
|
143
146
|
function parseQueueTime(value, flag) {
|
|
144
147
|
if (value === undefined)
|
|
145
148
|
return undefined;
|
|
146
|
-
const parsed =
|
|
147
|
-
if (
|
|
148
|
-
console.error(`❌ ${flag}
|
|
149
|
+
const parsed = parseTimeArg(value);
|
|
150
|
+
if (parsed === undefined) {
|
|
151
|
+
console.error(`❌ ${flag} 不是有效时间: ${value}(支持 ${TIME_ARG_FORMATS})`);
|
|
149
152
|
process.exit(1);
|
|
150
153
|
}
|
|
151
154
|
return parsed;
|
|
@@ -181,9 +184,9 @@ export function parseQueueOperationArgv(argv) {
|
|
|
181
184
|
const value = flags.get(flag);
|
|
182
185
|
if (value === undefined)
|
|
183
186
|
return undefined;
|
|
184
|
-
const parsed =
|
|
185
|
-
if (
|
|
186
|
-
throw new Error(`Invalid ${flag}
|
|
187
|
+
const parsed = parseTimeArg(value);
|
|
188
|
+
if (parsed === undefined)
|
|
189
|
+
throw new Error(`Invalid ${flag}(支持 ${TIME_ARG_FORMATS})`);
|
|
187
190
|
return parsed;
|
|
188
191
|
};
|
|
189
192
|
const after = time('--after');
|