evolcore 0.0.31 → 0.0.33

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 (179) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/bin/install-codex-managed-hooks.mjs +124 -37
  3. package/dist/agents/claude-runner.js +29 -2
  4. package/dist/agents/codex/app-server-client.js +3 -0
  5. package/dist/agents/codex/diagnostics.js +76 -44
  6. package/dist/agents/codex-runner.js +51 -24
  7. package/dist/agents/ecagent-runner.js +9 -13
  8. package/dist/agents/gemini-runner.js +4 -0
  9. package/dist/aun/aid/store.js +0 -81
  10. package/dist/aun/group/fs-download.js +1 -10
  11. package/dist/aun/group/operations.js +0 -1
  12. package/dist/aun/msg/history.js +1 -0
  13. package/dist/aun/msg/managed-operation.js +130 -32
  14. package/dist/aun/msg/p2p.js +0 -1
  15. package/dist/aun/outbox.js +50 -1
  16. package/dist/aun/service-proxy.js +12 -18
  17. package/dist/aun/storage/index.js +29 -0
  18. package/dist/channels/aun.js +38 -137
  19. package/dist/channels/daemon.js +257 -2
  20. package/dist/cli/agent-command.js +64 -31
  21. package/dist/cli/agent-create.js +43 -24
  22. package/dist/cli/agent.js +16 -70
  23. package/dist/cli/aun-commands.js +512 -32
  24. package/dist/cli/contact.js +8 -2
  25. package/dist/cli/ctl-command.js +1 -2
  26. package/dist/cli/daemon-commands.js +82 -13
  27. package/dist/cli/debug-mode.js +154 -0
  28. package/dist/cli/diag.js +2 -2
  29. package/dist/cli/handoff-command.js +18 -5
  30. package/dist/cli/index.js +81 -64
  31. package/dist/cli/init.js +2 -2
  32. package/dist/cli/managed-command-guard.js +5 -0
  33. package/dist/cli/memory-command.js +93 -12
  34. package/dist/cli/model.js +14 -138
  35. package/dist/cli/queue-command.js +51 -0
  36. package/dist/cli/response.js +5 -54
  37. package/dist/cli/session-command.js +194 -0
  38. package/dist/cli/skill-command.js +85 -3
  39. package/dist/cli/stats.js +10 -4
  40. package/dist/cli/task-command.js +1 -0
  41. package/dist/cli/task-context.js +16 -0
  42. package/dist/cli/thread-command.js +620 -0
  43. package/dist/cli/trigger-command.js +76 -50
  44. package/dist/config/builtin-roles.js +9 -7
  45. package/dist/config/config-field-policy.js +2 -3
  46. package/dist/config/config-manager.js +7 -2
  47. package/dist/config/resolved-config-op.js +3 -0
  48. package/dist/config-store.js +15 -0
  49. package/dist/core/agent-ipc-registration.js +65 -22
  50. package/dist/core/auth/agent-delegation.js +42 -2
  51. package/dist/core/auth/debug-context.js +139 -0
  52. package/dist/core/auth/delegation-authorization.js +1 -0
  53. package/dist/core/auth/operation-authorizer.js +24 -1
  54. package/dist/core/auth/operation-catalog.js +44 -3
  55. package/dist/core/background-session/session-cleanup.js +212 -0
  56. package/dist/core/background-session/types.js +10 -0
  57. package/dist/core/bootstrap-messages.js +1 -1
  58. package/dist/core/bootstrap-service.js +6 -3
  59. package/dist/core/command/command-handler.js +224 -45
  60. package/dist/core/command/diag-service.js +5 -1
  61. package/dist/core/command/memory-slash.js +6 -2
  62. package/dist/core/command/menu-catalog.js +48 -1
  63. package/dist/core/command/menu-handler.js +92 -16
  64. package/dist/core/command/menu-protocol.js +24 -1
  65. package/dist/core/command/skill-slash.js +322 -0
  66. package/dist/core/command/slash-gate.js +6 -4
  67. package/dist/core/command/slash-handler.js +193 -13
  68. package/dist/core/command/topic-slash.js +528 -0
  69. package/dist/core/evolagent-registry.js +20 -5
  70. package/dist/core/handoff/ipc-registration.js +38 -0
  71. package/dist/core/handoff/runtime.js +5 -11
  72. package/dist/core/handoff/store.js +5 -0
  73. package/dist/core/ipc-registration.js +210 -9
  74. package/dist/core/memory/consolidation-context.js +49 -16
  75. package/dist/core/memory/consolidation-ops-records.js +35 -0
  76. package/dist/core/memory/consolidation-queue-format.js +21 -0
  77. package/dist/core/memory/consolidation.js +174 -180
  78. package/dist/core/message/aun-ipc-sender.js +207 -8
  79. package/dist/core/message/im-renderer.js +149 -6
  80. package/dist/core/message/message-bridge.js +13 -3
  81. package/dist/core/message/message-log.js +1 -0
  82. package/dist/core/message/message-queue.js +131 -3
  83. package/dist/core/message/peer-mode.js +6 -1
  84. package/dist/core/message/response-engine.js +379 -69
  85. package/dist/core/message/subtask-tool-projection.js +140 -0
  86. package/dist/core/model/catalog-service.js +17 -12
  87. package/dist/core/permission/ec-command-parser.js +126 -7
  88. package/dist/core/permission/sandbox-runtime.js +14 -1
  89. package/dist/core/session/session-idle-monitor.js +249 -22
  90. package/dist/core/session/session-manager.js +54 -9
  91. package/dist/core/skill/command-parser.js +13 -0
  92. package/dist/core/skill/index-generator.js +4 -1
  93. package/dist/core/skill/startup.js +41 -0
  94. package/dist/core/skill/switch-resolver.js +55 -29
  95. package/dist/core/task/task-recovery-service.js +2 -0
  96. package/dist/core/task/task-resume-operation.js +11 -0
  97. package/dist/core/thread/command-parser.js +125 -0
  98. package/dist/core/thread/index.js +1 -0
  99. package/dist/core/thread/ipc-operation.js +95 -0
  100. package/dist/core/thread/thread-context-storage.js +131 -0
  101. package/dist/core/thread/thread-operation.js +258 -0
  102. package/dist/core/thread/thread-route.js +33 -0
  103. package/dist/core/thread/thread-service.js +777 -0
  104. package/dist/core/thread/types.js +1 -0
  105. package/dist/eck/message-renderer.js +35 -0
  106. package/dist/index.js +10 -7
  107. package/dist/ipc.js +234 -17
  108. package/dist/paths.js +23 -0
  109. package/dist/response-system/engines/v1/proactive-flow.js +169 -80
  110. package/dist/trigger/authorization.js +59 -29
  111. package/dist/trigger/feedback.js +7 -1
  112. package/dist/trigger/ipc-service.js +49 -35
  113. package/dist/trigger/parser.js +63 -1
  114. package/dist/trigger/script-sandbox.js +58 -77
  115. package/dist/trigger/validation.js +14 -0
  116. package/dist/utils/error-utils.js +22 -1
  117. package/kits/docs/AUTHORING.md +1 -1
  118. package/kits/docs/channels/aun.md +8 -0
  119. package/kits/docs/context-assembly.md +1 -0
  120. package/kits/docs/evolcore/INDEX.md +3 -2
  121. package/kits/docs/evolcore/agent-create.md +39 -28
  122. package/kits/docs/evolcore/agent.md +19 -4
  123. package/kits/docs/evolcore/ec-capabilities.md +4 -0
  124. package/kits/docs/evolcore/group-collaboration.md +3 -5
  125. package/kits/docs/evolcore/group.md +3 -4
  126. package/kits/docs/evolcore/memory-consolidation.md +1 -1
  127. package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
  128. package/kits/docs/evolcore/menu-protocol.md +7 -0
  129. package/kits/docs/evolcore/msg.md +5 -8
  130. package/kits/docs/evolcore/task.md +2 -0
  131. package/kits/docs/evolcore/thread-chain.md +267 -0
  132. package/kits/docs/evolcore/trigger.md +2 -2
  133. package/kits/docs/prompt-loading-architecture.md +1 -0
  134. package/kits/eck_manifest.json +61 -26
  135. package/kits/eck_message_manifest.json +169 -10
  136. package/kits/rules/01-overview.md +0 -9
  137. package/kits/rules/05-venue.md +1 -1
  138. package/kits/rules/06-channel.md +7 -1
  139. package/kits/rules/07-memory-and-thread.md +202 -0
  140. package/kits/schemas/relation-config.schema.9.json +18 -3
  141. package/kits/schemas/role-config.schema.1.json +6 -6
  142. package/kits/schemas/single-session.schema.1.json +6 -6
  143. package/kits/schemas/single-session.schema.2.json +6 -6
  144. package/kits/schemas/single-session.schema.3.json +6 -6
  145. package/kits/skills/.switches.json +12 -1
  146. package/kits/skills/ec-group/SKILL.md +234 -0
  147. package/kits/skills/ec-skill/SKILL.md +10 -1
  148. package/kits/skills/ec-skill/scripts/cli.mjs +15 -1
  149. package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
  150. package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
  151. package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
  152. package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
  153. package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
  154. package/kits/skills/thread-ops/SKILL.md +492 -0
  155. package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
  156. package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
  157. package/kits/skills/wechat-article-reader/SKILL.md +97 -0
  158. package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
  159. package/kits/templates/bootstrap-welcome.md +7 -7
  160. package/kits/templates/memory-consolidation/forget.md +5 -0
  161. package/kits/templates/memory-consolidation/generalize.md +5 -0
  162. package/kits/templates/memory-consolidation/profile.md +5 -0
  163. package/kits/templates/memory-consolidation/promote.md +5 -0
  164. package/kits/templates/message-fragments/item.md +2 -1
  165. package/kits/templates/message-fragments/thread-context.md +6 -0
  166. package/kits/templates/message-fragments/trigger-session.md +2 -0
  167. package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
  168. package/kits/templates/roles/member.json +2 -0
  169. package/kits/templates/roles/visitor.json +2 -0
  170. package/kits/templates/system-fragments/bootstrap.md +66 -72
  171. package/kits/templates/system-fragments/channel.md +3 -6
  172. package/kits/templates/system-fragments/commands.md +2 -1
  173. package/kits/templates/system-fragments/managed-runtime.md +15 -0
  174. package/kits/templates/system-fragments/reply.md +3 -2
  175. package/kits/templates/system-fragments/session.md +5 -14
  176. package/package.json +3 -1
  177. package/kits/docs/evolcore/group-fs.md +0 -17
  178. package/kits/docs/venues/aun-group.md +0 -45
  179. package/kits/docs/venues/group.md +0 -43
