evolcore 0.0.24 → 0.0.25

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 (197) hide show
  1. package/CHANGELOG.md +578 -561
  2. package/LICENSE +21 -21
  3. package/README.md +455 -455
  4. package/bin/codex-managed-acl.ps1 +160 -160
  5. package/bin/codex-managed-hook.mjs +208 -208
  6. package/bin/ec-safe-output.js +327 -327
  7. package/bin/ec.js +29 -29
  8. package/bin/install-codex-managed-hooks.mjs +555 -555
  9. package/dist/agents/claude-runner.js +4 -1
  10. package/dist/agents/codex-runner.js +7 -4
  11. package/dist/agents/ecagent-runner.js +14 -13
  12. package/dist/agents/gemini-runner.js +22 -2
  13. package/dist/aun/aid/agentmd.js +56 -4
  14. package/dist/aun/aid/index.js +1 -0
  15. package/dist/aun/aid/managed-operation.js +53 -1
  16. package/dist/aun/storage/client.js +4 -1
  17. package/dist/aun/storage/index.js +1 -1
  18. package/dist/cli/agent-command.js +186 -87
  19. package/dist/cli/agent-create.js +42 -4
  20. package/dist/cli/agent.js +103 -1
  21. package/dist/cli/aun-commands.js +360 -294
  22. package/dist/cli/bench.js +20 -20
  23. package/dist/cli/config.js +20 -20
  24. package/dist/cli/contact.js +10 -10
  25. package/dist/cli/ctl-command.js +22 -22
  26. package/dist/cli/daemon-commands.js +15 -15
  27. package/dist/cli/fs-command.js +67 -67
  28. package/dist/cli/handoff-command.js +7 -7
  29. package/dist/cli/index.js +77 -77
  30. package/dist/cli/link-rules.js +21 -21
  31. package/dist/cli/menu-client.js +11 -11
  32. package/dist/cli/net-check.js +22 -22
  33. package/dist/cli/queue-command.js +29 -29
  34. package/dist/cli/response.js +30 -30
  35. package/dist/cli/restart-monitor.js +30 -30
  36. package/dist/cli/stats.js +51 -51
  37. package/dist/cli/trigger-command.js +56 -56
  38. package/dist/config/builtin-roles.js +1 -0
  39. package/dist/config/config-manager.js +15 -0
  40. package/dist/config/config-operation-service.js +20 -3
  41. package/dist/config/resolved-config-op.js +39 -1
  42. package/dist/core/auth/operation-authorizer.js +62 -4
  43. package/dist/core/auth/operation-catalog.js +16 -0
  44. package/dist/core/command/agent-control.js +54 -25
  45. package/dist/core/command/cli-intent-parser.js +18 -0
  46. package/dist/core/command/command-handler.js +91 -16
  47. package/dist/core/command/menu-catalog.js +1 -0
  48. package/dist/core/command/menu-handler.js +41 -5
  49. package/dist/core/command/menu-protocol.js +1 -0
  50. package/dist/core/command/slash-handler.js +9 -9
  51. package/dist/core/event-catalog.js +5 -0
  52. package/dist/core/evolagent.js +3 -3
  53. package/dist/core/message/response-engine.js +12 -6
  54. package/dist/core/permission/tool-policy.js +45 -6
  55. package/dist/index.js +209 -162
  56. package/dist/stats/db.js +159 -159
  57. package/dist/stats/eck-vars.js +9 -9
  58. package/dist/stats/query.js +139 -139
  59. package/dist/stats/role-budget.js +6 -6
  60. package/dist/stats/writer.js +51 -51
  61. package/dist/utils/avatar-upload.js +282 -23
  62. package/dist/utils/error-dict.json +160 -160
  63. package/dist/utils/macos-autostart.js +22 -22
  64. package/dist/utils/model-prices.jsonl +23 -23
  65. package/dist/utils/welcome.js +22 -22
  66. package/ecagent/LICENSE +21 -21
  67. package/ecagent/NOTICE +11 -11
  68. package/ecagent/README.md +61 -61
  69. package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
  70. package/ecagent/dist/harness/compaction/compaction.js +83 -83
  71. package/ecagent/dist/harness/messages.js +7 -7
  72. package/kits/docs/GUIDE.md +20 -20
  73. package/kits/docs/INDEX.md +66 -66
  74. package/kits/docs/aun/CHEATSHEET.md +19 -19
  75. package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
  76. package/kits/docs/channels/aun.md +56 -56
  77. package/kits/docs/channels/feishu.md +56 -56
  78. package/kits/docs/context-assembly.md +365 -364
  79. package/kits/docs/eck_templates/GUIDE.template.md +22 -22
  80. package/kits/docs/eck_templates/INDEX.template.md +28 -28
  81. package/kits/docs/eck_templates/path-registry.template.md +33 -33
  82. package/kits/docs/eck_templates/runtime.template.md +19 -19
  83. package/kits/docs/evolcore/INDEX.md +71 -69
  84. package/kits/docs/evolcore/agent-create.md +170 -156
  85. package/kits/docs/evolcore/agent.md +83 -73
  86. package/kits/docs/evolcore/aid.md +64 -62
  87. package/kits/docs/evolcore/codex-windows-sandbox.md +146 -0
  88. package/kits/docs/evolcore/config.md +195 -195
  89. package/kits/docs/evolcore/contact.md +68 -68
  90. package/kits/docs/evolcore/ctl.md +46 -46
  91. package/kits/docs/evolcore/event.md +216 -216
  92. package/kits/docs/evolcore/fs-architecture.md +1215 -1215
  93. package/kits/docs/evolcore/fs.md +110 -110
  94. package/kits/docs/evolcore/group-collaboration.md +243 -243
  95. package/kits/docs/evolcore/group-fs.md +17 -17
  96. package/kits/docs/evolcore/group-rules.md +251 -251
  97. package/kits/docs/evolcore/group.md +152 -152
  98. package/kits/docs/evolcore/menu-client.md +34 -34
  99. package/kits/docs/evolcore/model.md +50 -50
  100. package/kits/docs/evolcore/msg.md +165 -165
  101. package/kits/docs/evolcore/response.md +75 -75
  102. package/kits/docs/evolcore/rpc.md +37 -37
  103. package/kits/docs/evolcore/self-summary.md +29 -29
  104. package/kits/docs/evolcore/stats.md +83 -83
  105. package/kits/docs/evolcore/storage.md +50 -50
  106. package/kits/docs/evolcore/trigger.md +575 -575
  107. package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
  108. package/kits/docs/identity/PATH_OPS.md +16 -16
  109. package/kits/docs/identity/ROLE_DETAIL.md +25 -25
  110. package/kits/docs/identity/identity-tools.md +26 -26
  111. package/kits/docs/path-registry.md +62 -62
  112. package/kits/docs/prompt-loading-architecture.md +270 -269
  113. package/kits/docs/venues/aun-group.md +45 -45
  114. package/kits/docs/venues/aun-private.md +10 -10
  115. package/kits/docs/venues/client-desktop.md +10 -10
  116. package/kits/docs/venues/client-mobile.md +10 -10
  117. package/kits/docs/venues/feishu-group.md +13 -13
  118. package/kits/docs/venues/feishu-private.md +9 -9
  119. package/kits/docs/venues/group.md +25 -25
  120. package/kits/docs/venues/private.md +10 -10
  121. package/kits/eck_manifest.auxiliary.json +43 -43
  122. package/kits/eck_manifest.json +195 -183
  123. package/kits/eck_message_manifest.json +74 -74
  124. package/kits/migrations/README-role-config-v4.md +32 -32
  125. package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
  126. package/kits/migrations/migrate-role-config-v4.mjs +614 -614
  127. package/kits/migrations/migrate-role-config-v5.mjs +365 -365
  128. package/kits/migrations/rename-config-file.mjs +99 -99
  129. package/kits/rules/01-overview.md +162 -162
  130. package/kits/rules/02-navigation.md +96 -96
  131. package/kits/rules/03-identity.md +39 -37
  132. package/kits/rules/04-relation.md +75 -75
  133. package/kits/rules/05-venue.md +60 -60
  134. package/kits/rules/06-channel.md +63 -63
  135. package/kits/schemas/_meta.json +53 -53
  136. package/kits/schemas/agent-config.schema.1.json +177 -177
  137. package/kits/schemas/agent-config.schema.10.json +395 -395
  138. package/kits/schemas/agent-config.schema.11.json +421 -421
  139. package/kits/schemas/agent-config.schema.12.json +427 -427
  140. package/kits/schemas/agent-config.schema.2.json +239 -239
  141. package/kits/schemas/agent-config.schema.3.json +119 -119
  142. package/kits/schemas/agent-config.schema.4.json +208 -208
  143. package/kits/schemas/agent-config.schema.5.json +326 -326
  144. package/kits/schemas/agent-config.schema.6.json +322 -322
  145. package/kits/schemas/agent-config.schema.7.json +303 -303
  146. package/kits/schemas/agent-config.schema.8.json +304 -304
  147. package/kits/schemas/agent-config.schema.9.json +364 -364
  148. package/kits/schemas/contact-book.schema.1.json +36 -36
  149. package/kits/schemas/contact-book.schema.2.json +43 -43
  150. package/kits/schemas/contact-book.schema.3.json +67 -67
  151. package/kits/schemas/daemon.schema.1.json +91 -91
  152. package/kits/schemas/daemon.schema.2.json +101 -101
  153. package/kits/schemas/daemon.schema.3.json +123 -123
  154. package/kits/schemas/daemon.schema.4.json +136 -136
  155. package/kits/schemas/daemon.schema.5.json +135 -135
  156. package/kits/schemas/daemon.schema.6.json +131 -131
  157. package/kits/schemas/defaults.schema.1.json +81 -81
  158. package/kits/schemas/defaults.schema.2.json +85 -85
  159. package/kits/schemas/defaults.schema.3.json +73 -73
  160. package/kits/schemas/defaults.schema.4.json +107 -107
  161. package/kits/schemas/defaults.schema.5.json +119 -119
  162. package/kits/schemas/menu-exec-schema-commands.md +208 -208
  163. package/kits/schemas/migrations/README.md +30 -30
  164. package/kits/schemas/relation-config.schema.1.json +158 -158
  165. package/kits/schemas/relation-config.schema.2.json +73 -73
  166. package/kits/schemas/relation-config.schema.3.json +50 -50
  167. package/kits/schemas/relation-config.schema.4.json +47 -47
  168. package/kits/schemas/relation-config.schema.5.json +47 -47
  169. package/kits/schemas/relation-config.schema.6.json +46 -46
  170. package/kits/schemas/relation-config.schema.7.json +59 -59
  171. package/kits/schemas/relation-config.schema.8.json +103 -103
  172. package/kits/schemas/role-config.schema.1.json +201 -201
  173. package/kits/schemas/role-registry.schema.1.json +35 -35
  174. package/kits/schemas/single-session.schema.1.json +31 -31
  175. package/kits/schemas/single-session.schema.2.json +57 -57
  176. package/kits/schemas/single-session.schema.3.json +32 -32
  177. package/kits/templates/bootstrap-welcome.md +17 -17
  178. package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
  179. package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
  180. package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
  181. package/kits/templates/message-fragments/inject-default.md +2 -2
  182. package/kits/templates/message-fragments/item.md +2 -2
  183. package/kits/templates/roles/admin.json +96 -84
  184. package/kits/templates/roles/member.json +97 -96
  185. package/kits/templates/roles/owner.json +9 -9
  186. package/kits/templates/roles/visitor.json +86 -85
  187. package/kits/templates/system-fragments/baseagent.md +14 -14
  188. package/kits/templates/system-fragments/bootstrap.md +38 -29
  189. package/kits/templates/system-fragments/channel.md +64 -64
  190. package/kits/templates/system-fragments/commands.md +28 -28
  191. package/kits/templates/system-fragments/identity.md +13 -13
  192. package/kits/templates/system-fragments/relation.md +19 -19
  193. package/kits/templates/system-fragments/session.md +59 -59
  194. package/kits/templates/system-fragments/venue.md +31 -31
  195. package/package.json +98 -98
  196. package/skills/eclink/SKILL.md +0 -84
  197. package/skills/eclink/agents/openai.yaml +0 -4
