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
@@ -2,6 +2,8 @@ import { resolvePaths } from '../paths.js';
2
2
  import { ipcQuery } from '../ipc.js';
3
3
  import { readDelegationCredential } from '../core/auth/agent-delegation.js';
4
4
  import { canonicalizeEvolcoreCommandArgv } from '../core/permission/ec-command-parser.js';
5
+ import { isMainSessionThreadId, resolveThreadRef } from '../core/thread/topic-id.js';
6
+ import { parseTimeArg, TIME_ARG_FORMATS } from './cli-argv.js';
5
7
  const TOPIC_STATUSES = ['pending', 'in_progress', 'completed', 'archived'];
6
8
  const SORT_ORDERS = ['recent', 'created'];
7
9
  const HELP_TEXT = `
@@ -45,8 +47,12 @@ list 选项:
45
47
 
46
48
  history 选项:
47
49
  --limit <n> 消息条数上限(默认 50)
48
- --before <timestamp> 截止时间戳(ms)
49
- --after <timestamp> 起始时间戳(ms)
50
+ --before <time> 截止时间
51
+ --after <time> 起始时间
52
+ <time> 支持:epoch 毫秒/秒、ISO 8601、
53
+ '2026-10-20 23:18:46 +08:00'(消息信封头原样)、
54
+ '2026/10/20 23:18:46'(history 输出原样,按本机时区)、
55
+ 相对时间 30s/5m/2h/1d(多久之前)、now
50
56
 
51
57
  summary 与增量总结:
52
58
  summary show <ref> 会打印 coveredThroughTs(本条摘要覆盖到的时间戳)。
@@ -128,13 +134,17 @@ function printItem(item) {
128
134
  const running = obj.running ? ' [运行中]' : '';
129
135
  // 内部话题(daemon 会话记录)不是真实联系人,标注出来避免误认
130
136
  const internal = obj.internal ? ' [内部会话记录·无消息]' : '';
131
- // 主会话的 threadId 是空串;显示成 /main 比留一个空尾巴好读。
132
- console.log(`${obj.peer}/${obj.threadId || 'main'}${running}${internal}`);
137
+ // 打印的就是可直接作为 `--thread` 的值:话题是 threadId,主话题是
138
+ // `main:<aid>:<aid>`。不再拼 `<peer>/` 前缀——那种写法从不可消费。
139
+ console.log(`${obj.threadId}${running}${internal}`);
133
140
  // 名称只放名称本身:状态、标签各自单独一行,避免污染标题(标题会被 summary set --name 引用)。
134
- // 主会话(threadId 为空)加 `[主会话]` 前缀,与普通话题区分开;前缀只在展示层加,
141
+ // 主话题加 `[主话题]` 前缀,与话题区分开;前缀只在展示层加,
135
142
  // 不进索引与 session 的 name 字段,避免被 summary set --name 当成真实标题。
136
- const namePrefix = obj.threadId ? '' : '[主会话] ';
137
- console.log(` 名称: ${namePrefix}${obj.name}`);
143
+ const namePrefix = isMainSessionThreadId(obj.threadId) ? '[主话题] ' : '';
144
+ // 旧版本曾把 `[主会话] ` 写进 name 本体(历史遗留),展示前剥掉,
145
+ // 否则会渲染成 `[主话题] [主会话] …`。存储值不改,避免误改用户起的名字。
146
+ const displayName = String(obj.name ?? '').replace(/^\[(?:主会话|主话题)\]\s*/, '');
147
+ console.log(` 名称: ${namePrefix}${displayName}`);
138
148
  if (obj.topicStatus)
139
149
  console.log(` 状态: ${obj.topicStatus}`);
140
150
  if (obj.label)
@@ -228,17 +238,26 @@ export async function runThreadCommand(args) {
228
238
  const commandArgv = canonicalizeEvolcoreCommandArgv(['ec', 'thread', ...args]).slice(1);
229
239
  const sendOp = (req) => sendThreadOp(req, commandArgv);
230
240
  // resolve <ref> → peer + threadId
241
+ //
242
+ // 规范形态只有两种:`main:<aid>:<aid>`(主话题)与话题 id(话题)。
243
+ // 历史写法 `<peer>/<threadId>` 仍接受;裸 `main` 与 `<peer>/main` 都拒绝——
244
+ // 前者没有对端、后者从未实现过。
245
+ // 返回 undefined 表示引用非法(已打印原因)。调用方必须直接返回,
246
+ // 不能把空对象当成"当前会话"继续执行——那会静默操作错会话。
231
247
  function resolveRef(ref) {
232
248
  if (ref === 'current')
233
249
  return {};
234
- const slash = ref.lastIndexOf('/');
235
- if (slash < 0)
236
- return { peer: ref };
237
- const raw = ref.slice(slash + 1);
238
- // 主会话的 threadId 是空串;`<peer>/main` 是同义写法,`list` 也这样显示。
239
- if (raw === 'main')
240
- return { peer: ref.slice(0, slash), threadId: '' };
241
- return { peer: ref.slice(0, slash), threadId: raw };
250
+ const resolved = resolveThreadRef(ref, selfAid ?? '');
251
+ if (resolved.kind === 'invalid') {
252
+ console.error(`✗ ${resolved.error}`);
253
+ process.exitCode = 1;
254
+ return undefined;
255
+ }
256
+ if (resolved.kind === 'current')
257
+ return {};
258
+ if (resolved.kind === 'main')
259
+ return { peer: resolved.peer, threadId: resolved.topicId };
260
+ return { peer: resolved.peer, threadId: resolved.threadId };
242
261
  }
243
262
  switch (sub) {
244
263
  case 'list': {
@@ -282,7 +301,10 @@ export async function runThreadCommand(args) {
282
301
  process.exitCode = 1;
283
302
  return;
284
303
  }
285
- const { peer, threadId } = resolveRef(ref);
304
+ const target = resolveRef(ref);
305
+ if (!target)
306
+ return;
307
+ const { peer, threadId } = target;
286
308
  const resp = await sendOp({ op: 'show', selfAid, peer, threadId });
287
309
  if (!resp.ok) {
288
310
  console.error(`✗ ${resp.error}`);
@@ -301,10 +323,29 @@ export async function runThreadCommand(args) {
301
323
  process.exitCode = 1;
302
324
  return;
303
325
  }
304
- const { peer, threadId } = resolveRef(ref);
326
+ const target = resolveRef(ref);
327
+ if (!target)
328
+ return;
329
+ const { peer, threadId } = target;
305
330
  const limit = argValue(args, '--limit') ? Number(argValue(args, '--limit')) : undefined;
306
- const before = argValue(args, '--before') ? Number(argValue(args, '--before')) : undefined;
307
- const after = argValue(args, '--after') ? Number(argValue(args, '--after')) : undefined;
331
+ const timeOption = (flag) => {
332
+ const raw = argValue(args, flag);
333
+ if (raw === undefined)
334
+ return undefined;
335
+ const value = parseTimeArg(raw);
336
+ if (value === undefined) {
337
+ console.error(`✗ ${flag} 不是有效时间: ${raw}(支持 ${TIME_ARG_FORMATS})`);
338
+ process.exitCode = 1;
339
+ return null;
340
+ }
341
+ return value;
342
+ };
343
+ const before = timeOption('--before');
344
+ if (before === null)
345
+ return;
346
+ const after = timeOption('--after');
347
+ if (after === null)
348
+ return;
308
349
  // threadId 可选:不传时读主会话(threadId=null)消息,与 show <peer> 行为对齐
309
350
  const resp = await sendOp({ op: 'history', selfAid, peer, threadId, limit, before, after });
310
351
  if (!resp.ok) {
@@ -354,7 +395,10 @@ export async function runThreadCommand(args) {
354
395
  process.exitCode = 1;
355
396
  return;
356
397
  }
357
- const { peer, threadId } = resolveRef(ref);
398
+ const target = resolveRef(ref);
399
+ if (!target)
400
+ return;
401
+ const { peer, threadId } = target;
358
402
  const resp = await sendOp({ op: 'rename', selfAid, peer, threadId, name: newName });
359
403
  if (!resp.ok) {
360
404
  console.error(`✗ ${resp.error}`);
@@ -371,7 +415,10 @@ export async function runThreadCommand(args) {
371
415
  process.exitCode = 1;
372
416
  return;
373
417
  }
374
- const { peer, threadId } = resolveRef(ref);
418
+ const target = resolveRef(ref);
419
+ if (!target)
420
+ return;
421
+ const { peer, threadId } = target;
375
422
  const label = hasFlag(args, '--clear') ? null : args[2] ?? null;
376
423
  const resp = await sendOp({ op: 'label', selfAid, peer, threadId, label });
377
424
  if (!resp.ok) {
@@ -395,7 +442,10 @@ export async function runThreadCommand(args) {
395
442
  process.exitCode = 1;
396
443
  return;
397
444
  }
398
- const { peer, threadId } = resolveRef(ref);
445
+ const target = resolveRef(ref);
446
+ if (!target)
447
+ return;
448
+ const { peer, threadId } = target;
399
449
  const resp = await sendOp({ op: 'status', selfAid, peer, threadId, topicStatus: statusVal });
400
450
  if (!resp.ok) {
401
451
  console.error(`✗ ${resp.error}`);
@@ -470,10 +520,13 @@ export async function runThreadCommand(args) {
470
520
  process.exitCode = 1;
471
521
  return;
472
522
  }
473
- const { peer, threadId } = resolveRef(ref);
474
- // current ref 允许通过(daemon 侧通过 sessionId 反查);其他情况必须带 threadId
475
- if (ref !== 'current' && !threadId) {
476
- console.error('✗ delete 必须指定 threadId(格式: <peer>/<threadId>)');
523
+ const target = resolveRef(ref);
524
+ if (!target)
525
+ return;
526
+ const { peer, threadId } = target;
527
+ // current ref 允许通过(daemon 侧通过 sessionId 反查);其他情况必须是话题 id。
528
+ if (ref !== 'current' && (!threadId || isMainSessionThreadId(threadId))) {
529
+ console.error('✗ delete 只能删除话题(主话题不可删除)');
477
530
  process.exitCode = 1;
478
531
  return;
479
532
  }
@@ -495,12 +548,20 @@ export async function runThreadCommand(args) {
495
548
  return;
496
549
  }
497
550
  if (subCmd === 'show') {
498
- const resp = await sendOp({ op: 'summary-show', selfAid });
551
+ const target = resolveRef(ref);
552
+ if (!target)
553
+ return;
554
+ const { peer, threadId } = target;
555
+ const resp = await sendOp({ op: 'summary-show', selfAid, peer, threadId });
499
556
  if (!resp.ok) {
500
557
  console.error(`✗ ${resp.error}`);
501
558
  process.exitCode = 1;
502
559
  return;
503
560
  }
561
+ if (jsonFormat) {
562
+ console.log(JSON.stringify(resp.result ?? null, null, 2));
563
+ return;
564
+ }
504
565
  if (!resp.result) {
505
566
  console.log('(暂无 summary)');
506
567
  }
@@ -539,7 +600,10 @@ export async function runThreadCommand(args) {
539
600
  return;
540
601
  }
541
602
  // 覆盖游标由 daemon 侧自动记录,无需传参
542
- const { peer: setPeer, threadId: setThreadId } = resolveRef(ref);
603
+ const setTarget = resolveRef(ref);
604
+ if (!setTarget)
605
+ return;
606
+ const { peer: setPeer, threadId: setThreadId } = setTarget;
543
607
  const resp = await sendOp({
544
608
  op: 'summary-set', selfAid, content, ifRev: ifRevRaw,
545
609
  ...(setPeer ? { peer: setPeer } : {}),
@@ -562,13 +626,21 @@ export async function runThreadCommand(args) {
562
626
  console.log(`⚠ 改名失败(摘要已写入): ${setRes.renameError}`);
563
627
  }
564
628
  else if (subCmd === 'log') {
565
- const resp = await sendOp({ op: 'summary-log', selfAid });
629
+ const target = resolveRef(ref);
630
+ if (!target)
631
+ return;
632
+ const { peer, threadId } = target;
633
+ const resp = await sendOp({ op: 'summary-log', selfAid, peer, threadId });
566
634
  if (!resp.ok) {
567
635
  console.error(`✗ ${resp.error}`);
568
636
  process.exitCode = 1;
569
637
  return;
570
638
  }
571
639
  const entries = resp.result;
640
+ if (jsonFormat) {
641
+ console.log(JSON.stringify(entries ?? [], null, 2));
642
+ return;
643
+ }
572
644
  if (!entries?.length) {
573
645
  console.log('(暂无历史)');
574
646
  return;
@@ -619,7 +691,8 @@ export async function runThreadCommand(args) {
619
691
  }
620
692
  for (const p of peers) {
621
693
  const kind = p.peerKind === 'group' ? ' [群]' : '';
622
- console.log(`${p.peer}${kind} 话题数:${p.threadCount} 活跃:${new Date(p.lastActiveAt).toLocaleString('zh-CN')}`);
694
+ const name = p.peerName && p.peerName !== p.peer ? ` (${p.peerName})` : '';
695
+ console.log(`${p.peer}${kind}${name} 话题数:${p.threadCount} 活跃:${new Date(p.lastActiveAt).toLocaleString('zh-CN')}`);
623
696
  }
624
697
  return;
625
698
  }
@@ -642,7 +642,7 @@ async function request(cmd, timeoutMs = 10_000) {
642
642
  }
643
643
  catch { }
644
644
  }
645
- const res = await ipcQuery(resolvePaths().socket, actorSessionId ? { ...cmd, actorSessionId, delegationToken } : { ...cmd, controlToken }, timeoutMs);
645
+ const res = await ipcQuery(resolvePaths().socket, actorSessionId ? { ...cmd, actorSessionId, delegationToken } : delegationToken ? { ...cmd, delegationToken } : { ...cmd, controlToken }, timeoutMs);
646
646
  if (!res)
647
647
  throw new Error('错误: 无法连接 evolcore 服务');
648
648
  if (res.ok === false || res.error)
@@ -28,6 +28,7 @@ const STAGES = [
28
28
  { stage: 'task_start', label: '4. 任务开始 ', color: YELLOW },
29
29
  { stage: 'task_done', label: '5. 任务完成 ', color: BLUE },
30
30
  { stage: 'aun_out', label: '6. AUN出站 ', color: GREEN },
31
+ { stage: 'send_ok', label: '7. 发送成功 ', color: GREEN },
31
32
  ];
32
33
  const state = new Map();
33
34
  for (const s of STAGES)
@@ -78,9 +78,9 @@ function accessPolicySnapshotFromAgent(selfAid, agent) {
78
78
  return { policy, accessRevision: accessPolicyRevision(policy) };
79
79
  }
80
80
  function assertAccessPolicyWrite(input, agent, policy) {
81
- const owners = validAgentOwnerIds(agent);
81
+ const owners = validAgentOwnerIds({ aid: input.selfAid });
82
82
  const normalizedActorAid = String(input.actorAid || '').trim();
83
- const isOwner = input.actorRole === 'owner' || owners.includes(normalizedActorAid);
83
+ const isOwner = owners.includes(normalizedActorAid);
84
84
  if (!isOwner) {
85
85
  throw new AccessPolicyError('access_policy_owner_required', 'Only an Agent Owner can change access policy');
86
86
  }
@@ -13,12 +13,13 @@ import path from 'path';
13
13
  import { resolvePaths } from '../paths.js';
14
14
  import { logger } from '../utils/logger.js';
15
15
  import { autoMigrateIfNeeded } from '../config-store.js';
16
- import { initConfigManager } from './config-manager.js';
16
+ import { ConfigTarget, initConfigManager, notifyConfigWrite } from './config-manager.js';
17
17
  import { ensureRoleConfigV4OnStartup, ensureRoleConfigV5OnStartup } from './role-migration-startup.js';
18
18
  import { ensureAuxiliaryModelMigrationOnStartup } from './schema-migration.js';
19
19
  import { ensureContactBookV2OnStartup } from './contact-book-v2-startup.js';
20
+ import { synchronizeAllManagementContactsSync } from './contact-book-store.js';
20
21
  import { readInstalledEvolcoreVersion, readFastaunVersion } from '../utils/evolcore-version.js';
21
- import { readCurrent, readWVersion, writeWVersion, materializeVersion, listAllVersions, diffVersions, snapshot, isConfigSnapshotsEnabled, ensureStartupConfigSnapshot, incrementSuccessCount, retentionCleanup, } from './snapshot.js';
22
+ import { readCurrent, readWVersion, writeWVersion, materializeVersion, listAllVersions, diffVersions, snapshot, isConfigSnapshotsEnabled, ensureStartupConfigSnapshot, incrementSuccessCount, retentionCleanup, writeSnapshotConfigFile, removeSnapshotConfigFile, } from './snapshot.js';
22
23
  const MAX_LINES = 300;
23
24
  const KEEP_MIN = 150;
24
25
  const FALLBACK_MAX_TRIES = 20;
@@ -54,6 +55,12 @@ export async function prepareStartupConfig(recoverRoleMutations) {
54
55
  logger.info(message);
55
56
  console.error(message);
56
57
  }
58
+ const synchronizedContacts = synchronizeAllManagementContactsSync();
59
+ if (synchronizedContacts > 0) {
60
+ const message = `✓ Contact management identities synchronized: ${synchronizedContacts} agent(s)`;
61
+ logger.info(message);
62
+ console.error(message);
63
+ }
57
64
  }
58
65
  export async function initializeStartupConfig(abort) {
59
66
  try {
@@ -292,18 +299,14 @@ async function expandToW(version, root) {
292
299
  const { collectConfigFiles } = await import('./snapshot.js');
293
300
  const existing = collectConfigFiles(root);
294
301
  for (const rel of existing) {
295
- if (!files.has(rel)) {
296
- try {
297
- fs.unlinkSync(path.join(root, rel));
298
- }
299
- catch { /* */ }
300
- }
302
+ if (!files.has(rel))
303
+ removeSnapshotConfigFile(root, rel);
301
304
  }
302
305
  for (const [rel, content] of files) {
303
- const dest = path.join(root, rel);
304
- fs.mkdirSync(path.dirname(dest), { recursive: true });
305
- fs.writeFileSync(dest, content, 'utf-8');
306
+ writeSnapshotConfigFile(root, rel, content);
306
307
  }
308
+ if (existing.includes('providers.json') || files.has('providers.json'))
309
+ notifyConfigWrite(ConfigTarget.Providers);
307
310
  writeWVersion({ full, delta: version });
308
311
  }
309
312
  async function workingDiffersFromVersion(version) {
@@ -48,6 +48,7 @@ const SENSITIVE_TOP_FIELDS = new Set([
48
48
  'lifecycle',
49
49
  'initialized',
50
50
  'initialization',
51
+ 'owner',
51
52
  'owners',
52
53
  'access',
53
54
  'fullaccess',
@@ -64,7 +65,7 @@ const SENSITIVE_TOP_FIELDS = new Set([
64
65
  'extra_backup',
65
66
  'decision_model',
66
67
  ]);
67
- const CRITICAL_AGENT_FIELDS = new Set(['owners', 'admins', 'roles', 'access']);
68
+ const CRITICAL_AGENT_FIELDS = new Set(['owner', 'owners', 'admins', 'roles', 'access']);
68
69
  const EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'max']);
69
70
  function scalar(rolePermissionKey, valueKind, access = 'role-overridable') {
70
71
  return { class: 'safe-scalar', access, rolePermissionKey, valueKind };
@@ -87,6 +88,11 @@ export function resolveConfigFieldRule(fieldPath, scope) {
87
88
  const top = parts[0];
88
89
  if (SENSITIVE_TOP_FIELDS.has(top))
89
90
  return { class: 'sensitive' };
91
+ if (top === 'Services') {
92
+ return parts.length === 3 && /^[A-Za-z0-9_-]+$/u.test(parts[1]) && ['provider', 'model', 'effort'].includes(parts[2])
93
+ ? scalar(field, parts[2] === 'effort' ? 'effort' : 'string', 'owner-only')
94
+ : { class: 'sensitive' };
95
+ }
90
96
  if (top === 'baseagents') {
91
97
  if (parts.length < 3)
92
98
  return { class: 'sensitive' };
@@ -101,6 +107,8 @@ export function resolveConfigFieldRule(fieldPath, scope) {
101
107
  ? 'effort'
102
108
  : leaf;
103
109
  const permissionKey = `baseagents.${baseagent}.${normalizedLeaf}`;
110
+ if (leaf === 'provider' && parts.length === 3)
111
+ return scalar(permissionKey, 'string', 'owner-only');
104
112
  if ((leaf === 'model' || leaf === 'auxiliaryModel') && parts.length === 3)
105
113
  return scalar(permissionKey, 'string');
106
114
  if ((leaf === 'effort' || leaf === 'reasoning' || leaf === 'auxiliaryEffort') && parts.length === 3)