package/dist/cli/index.js CHANGED
@@ -20,6 +20,7 @@ import { cmdStart, cmdStop, cmdRestart, cmdStatus, cmdLogs, cmdWatchCommand, cmd
20
20
  import { logCliCommand } from './command-log.js';
21
21
  import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
22
22
  import { assertManagedTopLevelCommandAllowed, ManagedCommandNotAllowedError } from './managed-command-guard.js';
23
+ import { resolveDebugContext, stripAsSessionArgs } from './debug-mode.js';
23
24
  const MAIN_HELP = `用法: ec <command> [选项]
24
25
 
25
26
  服务:
@@ -35,6 +36,7 @@ Agent 与会话:
35
36
  agent 管理 EvolAgent
36
37
  ctl 当前托管会话的控制命令
37
38
  queue 查询或操作 agent 消息队列
39
+ session 按 ec 会话 id 查询本地 session 存档(含 agentSessionId)
38
40
  task 恢复暂停或异常中断的会话任务
39
41
  trigger 管理定时与事件触发器
40
42
  handoff 查询和完成跨会话回流
@@ -102,8 +104,12 @@ export async function main(args) {
102
104
  return;
103
105
  }
104
106
  const cmd = args[0] || 'start';
107
+ // 调试路径:--as-session <sessionId> 注入托管会话身份,必须在白名单检查之前
108
+ await resolveDebugContext(args);
109
+ // 注入完成后剥除 --as-session <sessionId> 两个参数,避免子命令把它们当作未知参数
110
+ const strippedArgs = stripAsSessionArgs(args);
105
111
  try {
106
- assertManagedTopLevelCommandAllowed(cmd, args);
112
+ assertManagedTopLevelCommandAllowed(cmd, strippedArgs);
107
113
  }
108
114
  catch (error) {
109
115
  if (!(error instanceof ManagedCommandNotAllowedError))
@@ -112,7 +118,7 @@ export async function main(args) {
112
118
  process.exitCode = 1;
113
119
  return;
114
120
  }
115
- logCliCommand(cmd, args);
121
+ logCliCommand(cmd, strippedArgs);
116
122
  if (cmd === '--version' || cmd === '-v' || cmd === '-V') {
117
123
  const pkg = JSON.parse(fs.readFileSync(path.join(getPackageRoot(), 'package.json'), 'utf-8'));
118
124
  console.log(pkg.version);
@@ -125,7 +131,7 @@ export async function main(args) {
125
131
  switch (cmd) {
126
132
  case 'init': {
127
133
  try {
128
- if (wantsHelp(args.slice(1))) {
134
+ if (wantsHelp(strippedArgs.slice(1))) {
129
135
  console.log(`用法: ec init [渠道] [选项]
130
136
 
131
137
  仅初始化 defaults.json:
@@ -155,49 +161,49 @@ export async function main(args) {
155
161
  ec init wecom 企业微信 AI Bot 扫码创建/手工配置`);
156
162
  }
157
163
  else {
158
- const hasChannelTarget = Boolean(args[1] && !args[1].startsWith('-'));
164
+ const hasChannelTarget = Boolean(strippedArgs[1] && !strippedArgs[1].startsWith('-'));
159
165
  if (hasChannelTarget)
160
166
  printInitCancelHint();
161
- if (args[1] === 'aun') {
167
+ if (strippedArgs[1] === 'aun') {
162
168
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
163
169
  suppressSdkLogs();
164
170
  await cmdInitAun();
165
171
  }
166
- else if (args[1] === 'wechat') {
172
+ else if (strippedArgs[1] === 'wechat') {
167
173
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
168
174
  suppressSdkLogs();
169
175
  await cmdInitWechat();
170
176
  }
171
- else if (args[1] === 'feishu') {
177
+ else if (strippedArgs[1] === 'feishu') {
172
178
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
173
179
  suppressSdkLogs();
174
180
  await cmdInitFeishu();
175
181
  }
176
- else if (args[1] === 'dingtalk') {
182
+ else if (strippedArgs[1] === 'dingtalk') {
177
183
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
178
184
  suppressSdkLogs();
179
185
  await cmdInitDingtalk();
180
186
  }
181
- else if (args[1] === 'qqbot') {
187
+ else if (strippedArgs[1] === 'qqbot') {
182
188
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
183
189
  suppressSdkLogs();
184
190
  await cmdInitQQBot();
185
191
  }
186
- else if (args[1] === 'wecom') {
192
+ else if (strippedArgs[1] === 'wecom') {
187
193
  await cmdInitWecom();
188
194
  }
189
- else if (args[1] && !args[1].startsWith('-')) {
195
+ else if (strippedArgs[1] && !strippedArgs[1].startsWith('-')) {
190
196
  const supported = ['feishu', 'wechat', 'aun', 'dingtalk', 'qqbot', 'wecom'];
191
- console.error(`❌ 不支持的渠道: ${args[1]}`);
197
+ console.error(`❌ 不支持的渠道: ${strippedArgs[1]}`);
192
198
  console.error(` 支持的渠道: ${supported.join(', ')}`);
193
199
  process.exit(1);
194
200
  }
195
201
  else {
196
202
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
197
203
  suppressSdkLogs();
198
- const nonInteractive = args.includes('--non-interactive');
199
- const wantsAutoStart = args.includes('--auto-start');
200
- const wantsNoAutoStart = args.includes('--no-auto-start');
204
+ const nonInteractive = strippedArgs.includes('--non-interactive');
205
+ const wantsAutoStart = strippedArgs.includes('--auto-start');
206
+ const wantsNoAutoStart = strippedArgs.includes('--no-auto-start');
201
207
  if (wantsAutoStart && wantsNoAutoStart) {
202
208
  console.error('❌ --auto-start 与 --no-auto-start 不能同时使用');
203
209
  process.exitCode = 1;
@@ -205,12 +211,12 @@ export async function main(args) {
205
211
  }
206
212
  const initialized = await cmdInit({
207
213
  nonInteractive,
208
- baseagent: getArgValue(args, '--baseagent'),
209
- force: args.includes('--force'),
210
- owner: getArgValue(args, '--owner'),
211
- projectpath: getArgValue(args, '--projectpath'),
212
- ecweb: args.includes('--ecweb') ? true : undefined,
213
- format: getArgValue(args, '--format'),
214
+ baseagent: getArgValue(strippedArgs, '--baseagent'),
215
+ force: strippedArgs.includes('--force'),
216
+ owner: getArgValue(strippedArgs, '--owner'),
217
+ projectpath: getArgValue(strippedArgs, '--projectpath'),
218
+ ecweb: strippedArgs.includes('--ecweb') ? true : undefined,
219
+ format: getArgValue(strippedArgs, '--format'),
214
220
  autoStart: wantsAutoStart ? true : wantsNoAutoStart ? false : undefined,
215
221
  });
216
222
  if (!initialized && process.exitCode == null)
@@ -227,31 +233,32 @@ export async function main(args) {
227
233
  break;
228
234
  }
229
235
  case 'start':
230
- if (wantsHelp(args.slice(1))) {
236
+ if (wantsHelp(strippedArgs.slice(1))) {
231
237
  printLifecycleHelp('start');
232
238
  break;
233
239
  }
234
240
  await cmdStart({
235
- diagnose: args.includes('--diagnose') || args.includes('-d'),
236
- foreground: args.includes('--foreground'),
241
+ diagnose: strippedArgs.includes('--diagnose') || strippedArgs.includes('-d'),
242
+ foreground: strippedArgs.includes('--foreground'),
243
+ debug: strippedArgs.includes('--debug'),
237
244
  });
238
245
  break;
239
246
  case 'stop':
240
- if (wantsHelp(args.slice(1))) {
247
+ if (wantsHelp(strippedArgs.slice(1))) {
241
248
  printLifecycleHelp('stop');
242
249
  break;
243
250
  }
244
251
  await cmdStop();
245
252
  break;
246
253
  case 'restart':
247
- if (wantsHelp(args.slice(1))) {
254
+ if (wantsHelp(strippedArgs.slice(1))) {
248
255
  printLifecycleHelp('restart');
249
256
  break;
250
257
  }
251
- await cmdRestart({ clear: args.includes('--clear'), diagnose: args.includes('--diagnose') || args.includes('-d') });
258
+ await cmdRestart({ clear: strippedArgs.includes('--clear'), diagnose: strippedArgs.includes('--diagnose') || strippedArgs.includes('-d') });
252
259
  break;
253
260
  case 'status':
254
- if (wantsHelp(args.slice(1))) {
261
+ if (wantsHelp(strippedArgs.slice(1))) {
255
262
  printLifecycleHelp('status');
256
263
  break;
257
264
  }
@@ -273,21 +280,21 @@ export async function main(args) {
273
280
  }
274
281
  break;
275
282
  case 'logs':
276
- if (wantsHelp(args.slice(1))) {
283
+ if (wantsHelp(strippedArgs.slice(1))) {
277
284
  printLifecycleHelp('logs');
278
285
  break;
279
286
  }
280
- cmdLogs(args.slice(1));
287
+ cmdLogs(strippedArgs.slice(1));
281
288
  break;
282
289
  case 'watch':
283
- if (wantsHelp(args.slice(1))) {
290
+ if (wantsHelp(strippedArgs.slice(1))) {
284
291
  printLifecycleHelp('watch');
285
292
  break;
286
293
  }
287
- await cmdWatchCommand(args.slice(1));
294
+ await cmdWatchCommand(strippedArgs.slice(1));
288
295
  break;
289
296
  case 'restart-monitor':
290
- if (wantsHelp(args.slice(1))) {
297
+ if (wantsHelp(strippedArgs.slice(1))) {
291
298
  printLifecycleHelp('restart-monitor');
292
299
  break;
293
300
  }
@@ -297,7 +304,7 @@ export async function main(args) {
297
304
  try {
298
305
  // 开发源码仓可提供 mode.js;正式 npm 包可以不携带该内部命令。
299
306
  const { cmdMode } = await import('./mode.js');
300
- await cmdMode(args.slice(1));
307
+ await cmdMode(strippedArgs.slice(1));
301
308
  }
302
309
  catch (error) {
303
310
  if (error?.code === 'ERR_MODULE_NOT_FOUND' && /(?:^|[\\/])mode\.js(?:$|')/.test(String(error?.message ?? ''))) {
@@ -309,70 +316,70 @@ export async function main(args) {
309
316
  }
310
317
  break;
311
318
  case 'mv':
312
- if (wantsHelp(args.slice(1))) {
319
+ if (wantsHelp(strippedArgs.slice(1))) {
313
320
  printLifecycleHelp('mv');
314
321
  break;
315
322
  }
316
- await cmdMv(args[1], args[2]);
323
+ await cmdMv(strippedArgs[1], strippedArgs[2]);
317
324
  break;
318
325
  case 'diagnose':
319
- if (wantsHelp(args.slice(1))) {
326
+ if (wantsHelp(strippedArgs.slice(1))) {
320
327
  printLifecycleHelp('diagnose');
321
328
  break;
322
329
  }
323
- await cmdDiagnose(args.slice(1));
330
+ await cmdDiagnose(strippedArgs.slice(1));
324
331
  break;
325
332
  case 'data': {
326
333
  const { cmdData } = await import('./data-command.js');
327
- await cmdData(args.slice(1));
334
+ await cmdData(strippedArgs.slice(1));
328
335
  break;
329
336
  }
330
337
  case 'net': {
331
338
  const { cmdNet } = await import('./net-check.js');
332
- await cmdNet(args.slice(1));
339
+ await cmdNet(strippedArgs.slice(1));
333
340
  break;
334
341
  }
335
342
  case 'ctl':
336
- await cmdCtl(args.slice(1));
343
+ await cmdCtl(strippedArgs.slice(1));
337
344
  break;
338
345
  case 'memory':
339
- await cmdMemory(args.slice(1));
346
+ await cmdMemory(strippedArgs.slice(1));
340
347
  break;
341
348
  case 'queue':
342
- await cmdQueue(args.slice(1));
349
+ await cmdQueue(strippedArgs.slice(1));
343
350
  break;
344
351
  case 'task': {
345
352
  const { cmdTask } = await import('./task-command.js');
346
- await cmdTask(args.slice(1));
353
+ await cmdTask(strippedArgs.slice(1));
347
354
  break;
348
355
  }
349
356
  case 'trigger':
350
357
  {
351
358
  const { cmdTrigger } = await import('./trigger-command.js');
352
- await cmdTrigger(args.slice(1));
359
+ await cmdTrigger(strippedArgs.slice(1));
353
360
  }
354
361
  break;
355
362
  case 'agent': {
356
363
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
357
364
  suppressSdkLogs();
358
- await cmdAgent(args.slice(1));
365
+ await cmdAgent(strippedArgs.slice(1));
359
366
  break;
360
367
  }
361
368
  case 'aid': {
362
369
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
363
370
  suppressSdkLogs();
364
- await cmdAid(args.slice(1));
371
+ await cmdAid(strippedArgs.slice(1));
365
372
  break;
366
373
  }
367
374
  case 'rpc': {
368
375
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
369
376
  suppressSdkLogs();
370
- await cmdRpc(args.slice(1));
377
+ await cmdRpc(strippedArgs.slice(1));
371
378
  break;
372
379
  }
373
380
  case 'diag': {
374
381
  const { cmdDiag } = await import('./diag.js');
375
- await cmdDiag(args.slice(1));
382
+ await cmdDiag(strippedArgs.slice(1));
376
383
  break;
377
384
  }
378
385
  case 'menu-client': {
@@ -380,7 +387,7 @@ export async function main(args) {
380
387
  suppressSdkLogs();
381
388
  const { cmdMenuClient } = await import('./menu-client.js');
382
389
  try {
383
- await cmdMenuClient(args.slice(1));
390
+ await cmdMenuClient(strippedArgs.slice(1));
384
391
  }
385
392
  catch (error) {
386
393
  const payload = {
@@ -397,80 +404,90 @@ export async function main(args) {
397
404
  case 'storage': {
398
405
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
399
406
  suppressSdkLogs();
400
- await cmdStorage(args.slice(1));
407
+ await cmdStorage(strippedArgs.slice(1));
401
408
  break;
402
409
  }
403
410
  case 'fs': {
404
411
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
405
412
  suppressSdkLogs();
406
413
  const { cmdFs } = await import('./fs-command.js');
407
- await cmdFs(args.slice(1));
414
+ await cmdFs(strippedArgs.slice(1));
408
415
  break;
409
416
  }
410
417
  case 'msg': {
411
418
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
412
419
  suppressSdkLogs();
413
- await cmdMsg(args.slice(1));
420
+ await cmdMsg(strippedArgs.slice(1));
414
421
  break;
415
422
  }
416
423
  case 'handoff': {
417
424
  const { cmdHandoff } = await import('./handoff-command.js');
418
- await cmdHandoff(args.slice(1));
425
+ await cmdHandoff(strippedArgs.slice(1));
426
+ break;
427
+ }
428
+ case 'thread': {
429
+ const { runThreadCommand } = await import('./thread-command.js');
430
+ await runThreadCommand(strippedArgs.slice(1));
431
+ break;
432
+ }
433
+ case 'session': {
434
+ const { runSessionCommand } = await import('./session-command.js');
435
+ await runSessionCommand(strippedArgs.slice(1));
419
436
  break;
420
437
  }
421
438
  case 'group': {
422
439
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
423
440
  suppressSdkLogs();
424
- await cmdGroup(args.slice(1));
441
+ await cmdGroup(strippedArgs.slice(1));
425
442
  break;
426
443
  }
427
444
  case 'model': {
428
445
  const { cmdModel } = await import('./model.js');
429
- await cmdModel(args.slice(1));
446
+ await cmdModel(strippedArgs.slice(1));
430
447
  break;
431
448
  }
432
449
  case 'skill': {
433
450
  const { cmdSkill } = await import('./skill-command.js');
434
- await cmdSkill(args.slice(1));
451
+ await cmdSkill(strippedArgs.slice(1));
435
452
  break;
436
453
  }
437
454
  case 'response': {
438
455
  const { cmdResponse } = await import('./response.js');
439
- await cmdResponse(args.slice(1));
456
+ await cmdResponse(strippedArgs.slice(1));
440
457
  break;
441
458
  }
442
459
  case 'config': {
443
460
  const { cmdConfig } = await import('./config.js');
444
- await cmdConfig(args.slice(1));
461
+ await cmdConfig(strippedArgs.slice(1));
445
462
  break;
446
463
  }
447
464
  case 'contact': {
448
465
  const { cmdContact } = await import('./contact.js');
449
- await cmdContact(args.slice(1));
466
+ await cmdContact(strippedArgs.slice(1));
450
467
  break;
451
468
  }
452
469
  case 'stats': {
453
470
  const { handleStats } = await import('./stats.js');
454
- await handleStats(args.slice(1));
471
+ await handleStats(strippedArgs.slice(1));
455
472
  break;
456
473
  }
457
474
  case 'version':
458
475
  case '-v':
459
476
  case '--version': {
460
477
  const { handleVersion } = await import('./version.js');
461
- handleVersion(args.slice(1));
478
+ handleVersion(strippedArgs.slice(1));
462
479
  break;
463
480
  }
464
481
  case 'bench': {
465
482
  const { suppressSdkLogs } = await import('../aun/aid/index.js');
466
483
  suppressSdkLogs();
467
484
  const { cmdBench } = await import('./bench.js');
468
- await cmdBench(args.slice(1));
485
+ await cmdBench(strippedArgs.slice(1));
469
486
  break;
470
487
  }
471
488
  case 'link-rules': {
472
489
  const { cmdLinkRules } = await import('./link-rules.js');
473
- cmdLinkRules(args.slice(1));
490
+ cmdLinkRules(strippedArgs.slice(1));
474
491
  break;
475
492
  }
476
493
  default:
package/dist/cli/init.js CHANGED
@@ -561,8 +561,8 @@ export async function initTail(options = {}) {
561
561
  async function handleOwnersPrompt(rl) {
562
562
  const daemonConfigForOwners = loadDaemonConfig();
563
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 === 'y' || needOwner === 'yes') {
564
+ const needOwner = (await ask(rl, '\n是否配置进程级管理者(Owner AID)?[Y/n] ')).trim().toLowerCase();
565
+ if (!needOwner || needOwner === 'y' || needOwner === 'yes') {
566
566
  console.log('\n📡 进程级管理者绑定 — 请用 evol app 扫描二维码\n');
567
567
  // QR 绑定流程需要暂时关闭 rl,因为它会创建自己的输入监听
568
568
  rl.pause();
@@ -18,8 +18,13 @@ const MANAGED_TASK_COMMANDS = new Set([
18
18
  'msg',
19
19
  'queue',
20
20
  'response',
21
+ // `session` 按 ec 会话 id 只读查询本地 session 存档(meta 文件尾行的
22
+ // agentSessionId 等),不触碰 daemon 与进程生命周期。
23
+ 'session',
21
24
  // `skill` 管理 EC 技能(安装/开关/校验)。它的主要使用者就是 agent 自己——
22
25
  // ec-skill 技能的 SKILL.md 明确指导 agent 调用它。脚本只读写
26
+ // `thread` 提供话题链操作,通过 thread.op IPC 鉴权
27
+ 'thread',
23
28
  // $EVOLCORE_HOME/skills/ 与 kits/skills/ 下的技能文件,不触碰进程生命周期。
24
29
  // 本白名单只负责让它进到脚本;具体某一级的读写权限由 skill.mjs 的
25
30
  // assertPermission() 按会话上下文判定(群聊一律拒,Agent 级要 owner,
@@ -15,6 +15,8 @@ import { resolvePaths } from '../paths.js';
15
15
  import { ipcQuery } from '../ipc.js';
16
16
  import { isHelpFlag, wantsHelp } from './help.js';
17
17
  import { readDelegationCredential } from '../core/auth/agent-delegation.js';
18
+ import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
19
+ import { formatQueueDetails } from '../core/memory/consolidation-queue-format.js';
18
20
  export const MEMORY_MODES = ['notes', 'generalize', 'promote', 'profile', 'forget'];
19
21
  const MEMORY_HELP = `用法: ec memory <command> [选项]
20
22
 
@@ -63,6 +65,7 @@ ec memory consolidate [--mode <notes|generalize|promote|profile|forget>]
63
65
  ec memory update consolidated/commit-convention.md --tags "rule,done"
64
66
  ec memory archive consolidated/obsolete.md`;
65
67
  export async function cmdMemory(args) {
68
+ args = canonicalizeEvolcoreCommandArgv(['ec', 'memory', ...args]).slice(2);
66
69
  if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
67
70
  console.log(MEMORY_HELP);
68
71
  return;
@@ -99,13 +102,15 @@ export async function cmdMemory(args) {
99
102
  * 解析 `--key value` 与位置参数。未识别的 `--xxx` 一律报错,避免静默忽略。
100
103
  * `--debug <sessionId>` 是所有子命令的公共参数,不用每处声明。
101
104
  */
102
- function parseArgs(args, known) {
105
+ function parseArgs(args, known, throwOnUnknown = false) {
103
106
  const flags = new Map();
104
107
  const positional = [];
105
108
  for (let i = 0; i < args.length; i++) {
106
109
  const a = args[i];
107
110
  if (a.startsWith('--')) {
108
111
  if (a !== '--debug' && !known.includes(a)) {
112
+ if (throwOnUnknown)
113
+ throw new Error(`未知参数: ${a}`);
109
114
  console.error(`❌ 未知参数: ${a}`);
110
115
  process.exit(1);
111
116
  }
@@ -128,6 +133,76 @@ function parseTags(raw) {
128
133
  const tags = raw.split(',').map(t => t.trim()).filter(Boolean);
129
134
  return tags.length > 0 ? tags : undefined;
130
135
  }
136
+ export function resolveMemoryCommandArgv(argv) {
137
+ if (argv[0] !== 'memory')
138
+ throw new Error('Expected a memory command');
139
+ const noteSub = argv[1] === 'note' && ['update', 'drop', 'list'].includes(argv[2]) ? argv[2] : undefined;
140
+ const kind = noteSub ? `note.${noteSub}` : argv[1];
141
+ const known = {
142
+ note: ['--slug', '--tags', '--speakers'], 'note.update': ['--slug', '--tags'],
143
+ 'note.drop': [], 'note.list': [], create: ['--scope', '--slug', '--desc', '--tags', '--keywords', '--replaces', '--peer'],
144
+ update: ['--tags', '--touch'], archive: [], demote: ['--scope'], consolidate: ['--mode'], feedback: [],
145
+ };
146
+ if (!Object.prototype.hasOwnProperty.call(known, kind))
147
+ throw new Error('Invalid memory command');
148
+ const { flags, positional } = parseArgs(argv.slice(noteSub ? 3 : 2), known[kind], true);
149
+ const required = (value, name) => {
150
+ if (!value)
151
+ throw new Error(`${name} is required`);
152
+ return value;
153
+ };
154
+ const content = positional.join(' ').trim();
155
+ const type = `memory.${kind}`;
156
+ if (kind === 'note')
157
+ return { type, slug: required(flags.get('--slug'), '--slug'), content: required(content, 'content'),
158
+ tags: parseTags(flags.get('--tags')), speakers: parseTags(flags.get('--speakers')) };
159
+ if (kind === 'note.update') {
160
+ const newContent = positional.slice(1).join(' ').trim();
161
+ if (!flags.get('--slug') && !flags.has('--tags') && !newContent)
162
+ throw new Error('No memory note changes supplied');
163
+ return { type, slug: required(positional[0], 'slug'), newSlug: flags.get('--slug'),
164
+ tags: parseTags(flags.get('--tags')), tagsProvided: flags.has('--tags'), content: newContent || undefined };
165
+ }
166
+ if (kind === 'note.drop')
167
+ return { type, slug: required(positional[0], 'slug') };
168
+ if (kind === 'note.list')
169
+ return { type };
170
+ if (kind === 'create') {
171
+ const scope = flags.get('--scope');
172
+ if (!scope || !['relation', 'agent', 'owner'].includes(scope))
173
+ throw new Error('Invalid memory scope');
174
+ if (!flags.has('--tags'))
175
+ throw new Error('--tags is required');
176
+ if (flags.has('--peer') && scope !== 'relation')
177
+ throw new Error('--peer requires relation scope');
178
+ return { type, scope, slug: required(flags.get('--slug'), '--slug'), description: required(flags.get('--desc'), '--desc'),
179
+ content: required(content, 'content'), tags: parseTags(flags.get('--tags')), keywords: parseTags(flags.get('--keywords')),
180
+ replaces: parseTags(flags.get('--replaces')), targetPeerKey: flags.get('--peer') };
181
+ }
182
+ if (kind === 'update') {
183
+ if (!flags.has('--tags') && !flags.has('--touch'))
184
+ throw new Error('No memory changes supplied');
185
+ return { type, filePath: required(positional[0], 'path'), tags: parseTags(flags.get('--tags')), touch: flags.has('--touch') };
186
+ }
187
+ if (kind === 'archive') {
188
+ if (!positional.length)
189
+ throw new Error('Memory paths are required');
190
+ return { type, filePaths: positional };
191
+ }
192
+ if (kind === 'demote') {
193
+ const scope = flags.get('--scope') ?? 'agent';
194
+ if (scope !== 'agent' && scope !== 'owner')
195
+ throw new Error('Invalid demotion scope');
196
+ return { type, slug: required(positional[0], 'slug'), scope };
197
+ }
198
+ if (kind === 'consolidate') {
199
+ const mode = flags.get('--mode') ?? 'notes';
200
+ if (!MEMORY_MODES.includes(mode))
201
+ throw new Error('Invalid consolidation mode');
202
+ return { type, mode };
203
+ }
204
+ return { type, text: required(content, 'feedback') };
205
+ }
131
206
  /** 各子命令的一行完整用法:缺参报错时附上,模型照抄即可重试。 */
132
207
  const USAGE = {
133
208
  note: 'ec memory note --slug <slug> [--tags <tag1,tag2>] [--speakers <aid1,aid2>] "<正文>"',
@@ -193,7 +268,7 @@ async function cmdMemoryNoteCreate(args) {
193
268
  failWithUsage('必须提供记忆内容(content)', USAGE.note);
194
269
  const { socketPath, ...session } = requireManagedSession('ec memory note', flags);
195
270
  const result = await ipcQuery(socketPath, {
196
- type: 'memory.note', ...session, slug, content, tags,
271
+ type: 'memory.note', argv: ['memory', 'note', ...args], ...session, slug, content, tags,
197
272
  speakers: speakers && speakers.length > 0 ? speakers : undefined,
198
273
  }, 15_000);
199
274
  reportResult(result, (r) => {
@@ -215,7 +290,7 @@ async function cmdMemoryNoteUpdate(args) {
215
290
  }
216
291
  const { socketPath, ...session } = requireManagedSession('ec memory note update', flags);
217
292
  const result = await ipcQuery(socketPath, {
218
- type: 'memory.note.update', ...session, slug,
293
+ type: 'memory.note.update', argv: ['memory', 'note', 'update', ...args], ...session, slug,
219
294
  newSlug, tags, tagsProvided: tagsRaw !== undefined,
220
295
  content: content || undefined,
221
296
  }, 15_000);
@@ -231,7 +306,7 @@ async function cmdMemoryNoteDrop(args) {
231
306
  failWithUsage('必须提供要撤销的 slug', USAGE.noteDrop);
232
307
  const { socketPath, ...session } = requireManagedSession('ec memory note drop', flags);
233
308
  const result = await ipcQuery(socketPath, {
234
- type: 'memory.note.drop', ...session, slug,
309
+ type: 'memory.note.drop', argv: ['memory', 'note', 'drop', ...args], ...session, slug,
235
310
  }, 15_000);
236
311
  reportResult(result, (r) => {
237
312
  console.log(`✓ 已撤销: ${r.filePath ?? slug}`);
@@ -241,7 +316,7 @@ async function cmdMemoryNoteList(args) {
241
316
  const { flags } = parseArgs(args, []);
242
317
  const { socketPath, ...session } = requireManagedSession('ec memory note list', flags);
243
318
  const result = await ipcQuery(socketPath, {
244
- type: 'memory.note.list', ...session,
319
+ type: 'memory.note.list', argv: ['memory', 'note', 'list', ...args], ...session,
245
320
  }, 15_000);
246
321
  reportResult(result, (r) => {
247
322
  const notes = r.notes ?? [];
@@ -286,7 +361,7 @@ async function cmdMemoryCreate(args) {
286
361
  }
287
362
  const { socketPath, ...session } = requireManagedSession('ec memory create', flags);
288
363
  const result = await ipcQuery(socketPath, {
289
- type: 'memory.create', ...session, scope, slug, description: desc,
364
+ type: 'memory.create', argv: ['memory', 'create', ...args], ...session, scope, slug, description: desc,
290
365
  content,
291
366
  tags: parseTags(tagsRaw),
292
367
  keywords: parseTags(keywordsRaw),
@@ -312,7 +387,7 @@ async function cmdMemoryConsolidatedUpdate(args) {
312
387
  failWithUsage('至少提供 --tags 或 --touch', USAGE.update);
313
388
  const { socketPath, ...session } = requireManagedSession('ec memory update', flags);
314
389
  const result = await ipcQuery(socketPath, {
315
- type: 'memory.update', ...session, filePath,
390
+ type: 'memory.update', argv: ['memory', 'update', ...args], ...session, filePath,
316
391
  tags: parseTags(tagsRaw), touch,
317
392
  }, 15_000);
318
393
  reportResult(result, () => {
@@ -325,7 +400,7 @@ async function cmdMemoryArchive(args) {
325
400
  failWithUsage('必须提供至少一个要归档的文件路径', USAGE.archive);
326
401
  const { socketPath, ...session } = requireManagedSession('ec memory archive', flags);
327
402
  const result = await ipcQuery(socketPath, {
328
- type: 'memory.archive', ...session, filePaths: positional,
403
+ type: 'memory.archive', argv: ['memory', 'archive', ...args], ...session, filePaths: positional,
329
404
  }, 15_000);
330
405
  reportResult(result, (r) => {
331
406
  const archived = r.archived ?? positional;
@@ -353,7 +428,7 @@ async function cmdMemoryDemote(args) {
353
428
  }
354
429
  const { socketPath, ...session } = requireManagedSession('ec memory demote', flags);
355
430
  const result = await ipcQuery(socketPath, {
356
- type: 'memory.demote', ...session, slug, scope,
431
+ type: 'memory.demote', argv: ['memory', 'demote', ...args], ...session, slug, scope,
357
432
  }, 15_000);
358
433
  reportResult(result, (r) => {
359
434
  if (r.conflictArchived) {
@@ -385,15 +460,21 @@ async function cmdMemoryConsolidate(args) {
385
460
  const { socketPath, ...session } = requireManagedSession('ec memory consolidate', flags);
386
461
  console.log(`正在触发记忆整理(mode=${mode})...`);
387
462
  const result = await ipcQuery(socketPath, {
388
- type: 'memory.consolidate', ...session, mode,
463
+ type: 'memory.consolidate', argv: ['memory', 'consolidate', ...args], ...session, mode,
389
464
  }, 30_000);
390
465
  reportResult(result, (r) => {
466
+ if (r.queued) {
467
+ console.log(`⏳ 整理请求已入队(${mode} 模式),前一个整理会话结束后自动启动`);
468
+ for (const line of formatQueueDetails(r.queued))
469
+ console.log(` ${line}`);
470
+ console.log('启动后整理结果会反馈到发起会话。');
471
+ return;
472
+ }
391
473
  console.log(`✓ 整理会话已启动(${mode} 模式)`);
392
474
  if (r.triggerId)
393
475
  console.log(` triggerId: ${r.triggerId}`);
394
476
  if (r.executionSessionId)
395
477
  console.log(` sessionId: ${r.executionSessionId}`);
396
- console.log(` agentSessionId: ${r.agentSessionId ?? '(会话仍在初始化,稍后用 sessionId 查)'}`);
397
478
  if (r.contextFilePath)
398
479
  console.log(` context: ${r.contextFilePath}`);
399
480
  console.log('整理会话在后台继续运行。');
@@ -418,7 +499,7 @@ async function cmdMemoryFeedback(args) {
418
499
  }
419
500
  const { socketPath, ...session } = requireManagedSession('ec memory feedback', flags);
420
501
  const result = await ipcQuery(socketPath, {
421
- type: 'memory.feedback', ...session, text,
502
+ type: 'memory.feedback', argv: ['memory', 'feedback', ...args], ...session, text,
422
503
  }, 15_000);
423
504
  reportResult(result, () => {
424
505
  console.log('✓ 已记录反馈内容');