@@ -116,7 +116,7 @@ async function runManagedAid(args, formatJson) {
116
116
  if (!parsed.ok)
117
117
  failManagedAid(formatJson, parsed.code, parsed.reason);
118
118
  const runtime = await readBestTaskRuntimeContext();
119
- const requiresSelfAid = parsed.command.kind === 'show' || parsed.command.kind === 'agentmd.put';
119
+ const requiresSelfAid = parsed.command.kind === 'show' || parsed.command.kind === 'agentmd.put' || parsed.command.kind === 'avatar';
120
120
  if (requiresSelfAid && runtime?.selfAid && parsed.command.aid !== runtime.selfAid.replace(/^@/, '')) {
121
121
  failManagedAid(formatJson, 'SCOPE_MISMATCH', `托管任务只能操作当前 self AID:${runtime.selfAid}`);
122
122
  }
@@ -155,6 +155,22 @@ async function runManagedAid(args, formatJson) {
155
155
  console.log(JSON.stringify({ ok: true, aid: response.result.aid, path: response.result.path }, null, 2));
156
156
  else
157
157
  console.log('✓ agent.md 已发布');
158
+ return;
159
+ case 'avatar':
160
+ if (formatJson)
161
+ console.log(JSON.stringify({
162
+ ok: true,
163
+ aid: response.result.aid,
164
+ avatar: response.result.avatar,
165
+ objectKey: response.result.objectKey,
166
+ sha256: response.result.sha256,
167
+ mime: response.result.mime,
168
+ width: response.result.width,
169
+ height: response.result.height,
170
+ aspectRatio: response.result.aspectRatio,
171
+ }, null, 2));
172
+ else
173
+ console.log(`✓ 头像已更新${response.result.avatar ? `: ${response.result.avatar}` : ''}${response.result.sha256 ? ` (sha256: ${response.result.sha256})` : ''}`);
158
174
  }
159
175
  }
