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.
Files changed (224) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +6 -0
  3. package/bin/install-codex-managed-hooks.mjs +20 -3
  4. package/dist/agents/baseagent-availability.js +1 -1
  5. package/dist/agents/baseagent.js +88 -0
  6. package/dist/agents/claude-runner.js +59 -12
  7. package/dist/agents/codex/app-server-client.js +18 -1
  8. package/dist/agents/codex-runner.js +262 -21
  9. package/dist/agents/ecagent-runner.js +47 -11
  10. package/dist/agents/gemini-runner.js +36 -12
  11. package/dist/aun/aid/client.js +4 -3
  12. package/dist/aun/aid/control-aid.js +270 -8
  13. package/dist/aun/aid/identity.js +6 -3
  14. package/dist/aun/aid/ownership-operation.js +58 -0
  15. package/dist/aun/aid/store.js +1 -0
  16. package/dist/aun/group/fs-download.js +67 -2
  17. package/dist/aun/group/history.js +20 -5
  18. package/dist/aun/group/operations.js +8 -2
  19. package/dist/aun/menu/client.js +39 -2
  20. package/dist/aun/menu/transport.js +1 -1
  21. package/dist/aun/msg/history.js +43 -4
  22. package/dist/aun/msg/managed-operation.js +30 -53
  23. package/dist/aun/msg/p2p.js +51 -15
  24. package/dist/aun/outbox.js +4 -0
  25. package/dist/channels/aun.js +260 -73
  26. package/dist/channels/daemon.js +6 -4
  27. package/dist/channels/feishu.js +3 -0
  28. package/dist/cli/agent-command.js +161 -223
  29. package/dist/cli/agent-create.js +190 -223
  30. package/dist/cli/agent.js +3 -1
  31. package/dist/cli/aid-bind-command.js +53 -0
  32. package/dist/cli/aun-commands.js +384 -91
  33. package/dist/cli/bench.js +1 -1
  34. package/dist/cli/cli-argv.js +74 -0
  35. package/dist/cli/daemon-commands.js +105 -74
  36. package/dist/cli/diag.js +1 -1
  37. package/dist/cli/fs-command.js +18 -19
  38. package/dist/cli/getmeta-command.js +159 -6
  39. package/dist/cli/index.js +6 -12
  40. package/dist/cli/init-channel.js +8 -55
  41. package/dist/cli/init.js +125 -218
  42. package/dist/cli/queue-command.js +11 -8
  43. package/dist/cli/restart-monitor.js +177 -85
  44. package/dist/cli/session-command.js +1 -1
  45. package/dist/cli/stats.js +7 -5
  46. package/dist/cli/thread-command.js +103 -30
  47. package/dist/cli/trigger-command.js +1 -1
  48. package/dist/cli/watch-msg-diag.js +1 -0
  49. package/dist/config/access-policy.js +2 -2
  50. package/dist/config/boot-log.js +14 -11
  51. package/dist/config/config-field-policy.js +9 -1
  52. package/dist/config/config-manager.js +176 -90
  53. package/dist/config/config-operation-service.js +7 -14
  54. package/dist/config/contact-book-store.js +142 -26
  55. package/dist/config/contact-book.js +4 -2
  56. package/dist/config/lifecycle.js +1 -1
  57. package/dist/config/owner-config.js +96 -0
  58. package/dist/config/peer-role-resolver.js +12 -18
  59. package/dist/config/providers-config.js +382 -0
  60. package/dist/config/providers-import.js +74 -0
  61. package/dist/config/providers-management.js +328 -0
  62. package/dist/config/providers.js +22 -0
  63. package/dist/config/resolved-config-op.js +17 -14
  64. package/dist/config/snapshot.js +28 -16
  65. package/dist/config-store.js +18 -14
  66. package/dist/core/agent-ipc-registration.js +21 -63
  67. package/dist/core/agent-runtime.js +16 -5
  68. package/dist/core/auth/agent-delegation.js +199 -25
  69. package/dist/core/auth/auth-gateway.js +44 -2
  70. package/dist/core/auth/authorization-denial.js +1 -1
  71. package/dist/core/auth/debug-context.js +2 -1
  72. package/dist/core/auth/delegation-authorization.js +2 -2
  73. package/dist/core/auth/delegation-diagnostics.js +4 -1
  74. package/dist/core/auth/operation-authorizer.js +10 -1
  75. package/dist/core/auth/operation-catalog.js +19 -1
  76. package/dist/core/bootstrap-service.js +43 -20
  77. package/dist/core/channel-loader.js +0 -1
  78. package/dist/core/channel-runtime.js +30 -4
  79. package/dist/core/command/agent-control.js +196 -37
  80. package/dist/core/command/cli-intent-parser.js +60 -4
  81. package/dist/core/command/command-handler.js +212 -60
  82. package/dist/core/command/connect-menu.js +1 -0
  83. package/dist/core/command/diag-service.js +5 -4
  84. package/dist/core/command/file-search.js +368 -0
  85. package/dist/core/command/menu-catalog.js +2 -1
  86. package/dist/core/command/menu-handler.js +292 -107
  87. package/dist/core/command/menu-protocol.js +23 -0
  88. package/dist/core/command/role-menu.js +7 -19
  89. package/dist/core/command/skill-slash.js +130 -25
  90. package/dist/core/command/slash-handler.js +101 -53
  91. package/dist/core/command/topic-slash.js +16 -5
  92. package/dist/core/daemon-bootstrap.js +7 -1
  93. package/dist/core/daemon-control.js +19 -1
  94. package/dist/core/daemon-lifecycle.js +2 -1
  95. package/dist/core/event-catalog.js +2 -0
  96. package/dist/core/evolagent-registry.js +13 -2
  97. package/dist/core/evolagent.js +3 -6
  98. package/dist/core/handoff/ipc-registration.js +2 -2
  99. package/dist/core/handoff/runtime.js +40 -6
  100. package/dist/core/handoff/store.js +1 -0
  101. package/dist/core/inference/text-inference.js +95 -6
  102. package/dist/core/ipc-registration.js +43 -24
  103. package/dist/core/memory/consolidation-context.js +4 -1
  104. package/dist/core/memory/consolidation.js +25 -14
  105. package/dist/core/message/aun-ipc-sender.js +296 -88
  106. package/dist/core/message/aun-request-registry.js +226 -0
  107. package/dist/core/message/create-status.js +33 -4
  108. package/dist/core/message/message-bridge.js +62 -13
  109. package/dist/core/message/message-log.js +0 -1
  110. package/dist/core/message/message-queue.js +4 -1
  111. package/dist/core/message/message-utils.js +8 -1
  112. package/dist/core/message/peer-mode.js +17 -9
  113. package/dist/core/message/response-engine.js +266 -124
  114. package/dist/core/message/retry-scheduler.js +11 -8
  115. package/dist/core/model/catalog-service.js +60 -18
  116. package/dist/core/model/model-catalog.js +112 -9
  117. package/dist/core/model/model-fallback.js +94 -26
  118. package/dist/core/ownership/owner-resolver.js +687 -0
  119. package/dist/core/permission/approval-gateway.js +196 -62
  120. package/dist/core/permission/ec-command-parser.js +138 -25
  121. package/dist/core/permission/filesystem-approval-scope.js +141 -0
  122. package/dist/core/permission/protected-paths.js +14 -1
  123. package/dist/core/permission/sandbox-runtime.js +171 -18
  124. package/dist/core/permission/tool-policy.js +13 -2
  125. package/dist/core/role/runtime-policy.js +3 -4
  126. package/dist/core/session/session-idle-monitor.js +10 -8
  127. package/dist/core/session/session-manager.js +72 -45
  128. package/dist/core/session/session-mapper.js +18 -7
  129. package/dist/core/session/session-renew.js +5 -4
  130. package/dist/core/session/session-title.js +2 -1
  131. package/dist/core/session/session-turn-coordinator.js +4 -2
  132. package/dist/core/skill/index-generator.js +2 -16
  133. package/dist/core/task/task-recovery-service.js +15 -2
  134. package/dist/core/thread/command-parser.js +28 -13
  135. package/dist/core/thread/index.js +1 -0
  136. package/dist/core/thread/ipc-operation.js +11 -8
  137. package/dist/core/thread/thread-operation.js +79 -44
  138. package/dist/core/thread/thread-route.js +54 -6
  139. package/dist/core/thread/thread-service.js +236 -45
  140. package/dist/core/thread/topic-id.js +248 -0
  141. package/dist/eck/kit-renderer.js +1 -1
  142. package/dist/eck/message-renderer.js +12 -2
  143. package/dist/index.js +50 -27
  144. package/dist/ipc.js +59 -6
  145. package/dist/paths.js +1 -0
  146. package/dist/product.js +1 -0
  147. package/dist/response-system/engines/v1/proactive-flow.js +10 -3
  148. package/dist/stats/db.js +8 -0
  149. package/dist/stats/writer.js +26 -4
  150. package/dist/trigger/authorization.js +48 -3
  151. package/dist/trigger/feedback.js +28 -10
  152. package/dist/trigger/ipc-service.js +86 -10
  153. package/dist/trigger/local-files.js +55 -23
  154. package/dist/trigger/scheduler.js +57 -11
  155. package/dist/trigger/system-definitions.js +1 -0
  156. package/dist/trigger/validation.js +44 -15
  157. package/dist/utils/aid-bind.js +17 -297
  158. package/dist/utils/avatar-upload.js +16 -4
  159. package/dist/utils/cross-platform.js +115 -36
  160. package/dist/utils/ecweb-supervisor.js +1 -1
  161. package/dist/utils/ecweb-utils.js +8 -1
  162. package/dist/utils/error-utils.js +44 -6
  163. package/dist/utils/instance-registry.js +12 -2
  164. package/dist/utils/npm-ops.js +102 -27
  165. package/dist/utils/package-version-info.js +72 -27
  166. package/dist/utils/restart-safety.js +50 -0
  167. package/dist/utils/upgrade-jobs.js +304 -0
  168. package/dist/utils/windows-autostart.js +17 -10
  169. package/kits/docs/INDEX.md +5 -0
  170. package/kits/docs/aun/ABILITY_CALLING.md +239 -0
  171. package/kits/docs/evolcore/INDEX.md +14 -3
  172. package/kits/docs/evolcore/agent-create.md +55 -141
  173. package/kits/docs/evolcore/agent.md +38 -16
  174. package/kits/docs/evolcore/aid.md +34 -0
  175. package/kits/docs/evolcore/config.md +20 -1
  176. package/kits/docs/evolcore/event.md +2 -2
  177. package/kits/docs/evolcore/fs.md +18 -2
  178. package/kits/docs/evolcore/group-collaboration.md +13 -246
  179. package/kits/docs/evolcore/group.md +2 -1
  180. package/kits/docs/evolcore/memory-consolidation-batches.md +1 -1
  181. package/kits/docs/evolcore/menu-protocol.md +65 -1
  182. package/kits/docs/evolcore/msg.md +64 -2
  183. package/kits/docs/evolcore/skill.md +86 -0
  184. package/kits/docs/evolcore/stats.md +6 -0
  185. package/kits/docs/evolcore/task.md +2 -0
  186. package/kits/docs/evolcore/thread-chain.md +145 -51
  187. package/kits/docs/evolcore/trigger.md +48 -3
  188. package/kits/eck_manifest.json +21 -0
  189. package/kits/eck_message_manifest.json +4 -4
  190. package/kits/migrations/migrate-role-config-v5.mjs +20 -7
  191. package/kits/rules/01-overview.md +2 -1
  192. package/kits/rules/03-identity.md +3 -1
  193. package/kits/rules/04-relation.md +1 -1
  194. package/kits/rules/07-memory-and-thread.md +1 -1
  195. package/kits/schemas/_meta.json +16 -1
  196. package/kits/schemas/agent-config.schema.13.json +44 -2
  197. package/kits/schemas/contact-book.schema.3.json +5 -0
  198. package/kits/schemas/daemon.schema.6.json +3 -1
  199. package/kits/schemas/daemon.schema.8.json +329 -0
  200. package/kits/schemas/defaults.schema.5.json +39 -3
  201. package/kits/schemas/providers.schema.1.json +76 -0
  202. package/kits/schemas/relation-config.schema.9.json +5 -1
  203. package/kits/skills/.switches.json +28 -0
  204. package/kits/skills/aid-ability/SKILL.md +214 -0
  205. package/kits/skills/ec-agent-create/SKILL.md +162 -0
  206. package/kits/skills/ec-group/SKILL.md +2 -1
  207. package/kits/skills/ec-group-collaboration/SKILL.md +228 -0
  208. package/kits/skills/ec-identity/SKILL.md +143 -0
  209. package/kits/skills/ec-skill/scripts/cli.mjs +36 -3
  210. package/kits/skills/ec-skill/scripts/skill.mjs +202 -15
  211. package/kits/skills/ec-trigger/SKILL.md +167 -0
  212. package/kits/skills/ec-trigger/references/examples.md +153 -0
  213. package/kits/skills/thread-ops/SKILL.md +108 -420
  214. package/kits/templates/message-fragments/thread-context.md +1 -2
  215. package/kits/templates/message-fragments/trigger-thread-check.md +1 -1
  216. package/kits/templates/roles/member.json +1 -1
  217. package/kits/templates/roles/visitor.json +1 -0
  218. package/kits/templates/system-fragments/bootstrap.md +1 -0
  219. package/kits/templates/system-fragments/channel.md +2 -1
  220. package/kits/templates/system-fragments/commands.md +5 -4
  221. package/kits/templates/system-fragments/identity.md +2 -0
  222. package/kits/templates/system-fragments/session.md +1 -1
  223. package/kits/templates/system-fragments/venue.md +1 -1
  224. 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 { DEFAULT_ECAGENT_BASE_URL, resolveEcagentConfig } from '../agents/baseagent.js';
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, isInitCancelledError, printInitCancelHint } from './init-cancel.js';
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 ecagentUnavailableReason() {
67
- try {
68
- resolveEcagentConfig({ agents: { ecagent: {} } });
69
- return undefined;
70
- }
71
- catch (error) {
72
- return error instanceof Error ? error.message : String(error);
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, ecagentConfig) {
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 = ecagentConfig ?? 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, ecagentConfig) {
91
- saveDefaultsSafe(buildDefaults(chosen, available, projectsDefaultPath, ecagentConfig));
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 || !Array.isArray(daemon.owners) || daemon.owners.length === 0)
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('检测到可用的 baseagent:');
268
- for (const b of available) {
269
- const version = b === 'codex' ? codexAvailability.version : undefined;
270
- console.log(` ● ${b}${version ? ` (CLI ${version})` : ''}`);
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 + owners。
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/owners)。
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,并配置 API key');
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 = pickDefault(available);
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, ecagentConfig);
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, ecagentConfig);
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 + owners(可单独调用,不走 baseagent 向导)。 */
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
- if (!ownerBindingInterrupted) {
513
- await handleEcwebPrompt(rl);
514
- await handleAutostartPrompt(rl);
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 if (options.autoStart !== undefined) {
525
- autoStartReady = applyAutostart(options.autoStart);
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
- if (ownerBindingInterrupted)
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
- const platform = autostartPlatformLabel();
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 (daemonConfigForOwners.aid && (!daemonConfigForOwners.owners || daemonConfigForOwners.owners.length === 0)) {
564
- const needOwner = (await ask(rl, '\n是否配置进程级管理者(Owner AID)?[Y/n] ')).trim().toLowerCase();
565
- if (!needOwner || needOwner === 'y' || needOwner === 'yes') {
566
- console.log('\n📡 进程级管理者绑定 — 请用 evol app 扫描二维码\n');
567
- // QR 绑定流程需要暂时关闭 rl,因为它会创建自己的输入监听
568
- rl.pause();
569
- try {
570
- const { runDaemonOwnerQrBindFlow } = await import('./init-channel.js');
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
- catch (e) {
585
- if (isInitCancelledError(e))
586
- throw e;
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
- // QR 流程成功完成后恢复 rl
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
- else {
611
- console.log(' 未输入合法 AID,已跳过 owners 配置');
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
- else {
615
- console.log(' 已跳过 owners 配置(可日后编辑 daemon.json 或重跑 ec init)');
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(rl) {
529
+ async function handleEcwebPrompt() {
619
530
  const daemonConfigForEcweb = loadDaemonConfig();
620
531
  if (ecwebService(daemonConfigForEcweb.services)?.enabled === undefined) {
621
- const ans = (await ask(rl, '\n是否在 ec start 时自动启动 ECWeb 控制台?[y/N] ')).trim().toLowerCase();
622
- if (ans === 'y' || ans === 'yes') {
623
- const installResult = await ensureEcwebInstalledForInit();
624
- if (installResult.ok) {
625
- const cfg = loadDaemonConfig();
626
- saveDaemonConfig({
627
- ...cfg,
628
- services: setEcwebEnabled(cfg.services, true),
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(' 已跳过(可日后运行 ec watch web 手动启动,或编辑 daemon.json)');
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(` 管理者: ${finalCfg.owners?.join(', ') || '(未配置)'}`);
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} ownerAid=${result.ownerAid}`);
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 || (available.length === 1 && available[0] === 'ecagent' && ecagentUnavailableReason())) {
781
- fail('BASEAGENT_UNAVAILABLE', 'no usable baseagent detected (install claude/codex/gemini or configure bundled ecagent)', EXIT_USAGE, format);
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 after configuring its API key', EXIT_USAGE, format);
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. owner 冲突检测 ──
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. 写 daemon.json(aid + owners + ecweb)──
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. 输出 init.result ──
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
- ...(forced ? { forced: true, previousOwners } : {}),
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 接收时间晚于该值的消息(epoch ms 或 ISO)
16
- --before <time> 只显示 adapter 接收时间早于该值的消息(epoch ms 或 ISO)
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 = /^\d+$/.test(value) ? Number(value) : Date.parse(value);
147
- if (!Number.isFinite(parsed)) {
148
- console.error(`❌ ${flag} 必须是 epoch 毫秒或 ISO 时间: ${value}`);
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 = /^\d+$/.test(value) ? Number(value) : Date.parse(value);
185
- if (!Number.isFinite(parsed))
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');