160
176
  function failManagedGroup(formatJson, code, error) {
@@ -332,36 +348,37 @@ export async function cmdAid(args) {
332
348
  const formatJson = getArgValue(args, '--format') === 'json';
333
349
  const aunPath = resolveAunPath(args);
334
350
  if (!sub || isHelpFlag(sub)) {
335
- console.log(`用法: ec aid <command>
336
-
337
- Commands:
338
- list 列出本地所有 AID(实测 sign+verify)
339
- show <aid> 查看本地 AID 详情(证书、私钥、签名能力)
340
- new <aid> 创建新 AID 身份
341
- delete <aid> 删除指定本地 AID(无网络注销)
342
- delete --orphan 批量清理无私钥的外部 AID 缓存
343
- delete --no-cert 批量清理无私钥也无公钥证书的孤儿目录
344
- delete --unrecoverable 批量清理云端公钥已变更、本地不可恢复的 AID
345
- 批量删除默认 dry-run,加 --yes 执行
346
- lookup <aid> 远程探测 AID(是否存在 + 网关 + agent.md)
351
+ console.log(`用法: ec aid <command>
352
+
353
+ Commands:
354
+ list 列出本地所有 AID(实测 sign+verify)
355
+ show <aid> 查看本地 AID 详情(证书、私钥、签名能力)
356
+ new <aid> 创建新 AID 身份
357
+ delete <aid> 删除指定本地 AID(无网络注销)
358
+ delete --orphan 批量清理无私钥的外部 AID 缓存
359
+ delete --no-cert 批量清理无私钥也无公钥证书的孤儿目录
360
+ delete --unrecoverable 批量清理云端公钥已变更、本地不可恢复的 AID
361
+ 批量删除默认 dry-run,加 --yes 执行
362
+ lookup <aid> 远程探测 AID(是否存在 + 网关 + agent.md)
347
363
  agentmd put <aid> 读本地 agent.md → 签名 → 上传
348
364
  agentmd get <aid> 下载 agent.md → 验签 → 本地持久化
349
-
350
- Options:
351
- --format json 输出 JSON 格式
352
- --aun-path <path> 指定 AUN keystore 根(默认 EVOLCORE_HOME,可由 AUN_HOME 设置)
353
- --help, -h 各子命令均支持,查看详细用法
354
-
355
- 示例:
356
- ec aid list
357
- ec aid show toleiliang2.agentid.pub
358
- ec aid new reviewer.agentid.pub
359
- ec aid delete --help
360
- ec aid delete old.agentid.pub
361
- ec aid delete --orphan
362
- ec aid delete --unrecoverable --yes
363
- ec aid lookup someone.agentid.pub
364
- ec aid agentmd put mybot.agentid.pub
365
+ avatar <aid> --file <path> | --url <https-url> 上传头像并更新 agent.md
366
+
367
+ Options:
368
+ --format json 输出 JSON 格式
369
+ --aun-path <path> 指定 AUN keystore 根(默认 EVOLCORE_HOME,可由 AUN_HOME 设置)
370
+ --help, -h 各子命令均支持,查看详细用法
371
+
372
+ 示例:
373
+ ec aid list
374
+ ec aid show toleiliang2.agentid.pub
375
+ ec aid new reviewer.agentid.pub
376
+ ec aid delete --help
377
+ ec aid delete old.agentid.pub
378
+ ec aid delete --orphan
379
+ ec aid delete --unrecoverable --yes
380
+ ec aid lookup someone.agentid.pub
381
+ ec aid agentmd put mybot.agentid.pub
365
382
  ec aid agentmd get someone.agentid.pub`);
366
383
  return;
367
384
  }
@@ -372,33 +389,33 @@ Options:
372
389
  const { aidList, aidListVerified, aidCreate, aidShow, aidDelete, aidLookup, agentmdPut, agentmdGet, buildInitialAgentMd, isValidAid } = await import('../aun/aid/index.js');
373
390
  if (sub === 'list') {
374
391
  if (wantsHelp(args)) {
375
- console.log(`用法: ec aid list [筛选选项] [--no-verify] [--format json]
376
-
377
- 列出本地 AID 并跑 sign+verify 自检。
378
-
379
- 筛选选项(可组合,不指定 = 列出 mine + broken + peer-cert):
380
- --mine 仅本地可用身份(实测可签名+验签通过)
381
- --broken 仅有私钥但不可用(公钥不匹配 / 证书过期 / sign 失败)
382
- --peer-cert 仅对端 AID(无私钥,有公钥证书)
383
- --no-cert 仅无私钥无证书的目录(默认隐藏,需用 aid delete --no-cert 清理)
384
-
385
- 选项:
386
- --no-verify 跳过 sign+verify 实测,仅静态扫描(更快,mine/broken 仅按静态判定近似)
387
- --format json JSON 格式输出
388
-
389
- 输出图标:
390
- 🔑 有私钥
391
- ✅ 实测可签名/验签
392
- ❌ 不可签名(公钥不匹配 / sign 失败 / verify 失败等)
393
- ⌛ 证书过期
394
- 📜 有公钥证书
395
- 📄 有 agent.md
396
-
397
- 示例:
398
- ec aid list 列出 mine + broken + peer-cert
399
- ec aid list --mine 仅可用身份
400
- ec aid list --mine --broken 所有有私钥的 AID
401
- ec aid list --no-cert 仅无私钥无证书的孤儿目录
392
+ console.log(`用法: ec aid list [筛选选项] [--no-verify] [--format json]
393
+
394
+ 列出本地 AID 并跑 sign+verify 自检。
395
+
396
+ 筛选选项(可组合,不指定 = 列出 mine + broken + peer-cert):
397
+ --mine 仅本地可用身份(实测可签名+验签通过)
398
+ --broken 仅有私钥但不可用(公钥不匹配 / 证书过期 / sign 失败)
399
+ --peer-cert 仅对端 AID(无私钥,有公钥证书)
400
+ --no-cert 仅无私钥无证书的目录(默认隐藏,需用 aid delete --no-cert 清理)
401
+
402
+ 选项:
403
+ --no-verify 跳过 sign+verify 实测,仅静态扫描(更快,mine/broken 仅按静态判定近似)
404
+ --format json JSON 格式输出
405
+
406
+ 输出图标:
407
+ 🔑 有私钥
408
+ ✅ 实测可签名/验签
409
+ ❌ 不可签名(公钥不匹配 / sign 失败 / verify 失败等)
410
+ ⌛ 证书过期
411
+ 📜 有公钥证书
412
+ 📄 有 agent.md
413
+
414
+ 示例:
415
+ ec aid list 列出 mine + broken + peer-cert
416
+ ec aid list --mine 仅可用身份
417
+ ec aid list --mine --broken 所有有私钥的 AID
418
+ ec aid list --no-cert 仅无私钥无证书的孤儿目录
402
419
  ec aid list --no-verify 跳过实测,快速静态扫描`);
403
420
  return;
404
421
  }
@@ -450,8 +467,8 @@ Options:
450
467
  }
451
468
  if (sub === 'show') {
452
469
  if (wantsHelp(args)) {
453
- console.log(`用法: ec aid show <aid> [--format json]
454
-
470
+ console.log(`用法: ec aid show <aid> [--format json]
471
+
455
472
  查看本地 AID 详情:私钥/证书/agent.md 状态、签名能力实测。`);
456
473
  return;
457
474
  }
@@ -466,16 +483,16 @@ Options:
466
483
  }
467
484
  if (sub === 'new') {
468
485
  if (wantsHelp(args)) {
469
- console.log(`用法: ec aid new <完整AID> [--force] [--format json]
470
-
471
- 创建新 AID 身份:生成 ECDSA 密钥对、向 Issuer 申请证书、构建并上传初始 agent.md。
472
-
473
- 选项:
474
- --force 强制重新注册,覆盖已存在的身份(即使签名验证失败)
475
- --format json 输出 JSON
476
- --aun-path <path> 指定 AUN keystore 根
477
-
478
- 例: ec aid new reviewer.agentid.pub
486
+ console.log(`用法: ec aid new <完整AID> [--force] [--format json]
487
+
488
+ 创建新 AID 身份:生成 ECDSA 密钥对、向 Issuer 申请证书、构建并上传初始 agent.md。
489
+
490
+ 选项:
491
+ --force 强制重新注册,覆盖已存在的身份(即使签名验证失败)
492
+ --format json 输出 JSON
493
+ --aun-path <path> 指定 AUN keystore 根
494
+
495
+ 例: ec aid new reviewer.agentid.pub
479
496
  ec aid new reviewer.agentid.pub --force`);
480
497
  return;
481
498
  }
@@ -558,34 +575,34 @@ Options:
558
575
  }
559
576
  if (sub === 'delete') {
560
577
  if (wantsHelp(args)) {
561
- console.log(`用法: ec aid delete <子命令>
562
-
563
- 单个删除:
564
- ec aid delete <aid> 删除指定 AID 的本地数据(无网络注销)
565
-
566
- 批量删除(默认 dry-run,加 --yes 才真删):
567
- ec aid delete --orphan 删除所有"无私钥"的本地缓存(外部 AID)
568
- ec aid delete --no-cert 删除所有"无私钥也无公钥证书"的目录
569
- 条件:!hasPrivateKey && !hasCert
570
- 这些目录最多只剩 agent.md 或 SQLite 残留,
571
- 对验签和加密通信都没用,删除安全。
572
- ec aid delete --unrecoverable 删除所有不可恢复的 AID
573
- 条件:本地 sign+verify 实测失败
574
- 且 PKI 探测确认云端公钥也不等本地 key.json
575
-
576
- 选项:
577
- --yes 跳过 dry-run,立即执行
578
- --skip-pki --unrecoverable 时跳过 PKI 探测,仅依据本地 sign+verify 失败判断(危险,可能误删可恢复 AID)
579
- --format json 输出 JSON 格式
580
- --aun-path <path> 指定 AUN keystore 根
581
-
582
- 示例:
583
- ec aid delete old.agentid.pub
584
- ec aid delete --orphan 列出会被清理的孤儿
585
- ec aid delete --orphan --yes 实际清理
586
- ec aid delete --no-cert 列出无证书孤儿目录
587
- ec aid delete --no-cert --yes 实际清理
588
- ec aid delete --unrecoverable 联网探测后列出无救 AID
578
+ console.log(`用法: ec aid delete <子命令>
579
+
580
+ 单个删除:
581
+ ec aid delete <aid> 删除指定 AID 的本地数据(无网络注销)
582
+
583
+ 批量删除(默认 dry-run,加 --yes 才真删):
584
+ ec aid delete --orphan 删除所有"无私钥"的本地缓存(外部 AID)
585
+ ec aid delete --no-cert 删除所有"无私钥也无公钥证书"的目录
586
+ 条件:!hasPrivateKey && !hasCert
587
+ 这些目录最多只剩 agent.md 或 SQLite 残留,
588
+ 对验签和加密通信都没用,删除安全。
589
+ ec aid delete --unrecoverable 删除所有不可恢复的 AID
590
+ 条件:本地 sign+verify 实测失败
591
+ 且 PKI 探测确认云端公钥也不等本地 key.json
592
+
593
+ 选项:
594
+ --yes 跳过 dry-run,立即执行
595
+ --skip-pki --unrecoverable 时跳过 PKI 探测,仅依据本地 sign+verify 失败判断(危险,可能误删可恢复 AID)
596
+ --format json 输出 JSON 格式
597
+ --aun-path <path> 指定 AUN keystore 根
598
+
599
+ 示例:
600
+ ec aid delete old.agentid.pub
601
+ ec aid delete --orphan 列出会被清理的孤儿
602
+ ec aid delete --orphan --yes 实际清理
603
+ ec aid delete --no-cert 列出无证书孤儿目录
604
+ ec aid delete --no-cert --yes 实际清理
605
+ ec aid delete --unrecoverable 联网探测后列出无救 AID
589
606
  ec aid delete --unrecoverable --yes`);
590
607
  return;
591
608
  }
@@ -715,8 +732,8 @@ Options:
715
732
  }
716
733
  if (sub === 'lookup') {
717
734
  if (wantsHelp(args)) {
718
- console.log(`用法: ec aid lookup <aid> [--format json]
719
-
735
+ console.log(`用法: ec aid lookup <aid> [--format json]
736
+
720
737
  远程探测 AID:是否注册、所在网关、是否有 agent.md(不验签,仅获取)。`);
721
738
  return;
722
739
  }
@@ -737,9 +754,9 @@ Options:
737
754
  const verb = args[1];
738
755
  const aid = args[2];
739
756
  if (!verb || isHelpFlag(verb) || wantsHelp(args)) {
740
- console.log(`用法: ec aid agentmd <put|get> <aid> [--format json]
741
-
742
- put <aid> 读本地 agent.md → 用本地私钥签名 → 上传到 PKI
757
+ console.log(`用法: ec aid agentmd <put|get> <aid> [--format json]
758
+
759
+ put <aid> 读本地 agent.md → 用本地私钥签名 → 上传到 PKI
743
760
  get <aid> 从 PKI 下载 agent.md → 验签 → 持久化到本地`);
744
761
  return;
745
762
  }
@@ -795,30 +812,79 @@ Options:
795
812
  console.error(`未知子命令: aid agentmd ${verb ?? ''}\n用法: ec aid agentmd [put|get] <aid>`);
796
813
  process.exit(1);
797
814
  }
798
- console.error(`未知子命令: ${sub}\n用法: ec aid [list|show|new|delete|lookup|agentmd] <aid>`);
815
+ if (sub === 'avatar') {
816
+ const aid = args[1];
817
+ const fileIndex = args.indexOf('--file');
818
+ const urlIndex = args.indexOf('--url');
819
+ const filePath = fileIndex >= 0 ? args[fileIndex + 1] : undefined;
820
+ const url = urlIndex >= 0 ? args[urlIndex + 1] : undefined;
821
+ if (wantsHelp(args)) {
822
+ console.log('用法: ec aid avatar <aid> (--file <path> | --url <https-url>) [--format json]');
823
+ return;
824
+ }
825
+ const sourceCount = (fileIndex >= 0 ? 1 : 0) + (urlIndex >= 0 ? 1 : 0);
826
+ if (!aid || sourceCount !== 1 || (fileIndex >= 0 && (!filePath || filePath.startsWith('-')))
827
+ || (urlIndex >= 0 && (!url || url.startsWith('-'))) || (fileIndex >= 0 && fileIndex !== 2) || (urlIndex >= 0 && urlIndex !== 2)
828
+ || args.filter(value => value === '--file').length > 1 || args.filter(value => value === '--url').length > 1 || !isValidAid(aid)
829
+ || (args.includes('--format') && !formatJson) || (args.includes('--format') && args.filter(value => value === '--format').length !== 1)) {
830
+ const usage = '用法: ec aid avatar <aid> (--file <path> | --url <https-url>) [--format json]';
831
+ if (formatJson)
832
+ console.log(JSON.stringify({ ok: false, code: 'INVALID_ARGUMENT', error: usage }, null, 2));
833
+ else
834
+ console.error(usage);
835
+ process.exit(1);
836
+ }
837
+ const { uploadAvatarFile, uploadAvatarUrl } = await import('../utils/avatar-upload.js');
838
+ const result = filePath
839
+ ? await uploadAvatarFile(aid, filePath, { aunPath })
840
+ : await uploadAvatarUrl(aid, url, { aunPath });
841
+ if (!result.ok) {
842
+ if (formatJson)
843
+ console.log(JSON.stringify({ ok: false, code: result.code, error: result.error }, null, 2));
844
+ else
845
+ console.error(`❌ 头像上传失败: ${result.error}`);
846
+ process.exit(1);
847
+ }
848
+ if (formatJson)
849
+ console.log(JSON.stringify({
850
+ ok: true,
851
+ aid,
852
+ avatar: result.publicUrl,
853
+ objectKey: result.objectKey,
854
+ sha256: result.sha256,
855
+ mime: result.mime,
856
+ width: result.width,
857
+ height: result.height,
858
+ aspectRatio: result.aspectRatio,
859
+ }, null, 2));
860
+ else
861
+ console.log(`✓ 头像已更新${result.publicUrl ? `: ${result.publicUrl}` : ''}${result.sha256 ? ` (sha256: ${result.sha256})` : ''}`);
862
+ return;
863
+ }
864
+ console.error(`未知子命令: ${sub}\n用法: ec aid [list|show|new|delete|lookup|agentmd|avatar] <aid>`);
799
865
  process.exit(1);
800
866
  }
801
867
  // ==================== RPC ====================
802
868
  export async function cmdRpc(args) {
803
869
  if (args.length === 0 || wantsHelp(args)) {
804
- console.log(`用法: ec rpc --as <aid> --params <params>
805
-
806
- 通用 AUN RPC 调用。
807
-
808
- --params 自动判断输入形式:
809
- 单行 JSON (以 { 开头) → 单次调用
810
- 多行 JSONL → 逐行执行,失败即停
811
- 文件路径 (文件存在) → 读取文件内容作为 JSONL
812
-
813
- 每行 JSON 格式: {"method":"<namespace.method>","params":{...}}
814
-
815
- Options:
816
- --app <name> 指定应用 slot(独立消费通道)。仅对 message.pull / group.pull
817
- 等消费类方法有意义——隔离 seq 游标与消息过滤;默认与 daemon 共享通道。
818
- --aun-path <path> 指定 AUN keystore 根
819
-
820
- 示例:
821
- ec rpc --as alice.agentid.pub --params '{"method":"message.send","params":{"to":"bob.agentid.pub","payload":{"type":"text","text":"hello"}}}'
870
+ console.log(`用法: ec rpc --as <aid> --params <params>
871
+
872
+ 通用 AUN RPC 调用。
873
+
874
+ --params 自动判断输入形式:
875
+ 单行 JSON (以 { 开头) → 单次调用
876
+ 多行 JSONL → 逐行执行,失败即停
877
+ 文件路径 (文件存在) → 读取文件内容作为 JSONL
878
+
879
+ 每行 JSON 格式: {"method":"<namespace.method>","params":{...}}
880
+
881
+ Options:
882
+ --app <name> 指定应用 slot(独立消费通道)。仅对 message.pull / group.pull
883
+ 等消费类方法有意义——隔离 seq 游标与消息过滤;默认与 daemon 共享通道。
884
+ --aun-path <path> 指定 AUN keystore 根
885
+
886
+ 示例:
887
+ ec rpc --as alice.agentid.pub --params '{"method":"message.send","params":{"to":"bob.agentid.pub","payload":{"type":"text","text":"hello"}}}'
822
888
  ec rpc --as alice.agentid.pub --params calls.jsonl`);
823
889
  return;
824
890
  }
@@ -886,29 +952,29 @@ export async function cmdStorage(args) {
886
952
  const aunPath = resolveAunPath(args);
887
953
  const formatJson = getArgValue(args, '--format') === 'json';
888
954
  if (!sub || wantsHelp(args)) {
889
- console.log(`用法: ec storage <command> <aid> [options]
890
-
891
- Commands:
892
- upload <aid> <local-file> <remote-path> [--public] 上传文件(默认私有)
893
- download <aid> <url> [local-path] 下载文件
894
- ls <aid> [prefix] 列文件
895
- rm <aid> <remote-path> 删文件
896
- quota <aid> 查配额
897
-
898
- <url> 格式: [https://]<owner-aid>/<path>
899
-
900
- Options:
901
- --public 上传后公开可读(仅 upload)
902
- --format json 输出 JSON
903
- --aun-path <path> 指定 AUN keystore 根
904
-
905
- 示例:
906
- ec storage upload myaid.agentid.pub ./doc.txt notes/doc.txt
907
- ec storage upload myaid.agentid.pub ./pic.png images/pic.png --public
908
- ec storage download myaid.agentid.pub myaid.agentid.pub/notes/doc.txt ./doc.txt
909
- ec storage download myaid.agentid.pub bob.agentid.pub/public/file.pdf ./file.pdf
910
- ec storage ls myaid.agentid.pub notes/
911
- ec storage rm myaid.agentid.pub notes/doc.txt
955
+ console.log(`用法: ec storage <command> <aid> [options]
956
+
957
+ Commands:
958
+ upload <aid> <local-file> <remote-path> [--public] 上传文件(默认私有)
959
+ download <aid> <url> [local-path] 下载文件
960
+ ls <aid> [prefix] 列文件
961
+ rm <aid> <remote-path> 删文件
962
+ quota <aid> 查配额
963
+
964
+ <url> 格式: [https://]<owner-aid>/<path>
965
+
966
+ Options:
967
+ --public 上传后公开可读(仅 upload)
968
+ --format json 输出 JSON
969
+ --aun-path <path> 指定 AUN keystore 根
970
+
971
+ 示例:
972
+ ec storage upload myaid.agentid.pub ./doc.txt notes/doc.txt
973
+ ec storage upload myaid.agentid.pub ./pic.png images/pic.png --public
974
+ ec storage download myaid.agentid.pub myaid.agentid.pub/notes/doc.txt ./doc.txt
975
+ ec storage download myaid.agentid.pub bob.agentid.pub/public/file.pdf ./file.pdf
976
+ ec storage ls myaid.agentid.pub notes/
977
+ ec storage rm myaid.agentid.pub notes/doc.txt
912
978
  ec storage quota myaid.agentid.pub`);
913
979
  return;
914
980
  }
@@ -1063,83 +1129,83 @@ export async function cmdMsg(args) {
1063
1129
  const formatJson = getArgValue(args, '--format') === 'json';
1064
1130
  const appSlot = getArgValue(args, '--app');
1065
1131
  if (!sub || isHelpFlag(sub) || (wantsHelp(args) && sub !== 'history')) {
1066
- console.log(`用法: ec msg <command> <from-aid> [args...] [options]
1067
-
1068
- Commands:
1069
- send <from> <to> <text> --return <none|required> 发送文本(跨会话时 --return 必填)
1070
- send <from> <to> --text-from-file <path> 从文件读取文本内容
1071
- send <from> <to> --file <path> [--as <type>] 发送文件(image|video|voice|file)
1072
- send <from> <to> --link <url> [--title T] 发送链接卡片
1073
- send <from> <to> --payload <json> 发送自定义 payload
1132
+ console.log(`用法: ec msg <command> <from-aid> [args...] [options]
1133
+
1134
+ Commands:
1135
+ send <from> <to> <text> --return <none|required> 发送文本(跨会话时 --return 必填)
1136
+ send <from> <to> --text-from-file <path> 从文件读取文本内容
1137
+ send <from> <to> --file <path> [--as <type>] 发送文件(image|video|voice|file)
1138
+ send <from> <to> --link <url> [--title T] 发送链接卡片
1139
+ send <from> <to> --payload <json> 发送自定义 payload
1074
1140
  pull <from> [--after-seq N] [--limit N] --app <name> 拉取收件箱(必须使用独立 slot)
1075
- ack <from> <seq> [--app <name>] 确认已读
1076
- recall <from> <message-id> [<message-id>...] 撤回消息
1077
- online <from> <target-aid> [<target-aid>...] 查询在线状态
1078
- history <from> [<target-aid>|selector] [筛选选项] 查询本地消息历史
1079
-
1080
- Options:
1081
- --text-from-file <path> 从文件读取文本(UTF-8),用于超长消息或避免 Shell 转义
1082
- --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
1083
- --aun-path <path> 指定 AUN keystore 根
1084
- --format json 输出 JSON 格式
1085
- --encrypt 强制端到端加密(未指定时使用 daemon 默认值)
1086
- --no-encrypt 强制明文发送(优先于 --encrypt)
1087
- --thread <id> 指定话题 ID(用于多话题路由)
1088
- --session <latest|all|id> 按 EvolCore 逻辑会话过滤历史(默认 latest)
1089
- --before <time> 只返回该时间之前的历史
1090
- --after <time> 只返回该时间之后的历史
1091
- --direction <value> 历史方向:in|out|all
1092
- --channel <type> 历史渠道:aun|feishu|wechat|dingtalk|qqbot|wecom
1093
- --channel-name <name> 历史渠道实例名(非 AUN 渠道必须匹配 Agent 配置)
1094
- --channel-key <key> 非 AUN 已落盘渠道的完整实例键(与 --peer-id 成对)
1095
- --peer-id <id> 非 AUN 渠道的原生对端 ID(与 --channel-key 成对)
1096
- --return <none|required> 跨会话发送必填:none=仅补充目标上下文,required=回答回流来源
1097
- --content-type <mime> 显式覆盖 MIME(仅 --file 模式)
1098
- --as <type> 附件类型:image|video|voice|file(仅 --file 模式)
1099
- --text <说明> 附件说明文字(仅 --file 模式)
1100
- --transcript <text> 语音转写(仅 --as voice)
1101
- --title <text> 链接标题(仅 --link 模式)
1102
- --description <text> 链接描述(仅 --link 模式)
1103
- -- end-of-options:其后所有参数按正文处理
1104
- (用于发送恰好等于某 flag 的文本,如 send a b -- --encrypt)
1105
-
1106
- 示例:
1107
- ec msg send alice.agentid.pub bob.agentid.pub "hello" --return none
1108
- ec msg send alice.agentid.pub bob.agentid.pub --text-from-file long-message.txt --return none
1109
- ec msg send alice.agentid.pub bob.agentid.pub "讨论项目A" --thread "project-A" --return required
1110
- ec msg send alice.agentid.pub bob.agentid.pub --file ./pic.png --return none
1111
- ec msg send alice.agentid.pub bob.agentid.pub --file ./demo.mp4 --as video --return none
1112
- ec msg send alice.agentid.pub bob.agentid.pub --link https://example.com --title "AUN" --return none
1113
- ec msg pull alice.agentid.pub --app my-bot
1114
- ec msg ack alice.agentid.pub 42 --app my-bot
1115
- ec msg recall alice.agentid.pub msg-uuid-1 msg-uuid-2
1116
- ec msg online alice.agentid.pub bob.agentid.pub carol.agentid.pub
1117
- ec msg history alice.agentid.pub bob.agentid.pub --session latest --limit 50
1141
+ ack <from> <seq> [--app <name>] 确认已读
1142
+ recall <from> <message-id> [<message-id>...] 撤回消息
1143
+ online <from> <target-aid> [<target-aid>...] 查询在线状态
1144
+ history <from> [<target-aid>|selector] [筛选选项] 查询本地消息历史
1145
+
1146
+ Options:
1147
+ --text-from-file <path> 从文件读取文本(UTF-8),用于超长消息或避免 Shell 转义
1148
+ --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
1149
+ --aun-path <path> 指定 AUN keystore 根
1150
+ --format json 输出 JSON 格式
1151
+ --encrypt 强制端到端加密(未指定时使用 daemon 默认值)
1152
+ --no-encrypt 强制明文发送(优先于 --encrypt)
1153
+ --thread <id> 指定话题 ID(用于多话题路由)
1154
+ --session <latest|all|id> 按 EvolCore 逻辑会话过滤历史(默认 latest)
1155
+ --before <time> 只返回该时间之前的历史
1156
+ --after <time> 只返回该时间之后的历史
1157
+ --direction <value> 历史方向:in|out|all
1158
+ --channel <type> 历史渠道:aun|feishu|wechat|dingtalk|qqbot|wecom
1159
+ --channel-name <name> 历史渠道实例名(非 AUN 渠道必须匹配 Agent 配置)
1160
+ --channel-key <key> 非 AUN 已落盘渠道的完整实例键(与 --peer-id 成对)
1161
+ --peer-id <id> 非 AUN 渠道的原生对端 ID(与 --channel-key 成对)
1162
+ --return <none|required> 跨会话发送必填:none=仅补充目标上下文,required=回答回流来源
1163
+ --content-type <mime> 显式覆盖 MIME(仅 --file 模式)
1164
+ --as <type> 附件类型:image|video|voice|file(仅 --file 模式)
1165
+ --text <说明> 附件说明文字(仅 --file 模式)
1166
+ --transcript <text> 语音转写(仅 --as voice)
1167
+ --title <text> 链接标题(仅 --link 模式)
1168
+ --description <text> 链接描述(仅 --link 模式)
1169
+ -- end-of-options:其后所有参数按正文处理
1170
+ (用于发送恰好等于某 flag 的文本,如 send a b -- --encrypt)
1171
+
1172
+ 示例:
1173
+ ec msg send alice.agentid.pub bob.agentid.pub "hello" --return none
1174
+ ec msg send alice.agentid.pub bob.agentid.pub --text-from-file long-message.txt --return none
1175
+ ec msg send alice.agentid.pub bob.agentid.pub "讨论项目A" --thread "project-A" --return required
1176
+ ec msg send alice.agentid.pub bob.agentid.pub --file ./pic.png --return none
1177
+ ec msg send alice.agentid.pub bob.agentid.pub --file ./demo.mp4 --as video --return none
1178
+ ec msg send alice.agentid.pub bob.agentid.pub --link https://example.com --title "AUN" --return none
1179
+ ec msg pull alice.agentid.pub --app my-bot
1180
+ ec msg ack alice.agentid.pub 42 --app my-bot
1181
+ ec msg recall alice.agentid.pub msg-uuid-1 msg-uuid-2
1182
+ ec msg online alice.agentid.pub bob.agentid.pub carol.agentid.pub
1183
+ ec msg history alice.agentid.pub bob.agentid.pub --session latest --limit 50
1118
1184
  ec msg history alice.agentid.pub --channel-key feishu#alice.agentid.pub#main --peer-id ou_xxx --session all --format json`);
1119
1185
  return;
1120
1186
  }
1121
1187
  if (sub === 'history' && wantsHelp(args)) {
1122
- console.log(`用法: ec msg history <self-aid> [<target-aid> | --channel-key <key> --peer-id <id>] [options]
1123
-
1124
- 查询指定会话对的本地历史,不调用 message.pull,也不影响收件箱游标。非 AUN selector 按已落盘的 session metadata、完整 channelKey 与原生 peer ID 精确读取,不能传入文件路径。
1125
-
1126
- 托管会话限制:普通会话只能使用当前 self AID 和当前 AUN 私聊对端;可信 daemon Trigger 可用精确的 --channel-key/--peer-id selector 读取已落盘的非 AUN 私聊历史。托管任务不支持 --channel、--channel-name、--aun-path 或 --app。
1127
-
1128
- Options:
1129
- --session <latest|all|id> 默认 latest;all 查询全部;也可指定会话 ID
1130
- --limit <N> 返回最新 N 条(默认 50,最大 500)
1131
- --before <time> 开区间;epoch 毫秒或 ISO 时间
1132
- --after <time> 开区间;epoch 毫秒或 ISO 时间
1133
- --direction <value> in|out|all(默认 all)
1134
- --channel-key <key> 非 AUN 已落盘渠道完整键;必须与 --peer-id 同时给出
1135
- --peer-id <id> 原生私聊对端 ID;必须与 --channel-key 同时给出
1136
- --format <text|json> 输出格式(默认 text)
1137
-
1138
- 示例:
1139
- ec msg history alice.agentid.pub bob.agentid.pub
1140
- ec msg history alice.agentid.pub bob.agentid.pub --session latest
1141
- ec msg history alice.agentid.pub bob.agentid.pub --session all
1142
- ec msg history alice.agentid.pub bob.agentid.pub --session meta_20260713_1783920000000 --format json
1188
+ console.log(`用法: ec msg history <self-aid> [<target-aid> | --channel-key <key> --peer-id <id>] [options]
1189
+
1190
+ 查询指定会话对的本地历史,不调用 message.pull,也不影响收件箱游标。非 AUN selector 按已落盘的 session metadata、完整 channelKey 与原生 peer ID 精确读取,不能传入文件路径。
1191
+
1192
+ 托管会话限制:普通会话只能使用当前 self AID 和当前 AUN 私聊对端;可信 daemon Trigger 可用精确的 --channel-key/--peer-id selector 读取已落盘的非 AUN 私聊历史。托管任务不支持 --channel、--channel-name、--aun-path 或 --app。
1193
+
1194
+ Options:
1195
+ --session <latest|all|id> 默认 latest;all 查询全部;也可指定会话 ID
1196
+ --limit <N> 返回最新 N 条(默认 50,最大 500)
1197
+ --before <time> 开区间;epoch 毫秒或 ISO 时间
1198
+ --after <time> 开区间;epoch 毫秒或 ISO 时间
1199
+ --direction <value> in|out|all(默认 all)
1200
+ --channel-key <key> 非 AUN 已落盘渠道完整键;必须与 --peer-id 同时给出
1201
+ --peer-id <id> 原生私聊对端 ID;必须与 --channel-key 同时给出
1202
+ --format <text|json> 输出格式(默认 text)
1203
+
1204
+ 示例:
1205
+ ec msg history alice.agentid.pub bob.agentid.pub
1206
+ ec msg history alice.agentid.pub bob.agentid.pub --session latest
1207
+ ec msg history alice.agentid.pub bob.agentid.pub --session all
1208
+ ec msg history alice.agentid.pub bob.agentid.pub --session meta_20260713_1783920000000 --format json
1143
1209
  ec msg history alice.agentid.pub --channel-key feishu#alice.agentid.pub#main --peer-id ou_xxx --session all --format json`);
1144
1210
  return;
1145
1211
  }
@@ -1568,74 +1634,74 @@ export async function cmdGroup(args) {
1568
1634
  const appSlot = getArgValue(args, '--app');
1569
1635
  const rulesActionHelp = sub === 'rules' && isHelpFlag(args[3]);
1570
1636
  if (!sub || isHelpFlag(sub) || (wantsHelp(args) && !rulesActionHelp)) {
1571
- console.log(`用法: ec group <command> <from-aid> [args...] [options]
1572
-
1573
- 消息:
1574
- send <from> <group-id> <text> --return <none|required> 发送群文本(跨会话时 --return 必填)
1575
- send <from> <group-id> --file <path> [--as <type>] 发送群文件
1576
- send <from> <group-id> --payload <json> 发送自定义 payload
1637
+ console.log(`用法: ec group <command> <from-aid> [args...] [options]
1638
+
1639
+ 消息:
1640
+ send <from> <group-id> <text> --return <none|required> 发送群文本(跨会话时 --return 必填)
1641
+ send <from> <group-id> --file <path> [--as <type>] 发送群文件
1642
+ send <from> <group-id> --payload <json> 发送自定义 payload
1577
1643
  pull <from> <group-id> [--after-seq N] [--limit N] --app <name> 拉取群消息(必须使用独立 slot)
1578
- ack <from> <group-id> <seq> [--app <name>] 确认已读
1579
-
1580
- 群管理:
1581
- create <from> <name> [--visibility public|private] [--description D]
1582
- [--join-mode open|approval|invite_only|closed] 创建群
1583
- list <from> [--size N] 列出我加入的群
1584
- info <from> <group-id> 查看群详情
1585
- update <from> <group-id> [--name N] [--description D] 修改群信息
1586
- dissolve <from> <group-id> 解散群
1587
- suspend <from> <group-id> 暂停群
1588
- resume <from> <group-id> 恢复群
1589
- rules <from> <group-id> get 读取已发布群规则文件 /rules.md
1590
- rules <from> <group-id> set <file> 上传并发布群规则文件
1591
- rules <from> <group-id> publish 发布当前群空间 /rules.md
1592
- rules <from> <group-id> [--mode M] [--question Q] [--max-pending N] 查看/更新入群规则
1593
-
1594
- 成员:
1595
- join <from> <group-id> [--message M] [--answer A] 申请加入
1596
- leave <from> <group-id> 退出群
1597
- invite <from> <group-id> <member-aid> [<member-aid>...] 创建定向邀请
1598
- invites <from> [--page N] [--size N] 查看收到的邀请
1599
- accept-invite <from> <invite-id> 接受邀请
1600
- reject-invite <from> <invite-id> 拒绝邀请
1601
- revoke-invite <from> <invite-id> 撤回邀请
1602
- kick <from> <group-id> <member-aid> 踢出成员
1603
- members <from> <group-id> [--page N] [--size N] 列出群成员
1604
- online <from> <group-id> 查看在线成员
1605
- role <from> <group-id> <member-aid> <admin|member> 设置成员角色
1606
- owner <from> <group-id> <new-owner-aid> 转让群主
1607
- ban <from> <group-id> [<member-aid>] [--duration N] 封禁成员;不带 member-aid 时列出封禁
1608
- unban <from> <group-id> <member-aid> 解封成员
1609
-
1610
- Options:
1611
- --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
1612
- --aun-path <path> 指定 AUN keystore 根
1613
- --format json 输出 JSON 格式
1614
- --encrypt 强制端到端加密(未指定时使用 daemon 默认值;仅 send)
1615
- --no-encrypt 强制明文发送(优先于 --encrypt;仅 send)
1616
- --thread <id> 指定话题 ID(仅 send)
1617
- --return <none|required> 跨会话发送必填(仅 send;Trigger 只能使用 none)
1618
- --mention <aid> 发送时 @ 某个成员(可多次,或用逗号分隔多个 aid)
1619
- --mention-all 发送时 @ 所有人
1620
- --content-type <mime> 显式覆盖 MIME(仅 --file 模式)
1621
- --as <type> 附件类型:image|video|voice|file(仅 --file 模式)
1622
- --text <说明> 附件说明文字(仅 --file 模式)
1623
- --transcript <text> 语音转写(仅 --as voice)
1624
- --group-id <aid> 指定自定义群 AID(仅 create)
1625
- --member-type <type> 定向邀请成员类型:human|ai(仅 invite)
1626
- -- end-of-options:其后所有参数按正文处理
1627
- (用于发送恰好等于某 flag 的文本,如 send a g -- --encrypt)
1628
-
1629
- 格式示例(.example.invalid 是保留的虚构域,以下 AID 均不是真实地址):
1630
- ec group create sender.example.invalid "Dev Team" --visibility private
1631
- ec group send sender.example.invalid 12345.example.invalid "hello team" --return none
1632
- ec group send sender.example.invalid 12345.example.invalid "@member 看下 PR" --mention member.example.invalid
1633
- ec group send sender.example.invalid 12345.example.invalid --file ./arch.png
1634
- ec group rules sender.example.invalid 12345.example.invalid set ./rules.md
1635
- ec group invite sender.example.invalid 12345.example.invalid member.example.invalid
1636
- ec group members sender.example.invalid 12345.example.invalid
1637
-
1638
- 查询真实群 AID:
1644
+ ack <from> <group-id> <seq> [--app <name>] 确认已读
1645
+
1646
+ 群管理:
1647
+ create <from> <name> [--visibility public|private] [--description D]
1648
+ [--join-mode open|approval|invite_only|closed] 创建群
1649
+ list <from> [--size N] 列出我加入的群
1650
+ info <from> <group-id> 查看群详情
1651
+ update <from> <group-id> [--name N] [--description D] 修改群信息
1652
+ dissolve <from> <group-id> 解散群
1653
+ suspend <from> <group-id> 暂停群
1654
+ resume <from> <group-id> 恢复群
1655
+ rules <from> <group-id> get 读取已发布群规则文件 /rules.md
1656
+ rules <from> <group-id> set <file> 上传并发布群规则文件
1657
+ rules <from> <group-id> publish 发布当前群空间 /rules.md
1658
+ rules <from> <group-id> [--mode M] [--question Q] [--max-pending N] 查看/更新入群规则
1659
+
1660
+ 成员:
1661
+ join <from> <group-id> [--message M] [--answer A] 申请加入
1662
+ leave <from> <group-id> 退出群
1663
+ invite <from> <group-id> <member-aid> [<member-aid>...] 创建定向邀请
1664
+ invites <from> [--page N] [--size N] 查看收到的邀请
1665
+ accept-invite <from> <invite-id> 接受邀请
1666
+ reject-invite <from> <invite-id> 拒绝邀请
1667
+ revoke-invite <from> <invite-id> 撤回邀请
1668
+ kick <from> <group-id> <member-aid> 踢出成员
1669
+ members <from> <group-id> [--page N] [--size N] 列出群成员
1670
+ online <from> <group-id> 查看在线成员
1671
+ role <from> <group-id> <member-aid> <admin|member> 设置成员角色
1672
+ owner <from> <group-id> <new-owner-aid> 转让群主
1673
+ ban <from> <group-id> [<member-aid>] [--duration N] 封禁成员;不带 member-aid 时列出封禁
1674
+ unban <from> <group-id> <member-aid> 解封成员
1675
+
1676
+ Options:
1677
+ --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
1678
+ --aun-path <path> 指定 AUN keystore 根
1679
+ --format json 输出 JSON 格式
1680
+ --encrypt 强制端到端加密(未指定时使用 daemon 默认值;仅 send)
1681
+ --no-encrypt 强制明文发送(优先于 --encrypt;仅 send)
1682
+ --thread <id> 指定话题 ID(仅 send)
1683
+ --return <none|required> 跨会话发送必填(仅 send;Trigger 只能使用 none)
1684
+ --mention <aid> 发送时 @ 某个成员(可多次,或用逗号分隔多个 aid)
1685
+ --mention-all 发送时 @ 所有人
1686
+ --content-type <mime> 显式覆盖 MIME(仅 --file 模式)
1687
+ --as <type> 附件类型:image|video|voice|file(仅 --file 模式)
1688
+ --text <说明> 附件说明文字(仅 --file 模式)
1689
+ --transcript <text> 语音转写(仅 --as voice)
1690
+ --group-id <aid> 指定自定义群 AID(仅 create)
1691
+ --member-type <type> 定向邀请成员类型:human|ai(仅 invite)
1692
+ -- end-of-options:其后所有参数按正文处理
1693
+ (用于发送恰好等于某 flag 的文本,如 send a g -- --encrypt)
1694
+
1695
+ 格式示例(.example.invalid 是保留的虚构域,以下 AID 均不是真实地址):
1696
+ ec group create sender.example.invalid "Dev Team" --visibility private
1697
+ ec group send sender.example.invalid 12345.example.invalid "hello team" --return none
1698
+ ec group send sender.example.invalid 12345.example.invalid "@member 看下 PR" --mention member.example.invalid
1699
+ ec group send sender.example.invalid 12345.example.invalid --file ./arch.png
1700
+ ec group rules sender.example.invalid 12345.example.invalid set ./rules.md
1701
+ ec group invite sender.example.invalid 12345.example.invalid member.example.invalid
1702
+ ec group members sender.example.invalid 12345.example.invalid
1703
+
1704
+ 查询真实群 AID:
1639
1705
  ec group list <发送方AID>`);
1640
1706
  return;
1641
1707
  }
@@ -2067,18 +2133,18 @@ Options:
2067
2133
  const groupId = requireGroupId();
2068
2134
  const action = args[3];
2069
2135
  const printRulesFileUsage = () => {
2070
- console.log(`用法:
2071
- ec group rules <from> <group-id> get
2072
- ec group rules <from> <group-id> set <file>
2073
- ec group rules <from> <group-id> publish
2074
- ec group rules <from> <group-id> [--mode open|approval|invite_only|closed] [--question Q] [--max-pending N]
2075
-
2076
- 说明:
2077
- get 读取当前已发布的群规则文件 /rules.md
2078
- set 上传本地文件到群空间 /rules.md,发布 rules.content 元数据,并发送 group.rules.updated 通知
2079
- publish 不上传文件,仅发布当前群空间 /rules.md 的元数据并发送通知
2080
-
2081
- 兼容:
2136
+ console.log(`用法:
2137
+ ec group rules <from> <group-id> get
2138
+ ec group rules <from> <group-id> set <file>
2139
+ ec group rules <from> <group-id> publish
2140
+ ec group rules <from> <group-id> [--mode open|approval|invite_only|closed] [--question Q] [--max-pending N]
2141
+
2142
+ 说明:
2143
+ get 读取当前已发布的群规则文件 /rules.md
2144
+ set 上传本地文件到群空间 /rules.md,发布 rules.content 元数据,并发送 group.rules.updated 通知
2145
+ publish 不上传文件,仅发布当前群空间 /rules.md 的元数据并发送通知
2146
+
2147
+ 兼容:
2082
2148
  不带 get/set/publish 时仍使用旧的入群规则接口。`);
2083
2149
  };
2084
2150
  const printRulesFileState = (result, verb) => {