evolcore 0.0.23 → 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 (245) hide show
  1. package/CHANGELOG.md +583 -516
  2. package/LICENSE +21 -21
  3. package/README.md +455 -453
  4. package/bin/codex-managed-acl.ps1 +160 -155
  5. package/bin/codex-managed-hook.mjs +209 -92
  6. package/bin/ec-safe-output.js +327 -245
  7. package/bin/ec.js +29 -29
  8. package/bin/install-codex-managed-hooks.mjs +555 -544
  9. package/dist/agents/baseagent-availability.js +4 -4
  10. package/dist/agents/baseagent.js +29 -1
  11. package/dist/agents/claude-runner.js +152 -14
  12. package/dist/agents/codex/app-server-client.js +18 -8
  13. package/dist/agents/codex/catalog.js +1 -1
  14. package/dist/agents/codex/diagnostics.js +215 -0
  15. package/dist/agents/codex-runner.js +445 -63
  16. package/dist/agents/ecagent-runner.js +31 -16
  17. package/dist/agents/gemini-runner.js +82 -4
  18. package/dist/agents/runner-types.js +1 -1
  19. package/dist/aun/aid/agentmd.js +56 -4
  20. package/dist/aun/aid/index.js +1 -0
  21. package/dist/aun/aid/managed-operation.js +80 -6
  22. package/dist/aun/aid/store.js +41 -0
  23. package/dist/aun/msg/managed-operation.js +6 -1
  24. package/dist/aun/outbox.js +56 -18
  25. package/dist/aun/rpc/client.js +4 -5
  26. package/dist/aun/storage/client.js +4 -1
  27. package/dist/aun/storage/index.js +1 -1
  28. package/dist/channels/aun.js +147 -76
  29. package/dist/channels/daemon.js +7 -1
  30. package/dist/channels/dingtalk.js +1 -0
  31. package/dist/channels/feishu.js +10 -4
  32. package/dist/channels/wecom.js +2 -1
  33. package/dist/cli/agent-command.js +214 -89
  34. package/dist/cli/agent-create.js +576 -0
  35. package/dist/cli/agent.js +129 -676
  36. package/dist/cli/aun-commands.js +419 -313
  37. package/dist/cli/bench.js +20 -20
  38. package/dist/cli/config.js +20 -20
  39. package/dist/cli/contact.js +10 -10
  40. package/dist/cli/ctl-command.js +22 -20
  41. package/dist/cli/daemon-commands.js +163 -32
  42. package/dist/cli/fs-command.js +67 -67
  43. package/dist/cli/handoff-command.js +7 -7
  44. package/dist/cli/index.js +79 -79
  45. package/dist/cli/link-rules.js +21 -21
  46. package/dist/cli/managed-command-guard.js +3 -0
  47. package/dist/cli/menu-client.js +11 -11
  48. package/dist/cli/net-check.js +22 -22
  49. package/dist/cli/queue-command.js +29 -29
  50. package/dist/cli/response.js +30 -30
  51. package/dist/cli/restart-monitor.js +462 -38
  52. package/dist/cli/stats.js +161 -51
  53. package/dist/cli/trigger-command.js +56 -56
  54. package/dist/config/builtin-roles.js +3 -0
  55. package/dist/config/config-manager.js +15 -0
  56. package/dist/config/config-operation-service.js +20 -3
  57. package/dist/config/resolved-config-op.js +39 -1
  58. package/dist/core/auth/auth-gateway.js +3 -2
  59. package/dist/core/auth/authorization-audit.js +72 -19
  60. package/dist/core/auth/operation-authorizer.js +125 -7
  61. package/dist/core/auth/operation-catalog.js +26 -2
  62. package/dist/core/auth/remote-access-store.js +3 -2
  63. package/dist/core/baseagent-loader.js +4 -4
  64. package/dist/core/bootstrap-messages.js +39 -18
  65. package/dist/core/bootstrap-service.js +32 -26
  66. package/dist/core/capability/capability-manager.js +8 -4
  67. package/dist/core/capability/providers/codex-capability-provider.js +1 -1
  68. package/dist/core/command/agent-control.js +60 -26
  69. package/dist/core/command/cli-intent-parser.js +18 -0
  70. package/dist/core/command/command-handler.js +173 -36
  71. package/dist/core/command/menu-catalog.js +4 -1
  72. package/dist/core/command/menu-handler.js +315 -75
  73. package/dist/core/command/menu-protocol.js +7 -2
  74. package/dist/core/command/slash-gate.js +1 -3
  75. package/dist/core/command/slash-handler.js +166 -57
  76. package/dist/core/data-migration.js +5 -15
  77. package/dist/core/event-catalog.js +8 -0
  78. package/dist/core/evolagent.js +3 -3
  79. package/dist/core/handoff/runtime.js +3 -1
  80. package/dist/core/handoff/store.js +7 -1
  81. package/dist/core/message/im-renderer.js +13 -6
  82. package/dist/core/message/message-bridge.js +5 -36
  83. package/dist/core/message/message-utils.js +6 -3
  84. package/dist/core/message/response-engine.js +85 -27
  85. package/dist/core/model/catalog-service.js +3 -1
  86. package/dist/core/model/model-catalog.js +10 -0
  87. package/dist/core/model/model-permission.js +4 -1
  88. package/dist/core/permission/approval-gateway.js +169 -33
  89. package/dist/core/permission/tool-policy.js +56 -10
  90. package/dist/core/session/adapters/codex-session-file-adapter.js +71 -3
  91. package/dist/core/session/session-manager.js +49 -13
  92. package/dist/core/session/session-renew.js +1 -0
  93. package/dist/index.js +327 -134
  94. package/dist/ipc.js +68 -21
  95. package/dist/paths.js +23 -1
  96. package/dist/stats/billing.js +18 -4
  97. package/dist/stats/db.js +159 -159
  98. package/dist/stats/eck-vars.js +9 -9
  99. package/dist/stats/query.js +139 -139
  100. package/dist/stats/role-budget.js +6 -6
  101. package/dist/stats/writer.js +51 -51
  102. package/dist/utils/atomic-write.js +26 -2
  103. package/dist/utils/avatar-upload.js +282 -23
  104. package/dist/utils/cross-platform.js +436 -1
  105. package/dist/utils/error-dict.json +160 -160
  106. package/dist/utils/error-utils.js +11 -4
  107. package/dist/utils/macos-autostart.js +22 -22
  108. package/dist/utils/model-prices.jsonl +23 -20
  109. package/dist/utils/npm-ops.js +24 -1
  110. package/dist/utils/welcome.js +22 -22
  111. package/dist/utils/windows-autostart.js +1 -1
  112. package/ecagent/LICENSE +21 -21
  113. package/ecagent/NOTICE +11 -11
  114. package/ecagent/README.md +61 -61
  115. package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
  116. package/ecagent/dist/harness/compaction/compaction.js +83 -83
  117. package/ecagent/dist/harness/messages.js +7 -7
  118. package/kits/docs/GUIDE.md +20 -20
  119. package/kits/docs/INDEX.md +66 -66
  120. package/kits/docs/aun/CHEATSHEET.md +19 -19
  121. package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
  122. package/kits/docs/channels/aun.md +56 -56
  123. package/kits/docs/channels/feishu.md +56 -56
  124. package/kits/docs/context-assembly.md +365 -364
  125. package/kits/docs/eck_templates/GUIDE.template.md +22 -22
  126. package/kits/docs/eck_templates/INDEX.template.md +28 -28
  127. package/kits/docs/eck_templates/path-registry.template.md +33 -33
  128. package/kits/docs/eck_templates/runtime.template.md +19 -19
  129. package/kits/docs/evolcore/INDEX.md +71 -69
  130. package/kits/docs/evolcore/agent-create.md +170 -156
  131. package/kits/docs/evolcore/agent.md +83 -73
  132. package/kits/docs/evolcore/aid.md +64 -62
  133. package/kits/docs/evolcore/codex-windows-sandbox.md +146 -0
  134. package/kits/docs/evolcore/config.md +195 -195
  135. package/kits/docs/evolcore/contact.md +68 -68
  136. package/kits/docs/evolcore/ctl.md +46 -46
  137. package/kits/docs/evolcore/event.md +216 -216
  138. package/kits/docs/evolcore/fs-architecture.md +1215 -1215
  139. package/kits/docs/evolcore/fs.md +110 -110
  140. package/kits/docs/evolcore/group-collaboration.md +243 -243
  141. package/kits/docs/evolcore/group-fs.md +17 -17
  142. package/kits/docs/evolcore/group-rules.md +251 -251
  143. package/kits/docs/evolcore/group.md +152 -152
  144. package/kits/docs/evolcore/menu-client.md +34 -34
  145. package/kits/docs/evolcore/model.md +50 -50
  146. package/kits/docs/evolcore/msg.md +165 -165
  147. package/kits/docs/evolcore/response.md +75 -75
  148. package/kits/docs/evolcore/rpc.md +37 -37
  149. package/kits/docs/evolcore/self-summary.md +29 -29
  150. package/kits/docs/evolcore/stats.md +83 -83
  151. package/kits/docs/evolcore/storage.md +50 -50
  152. package/kits/docs/evolcore/trigger.md +575 -575
  153. package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
  154. package/kits/docs/identity/PATH_OPS.md +16 -16
  155. package/kits/docs/identity/ROLE_DETAIL.md +25 -25
  156. package/kits/docs/identity/identity-tools.md +26 -26
  157. package/kits/docs/path-registry.md +62 -62
  158. package/kits/docs/prompt-loading-architecture.md +270 -269
  159. package/kits/docs/venues/aun-group.md +45 -45
  160. package/kits/docs/venues/aun-private.md +10 -10
  161. package/kits/docs/venues/client-desktop.md +10 -10
  162. package/kits/docs/venues/client-mobile.md +10 -10
  163. package/kits/docs/venues/feishu-group.md +13 -13
  164. package/kits/docs/venues/feishu-private.md +9 -9
  165. package/kits/docs/venues/group.md +25 -25
  166. package/kits/docs/venues/private.md +10 -10
  167. package/kits/eck_manifest.auxiliary.json +43 -43
  168. package/kits/eck_manifest.json +195 -183
  169. package/kits/eck_message_manifest.json +74 -74
  170. package/kits/migrations/README-role-config-v4.md +32 -32
  171. package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
  172. package/kits/migrations/migrate-role-config-v4.mjs +614 -614
  173. package/kits/migrations/migrate-role-config-v5.mjs +365 -365
  174. package/kits/migrations/rename-config-file.mjs +99 -99
  175. package/kits/rules/01-overview.md +162 -162
  176. package/kits/rules/02-navigation.md +96 -96
  177. package/kits/rules/03-identity.md +39 -37
  178. package/kits/rules/04-relation.md +75 -75
  179. package/kits/rules/05-venue.md +60 -60
  180. package/kits/rules/06-channel.md +63 -63
  181. package/kits/schemas/_meta.json +53 -53
  182. package/kits/schemas/agent-config.schema.1.json +177 -177
  183. package/kits/schemas/agent-config.schema.10.json +395 -395
  184. package/kits/schemas/agent-config.schema.11.json +421 -421
  185. package/kits/schemas/agent-config.schema.12.json +427 -427
  186. package/kits/schemas/agent-config.schema.2.json +239 -239
  187. package/kits/schemas/agent-config.schema.3.json +119 -119
  188. package/kits/schemas/agent-config.schema.4.json +208 -208
  189. package/kits/schemas/agent-config.schema.5.json +326 -326
  190. package/kits/schemas/agent-config.schema.6.json +322 -322
  191. package/kits/schemas/agent-config.schema.7.json +303 -303
  192. package/kits/schemas/agent-config.schema.8.json +304 -304
  193. package/kits/schemas/agent-config.schema.9.json +364 -364
  194. package/kits/schemas/contact-book.schema.1.json +36 -36
  195. package/kits/schemas/contact-book.schema.2.json +43 -43
  196. package/kits/schemas/contact-book.schema.3.json +67 -67
  197. package/kits/schemas/daemon.schema.1.json +91 -91
  198. package/kits/schemas/daemon.schema.2.json +101 -101
  199. package/kits/schemas/daemon.schema.3.json +123 -123
  200. package/kits/schemas/daemon.schema.4.json +136 -136
  201. package/kits/schemas/daemon.schema.5.json +135 -135
  202. package/kits/schemas/daemon.schema.6.json +131 -131
  203. package/kits/schemas/defaults.schema.1.json +81 -81
  204. package/kits/schemas/defaults.schema.2.json +85 -85
  205. package/kits/schemas/defaults.schema.3.json +73 -73
  206. package/kits/schemas/defaults.schema.4.json +107 -107
  207. package/kits/schemas/defaults.schema.5.json +119 -119
  208. package/kits/schemas/menu-exec-schema-commands.md +208 -208
  209. package/kits/schemas/migrations/README.md +30 -30
  210. package/kits/schemas/relation-config.schema.1.json +158 -158
  211. package/kits/schemas/relation-config.schema.2.json +73 -73
  212. package/kits/schemas/relation-config.schema.3.json +50 -50
  213. package/kits/schemas/relation-config.schema.4.json +47 -47
  214. package/kits/schemas/relation-config.schema.5.json +47 -47
  215. package/kits/schemas/relation-config.schema.6.json +46 -46
  216. package/kits/schemas/relation-config.schema.7.json +59 -59
  217. package/kits/schemas/relation-config.schema.8.json +103 -103
  218. package/kits/schemas/role-config.schema.1.json +201 -201
  219. package/kits/schemas/role-registry.schema.1.json +35 -35
  220. package/kits/schemas/single-session.schema.1.json +31 -31
  221. package/kits/schemas/single-session.schema.2.json +57 -57
  222. package/kits/schemas/single-session.schema.3.json +32 -32
  223. package/kits/templates/bootstrap-welcome.md +17 -17
  224. package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
  225. package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
  226. package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
  227. package/kits/templates/message-fragments/inject-default.md +2 -2
  228. package/kits/templates/message-fragments/item.md +2 -2
  229. package/kits/templates/roles/admin.json +96 -82
  230. package/kits/templates/roles/member.json +97 -96
  231. package/kits/templates/roles/owner.json +9 -9
  232. package/kits/templates/roles/visitor.json +86 -85
  233. package/kits/templates/system-fragments/baseagent.md +14 -14
  234. package/kits/templates/system-fragments/bootstrap.md +38 -29
  235. package/kits/templates/system-fragments/channel.md +64 -64
  236. package/kits/templates/system-fragments/commands.md +28 -28
  237. package/kits/templates/system-fragments/identity.md +13 -13
  238. package/kits/templates/system-fragments/relation.md +19 -19
  239. package/kits/templates/system-fragments/session.md +59 -59
  240. package/kits/templates/system-fragments/venue.md +31 -31
  241. package/package.json +98 -94
  242. package/AGENTS.md +0 -62
  243. package/dist/utils/codex-cli.js +0 -43
  244. package/skills/eclink/SKILL.md +0 -84
  245. package/skills/eclink/agents/openai.yaml +0 -4
package/dist/cli/bench.js CHANGED
@@ -381,26 +381,26 @@ async function cliAuth(aid, slotId) {
381
381
  // ==================== Main Command ====================
382
382
  export async function cmdBench(args) {
383
383
  if (isHelpFlag(args[0]) || wantsHelp(args)) {
384
- console.log(`用法: ec bench [options]
385
-
386
- AUN 消息系统性能基准测试。使用多个本地 AID 并发互发消息,
387
- 测量吞吐量、延迟、丢失率,以及认证性能和账号切换性能。
388
-
389
- Options:
390
- --aids N 使用的 AID 数量 (默认 3, 范围 2-10)
391
- --rounds N 每个 AID 发送的消息轮数 (默认 20)
392
- --concurrency N 最大并发发送数 (默认 5)
393
- --wait N 发送后等待传播的秒数 (默认 3)
394
- --encrypt 发送加密消息(E2EE)
395
- --file 文件传输验证模式(压缩 evolcore 目录,拆片发送,接收后 MD5 校验+解压)
396
- --cli 使用 CLI 子进程调用(测试完整命令行链路,含进程启动开销)
397
- --aun-path <path> 自定义 AUN 目录
398
- --format json 以 JSON 输出结果
399
-
400
- 示例:
401
- ec bench --aids 5 --rounds 10
402
- ec bench --file --rounds 50
403
- ec bench --encrypt --aids 5 --rounds 20
384
+ console.log(`用法: ec bench [options]
385
+
386
+ AUN 消息系统性能基准测试。使用多个本地 AID 并发互发消息,
387
+ 测量吞吐量、延迟、丢失率,以及认证性能和账号切换性能。
388
+
389
+ Options:
390
+ --aids N 使用的 AID 数量 (默认 3, 范围 2-10)
391
+ --rounds N 每个 AID 发送的消息轮数 (默认 20)
392
+ --concurrency N 最大并发发送数 (默认 5)
393
+ --wait N 发送后等待传播的秒数 (默认 3)
394
+ --encrypt 发送加密消息(E2EE)
395
+ --file 文件传输验证模式(压缩 evolcore 目录,拆片发送,接收后 MD5 校验+解压)
396
+ --cli 使用 CLI 子进程调用(测试完整命令行链路,含进程启动开销)
397
+ --aun-path <path> 自定义 AUN 目录
398
+ --format json 以 JSON 输出结果
399
+
400
+ 示例:
401
+ ec bench --aids 5 --rounds 10
402
+ ec bench --file --rounds 50
403
+ ec bench --encrypt --aids 5 --rounds 20
404
404
  ec bench --cli --aids 3 --rounds 5`);
405
405
  return;
406
406
  }
@@ -196,26 +196,26 @@ async function runManagedBatchGet(fields, rest, formatJson) {
196
196
  }
197
197
  renderConfigExecution(response.result, formatJson);
198
198
  }
199
- const HELP = `Usage: ec config <command> [options]
200
-
201
- Fields:
202
- get <field> [<field> ...] one or more fields (batch)
203
- set <field> <value>
204
- unset <field>
205
-
206
- Scoped commands:
207
- show | effective | fields [field] | validate | init
208
-
209
- Global commands:
210
- list | snapshot | prune | history | diff | restore | current | boots
211
- schema overview of all schemas
212
- schema <name> [<version>] view a schema definition
213
- schema <name> --list list a schema's versions
214
-
215
- Selectors:
216
- --self <aid> [--peer <peerKey>] | --default | --process
217
-
218
- Output:
199
+ const HELP = `Usage: ec config <command> [options]
200
+
201
+ Fields:
202
+ get <field> [<field> ...] one or more fields (batch)
203
+ set <field> <value>
204
+ unset <field>
205
+
206
+ Scoped commands:
207
+ show | effective | fields [field] | validate | init
208
+
209
+ Global commands:
210
+ list | snapshot | prune | history | diff | restore | current | boots
211
+ schema overview of all schemas
212
+ schema <name> [<version>] view a schema definition
213
+ schema <name> --list list a schema's versions
214
+
215
+ Selectors:
216
+ --self <aid> [--peer <peerKey>] | --default | --process
217
+
218
+ Output:
219
219
  --format json`;
220
220
  export async function cmdConfig(args) {
221
221
  const subcommand = args[0];
@@ -58,15 +58,15 @@ function fail(message, code = 'INVALID_ARGUMENT', data) {
58
58
  throw error;
59
59
  }
60
60
  function printHelp() {
61
- console.log(`Usage:
62
- ec contact add <primaryId> --self <agent-aid>
63
- ec contact block <primaryId> --self <agent-aid>
64
- ec contact unblock <primaryId> --self <agent-aid>
65
- ec contact list --blocked --self <agent-aid>
66
-
67
- Options:
68
- --self <agent-aid> 必填,本端 agent AID
69
- --blocked list 必填,仅列出已拉黑联系人
70
- --format json 输出 JSON
61
+ console.log(`Usage:
62
+ ec contact add <primaryId> --self <agent-aid>
63
+ ec contact block <primaryId> --self <agent-aid>
64
+ ec contact unblock <primaryId> --self <agent-aid>
65
+ ec contact list --blocked --self <agent-aid>
66
+
67
+ Options:
68
+ --self <agent-aid> 必填,本端 agent AID
69
+ --blocked list 必填,仅列出已拉黑联系人
70
+ --format json 输出 JSON
71
71
  --help, -h 显示帮助`);
72
72
  }
@@ -3,26 +3,28 @@ import { ipcQuery } from '../ipc.js';
3
3
  import { isHelpFlag, wantsHelp } from './help.js';
4
4
  import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
5
5
  // ==================== Ctl ====================
6
- const CTL_HELP = `用法: ec ctl <command> [args...]
7
-
8
- 查询:
9
- status 查看会话状态
10
- pwd 显示当前项目路径
11
- help 显示帮助
12
-
13
- 会话:
14
- name <名称> 重命名当前会话
15
-
16
- 消息:
17
- send <消息内容> 主动发送文本消息(proactive 模式)
18
- file [channel] <path> 发送项目内文件
19
- queue [--after <time>] [--before <time>] 查看/管理会话消息队列
20
-
21
- 示例:
22
- ec ctl status
23
- ec ctl name "新会话名称"
24
- ec ctl send "任务已完成"
25
- ec ctl file report.md
6
+ const CTL_HELP = `用法: ec ctl <command> [args...]
7
+
8
+ 查询:
9
+ status 查看会话状态
10
+ status --format json 查看当前任务的结构化运行上下文
11
+ pwd 显示当前项目路径
12
+ help 显示帮助
13
+
14
+ 会话:
15
+ name <名称> 重命名当前会话
16
+
17
+ 消息:
18
+ send <消息内容> 主动发送文本消息(proactive 模式)
19
+ file [channel] <path> 发送项目内文件
20
+ queue [--after <time>] [--before <time>] 查看/管理会话消息队列
21
+
22
+ 示例:
23
+ ec ctl status
24
+ ec ctl status --format json
25
+ ec ctl name "新会话名称"
26
+ ec ctl send "任务已完成"
27
+ ec ctl file report.md
26
28
  ec ctl queue --full`;
27
29
  export async function cmdCtl(args) {
28
30
  if (args.length === 0) {
@@ -30,8 +30,50 @@ import { inspectDataMigrationRequirement } from '../core/data-migration.js';
30
30
  import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
31
31
  import { listCodexAppServerProcesses, unregisterCodexAppServerProcess } from '../agents/codex/app-server-registry.js';
32
32
  import { DEFAULT_ECWEB_PORT, ecwebService, setEcwebEnabled } from '../config/daemon-services.js';
33
- import { checkCodexProjectPath, inspectCodexManagedHook } from '../agents/codex/diagnostics.js';
33
+ import { checkCodexProjectPath, inspectCodexManagedHook, ensureCodexManagedHook, runCodexHookLaunchDiagnostic, } from '../agents/codex/diagnostics.js';
34
34
  const execFileAsync = promisify(execFile);
35
+ /** Run before launch, and before restart stops any existing daemon. */
36
+ export function ensureCodexHookBeforeLifecycle(onRepaired) {
37
+ if (!platform.isWindows)
38
+ return true;
39
+ try {
40
+ const usesCodex = loadDefaults()?.active_baseagent === 'codex'
41
+ || loadAllAgents().agents.some(agent => {
42
+ try {
43
+ return resolveEffective({ self: agent.aid }).active_baseagent === 'codex';
44
+ }
45
+ catch (error) {
46
+ console.warn(`⚠ Agent ${agent.aid} 配置解析失败:${error instanceof Error ? error.message : String(error)}`);
47
+ return false;
48
+ }
49
+ });
50
+ if (!usesCodex)
51
+ return true;
52
+ const result = ensureCodexManagedHook({
53
+ packageRoot: getPackageRoot(),
54
+ onInstallRequired: () => console.log('🔧 Codex 运行组件缺失,正在自动安装;Windows 提示管理员授权时请选择“是”。'),
55
+ });
56
+ if (result.status === 'installed') {
57
+ if (result.repaired) {
58
+ console.log('✅ Codex Windows managed hook 已自动安装并验证');
59
+ onRepaired?.();
60
+ }
61
+ return true;
62
+ }
63
+ console.error(`❌ Codex Windows managed hook 未就绪:${result.error || result.reason || result.status}`);
64
+ if (result.status === 'missing') {
65
+ console.error(' 本次操作已停止。下次启动或重启会再次自动尝试安装,需要允许 Windows 管理员授权。');
66
+ }
67
+ else {
68
+ console.error(' 本次操作已停止。现有 Codex 策略或文件访问异常,需要管理员核对;自动安装不会覆盖异常策略。');
69
+ }
70
+ }
71
+ catch (error) {
72
+ console.error(`❌ Codex 启动检查失败:${error instanceof Error ? error.message : String(error)}`);
73
+ }
74
+ process.exitCode = 1;
75
+ return false;
76
+ }
35
77
  async function runAutomaticInit(action) {
36
78
  try {
37
79
  return await action();
@@ -66,8 +108,8 @@ function printNoSelfAgentHints(options) {
66
108
  // taskkill, even though the daemon is healthy and able to shut down gracefully.
67
109
  const DAEMON_PROBE_TIMEOUT_MS = platform.isWindows ? 5_000 : 1_000;
68
110
  export const DAEMON_SHUTDOWN_TIMEOUT_MS = platform.isWindows ? 10_000 : 3_000;
69
- async function probeDaemon(socketPath, timeoutMs = DAEMON_PROBE_TIMEOUT_MS) {
70
- const response = await ipcQuery(socketPath, { type: 'ping' }, timeoutMs);
111
+ async function probeDaemon(socketPath, timeoutMs = DAEMON_PROBE_TIMEOUT_MS, throwOnError = false) {
112
+ const response = await ipcQuery(socketPath, { type: 'ping' }, timeoutMs, { throwOnError });
71
113
  if (response?.pong !== true || !Number.isInteger(response.pid) || response.pid <= 0)
72
114
  return null;
73
115
  return response;
@@ -205,19 +247,39 @@ function runSourceBuild() {
205
247
  });
206
248
  });
207
249
  }
250
+ /**
251
+ * Spawn the restart monitor and confirm it actually reached its own code.
252
+ *
253
+ * The daemon is already stopped at this point, so a monitor that dies on
254
+ * startup leaves nothing running and nobody watching — the exact silent
255
+ * failure this mechanism exists to prevent.
256
+ */
257
+ async function spawnRestartMonitorAndConfirm(monitorEntry, reportLine) {
258
+ const result = await platform.launchMonitorAndConfirm([...monitorEntry.args, 'restart-monitor'], { EVOLCORE_HOME: resolvePaths().root, ...(monitorEntry.env ?? {}) }, pid => scanInstances().restartMonitors.some(m => m.alive && m.record.pid === pid), pid => scanInstances().restartMonitors.some(m => m.alive && m.record.pid !== pid));
259
+ if (result.ok)
260
+ return { ok: true };
261
+ for (const line of (result.stderrTail ?? '').split(/\r?\n/).filter(Boolean).slice(-8)) {
262
+ reportLine(` | ${line}`);
263
+ }
264
+ return { ok: false, reason: result.reason ?? 'unknown' };
265
+ }
208
266
  async function requireFreshSourceBuild() {
209
267
  if (!sourceBuildNeedsRefresh())
210
268
  return true;
211
269
  return await runSourceBuild();
212
270
  }
213
- function requireCompletedDataMigration(root) {
271
+ function requireCompletedDataMigration(root, action = 'start') {
214
272
  const requirement = inspectDataMigrationRequirement(root);
215
273
  if (!requirement.required)
216
274
  return true;
217
- console.error(`❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,服务未启动。`);
275
+ console.error(action === 'restart'
276
+ ? `❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,本次不停止当前服务。`
277
+ : `❌ 检测到 ${requirement.operationCount} 项待确认的用户数据迁移,服务未启动。`);
218
278
  console.error(' 先执行: ec data migrate --dry-run');
219
279
  console.error(' 确认后: ec data migrate --apply');
220
280
  console.error(' 迁移成功并校验后,再执行 ec start 或 ec restart。');
281
+ if (action === 'restart')
282
+ console.error(' 本次 ec restart 仅完成只读检查,未停止当前服务。');
221
283
  process.exitCode = 2;
222
284
  return false;
223
285
  }
@@ -386,6 +448,14 @@ export async function cmdStart(opts = {}) {
386
448
  const p = resolvePaths();
387
449
  const existingDaemon = await probeDaemon(p.socket);
388
450
  if (existingDaemon) {
451
+ let hookRepaired = false;
452
+ if (!ensureCodexHookBeforeLifecycle(() => { hookRepaired = true; }))
453
+ return;
454
+ if (hookRepaired) {
455
+ console.log('🔄 Codex 运行组件已补齐,正在自动重启服务以加载策略...');
456
+ await cmdRestart({ diagnose: opts.diagnose });
457
+ return;
458
+ }
389
459
  console.log(` EvolCore is already running (PID: ${existingDaemon.pid}, IPC reachable)`);
390
460
  console.log(` 已在运行;已运行时长: ${resolveRunningDuration(existingDaemon.pid, existingDaemon.uptime)};部署/脚本可直接复用当前实例`);
391
461
  return;
@@ -424,6 +494,11 @@ export async function cmdStart(opts = {}) {
424
494
  console.log('\n初始化完成,开始启动 EvolCore ....');
425
495
  }
426
496
  }
497
+ // The initialization path can create the first Codex agent, so perform the
498
+ // machine-hook check after config migration/auto-init and before any daemon
499
+ // process is launched.
500
+ if (!ensureCodexHookBeforeLifecycle())
501
+ return;
427
502
  // 控制 AID 门禁:缺 aid 且交互式 → 只补全控制 AID + owners(不重走 baseagent 向导)。
428
503
  // 非 TTY(restart-monitor/systemd/管道)不补全(无法交互),只提示后继续启动,daemon 侧 warn 兜底。
429
504
  const daemonCfgStart = loadDaemonConfig();
@@ -758,6 +833,8 @@ export async function cmdStop() {
758
833
  export async function cmdRestart(opts = {}) {
759
834
  const cmdStartedAt = Date.now();
760
835
  console.log('🔄 Restarting EvolCore...');
836
+ if (!ensureCodexHookBeforeLifecycle())
837
+ return;
761
838
  const initialStatus = scanInstances();
762
839
  const initialOrphans = findOrphanProcesses();
763
840
  const initialRuntimeOrphans = initialOrphans.filter(orphan => isRuntimeOrphan(orphan));
@@ -769,12 +846,12 @@ export async function cmdRestart(opts = {}) {
769
846
  if (initialRuntimeOrphans.length === 0 && rejectPidIsolatedLifecycle('restart', initialStatus, ping))
770
847
  return;
771
848
  }
772
- if (!await requireFreshSourceBuild())
773
- return;
849
+ // 构建交给 restart-monitor:它在 daemon 停止之后才编译,dist/ 不会被活进程
850
+ // 占用,失败还能回滚到上一份产物。这里再编译一次会落在事务保护之外。
774
851
  // Keep restart behavior identical to startup: both paths use one upgrade
775
852
  // check implementation and continue when an upgrade is unavailable.
776
853
  await runUpgradeChecks();
777
- if (!requireCompletedDataMigration(resolveRoot()))
854
+ if (!requireCompletedDataMigration(resolveRoot(), 'restart'))
778
855
  return;
779
856
  // 停止所有活 main 进程(可能不止一个)
780
857
  const status = scanInstances();
@@ -854,11 +931,30 @@ export async function cmdRestart(opts = {}) {
854
931
  }
855
932
  }
856
933
  console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
857
- // 通过 restart-monitor 启动,避免在 agent 内调用时自杀
858
- const appCli = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
859
- platform.spawnDetachedNode([appCli, 'restart-monitor'], {
860
- EVOLCORE_HOME: resolvePaths().root,
861
- });
934
+ // 通过 restart-monitor 启动,避免在 agent 内调用时自杀。
935
+ // 开发仓下 monitor 从源码跑;安装包下先复制到 stage 目录,两种情况都让看门狗
936
+ // 不住在会被替换的产物里。
937
+ const monitorEntry = platform.resolveMonitorLaunch(getPackageRoot(), path.join(resolvePaths().root, 'data', 'monitor-stage'));
938
+ if (monitorEntry.note)
939
+ console.log(`ℹ ${monitorEntry.note}`);
940
+ if (!fs.existsSync(monitorEntry.entry)) {
941
+ console.error(`❌ 重启中止:找不到 restart-monitor 入口 ${monitorEntry.entry}`);
942
+ console.error(' 请先执行 npm run build 重建产物');
943
+ process.exitCode = 1;
944
+ return;
945
+ }
946
+ const monitorStarted = await spawnRestartMonitorAndConfirm(monitorEntry, log => console.error(log));
947
+ if (!monitorStarted.ok) {
948
+ if (monitorEntry.stageDir)
949
+ platform.cleanupMonitorStage(monitorEntry.stageDir);
950
+ console.error(`❌ 重启中止:restart-monitor 未能启动(${monitorStarted.reason})`);
951
+ if (fs.existsSync(path.join(getPackageRoot(), 'src', 'cli', 'index.ts'))) {
952
+ console.error(' 源码可能存在语法错误导致 tsx 无法加载。请执行 npx tsc --noEmit 检查。');
953
+ }
954
+ console.error(' 服务已停止,请修复后执行 ec start。');
955
+ process.exitCode = 1;
956
+ return;
957
+ }
862
958
  console.log('🔄 Restart monitor started, waiting for service to come back online...');
863
959
  await sleep(2000);
864
960
  // 代码统计(开发环境)
@@ -1032,7 +1128,11 @@ export async function cmdStatus() {
1032
1128
  // Start all read-only daemon queries together. On a busy Windows host each
1033
1129
  // query can otherwise wait behind the same IPC/event-loop delay and make the
1034
1130
  // total `ec status` time the sum of several individual timeouts.
1035
- const pingPromise = probeDaemon(p.socket).catch(() => null);
1131
+ let ipcFailure;
1132
+ const pingPromise = probeDaemon(p.socket, DAEMON_PROBE_TIMEOUT_MS, true).catch(error => {
1133
+ ipcFailure = error;
1134
+ return null;
1135
+ });
1036
1136
  const statusPromise = ipcQuery(p.socket, { type: 'status' }).catch(() => null);
1037
1137
  const aidsPromise = ipcQuery(p.socket, { type: 'aun-aids' }).catch(() => null);
1038
1138
  const agentsPromise = ipcQuery(p.socket, { type: 'evolagent.list' }).catch(() => null);
@@ -1049,6 +1149,11 @@ export async function cmdStatus() {
1049
1149
  }
1050
1150
  if (pid) {
1051
1151
  printStartupInfo({ pid, running: true });
1152
+ if (!ping) {
1153
+ console.log('⚠ 仅确认 daemon PID 存活,IPC 不可用,不能据此判断服务健康。');
1154
+ if (ipcFailure)
1155
+ console.log(` ${ipcFailure instanceof Error ? ipcFailure.message : String(ipcFailure)}`);
1156
+ }
1052
1157
  console.log('');
1053
1158
  console.log('📊 Process Info:');
1054
1159
  if (processVisible) {
@@ -1159,7 +1264,9 @@ export async function cmdStatus() {
1159
1264
  }
1160
1265
  }
1161
1266
  else {
1162
- console.log('⚠ EvolCore is not running');
1267
+ console.log(ipcFailure ? '⚠ 无法确认 EvolCore 运行状态:IPC 不可用,且没有可见的存活 PID。' : '⚠ EvolCore is not running');
1268
+ if (ipcFailure)
1269
+ console.log(` ${ipcFailure instanceof Error ? ipcFailure.message : String(ipcFailure)}`);
1163
1270
  }
1164
1271
  // Session & Project statistics (从文件系统读)
1165
1272
  if (fs.existsSync(p.sessionsDir)) {
@@ -2905,7 +3012,12 @@ async function cmdWatchWeb() {
2905
3012
  const cfg = loadDaemonConfig();
2906
3013
  const currentService = ecwebService(cfg.services);
2907
3014
  const port = currentService?.port ?? DEFAULT_ECWEB_PORT;
2908
- saveDaemonConfig({ ...cfg, services: setEcwebEnabled(cfg.services, true, port) });
3015
+ // Avoid rewriting daemon.json on every invocation once ECWeb is already
3016
+ // enabled on the requested port. The persisted config is the daemon's
3017
+ // lifecycle source of truth, but an unchanged desired state needs no write.
3018
+ if (currentService?.enabled !== true || currentService.port !== port) {
3019
+ saveDaemonConfig({ ...cfg, services: setEcwebEnabled(cfg.services, true, port) });
3020
+ }
2909
3021
  const ok = await startEcwebIfEnabled(p, { forceRestart: true });
2910
3022
  if (!ok)
2911
3023
  process.exit(1); // 失败原因已由 startEcwebIfEnabled 打印
@@ -2944,9 +3056,10 @@ export async function cmdMv(oldDir, newDir) {
2944
3056
  }
2945
3057
  }
2946
3058
  // ==================== Diagnose ====================
2947
- export async function cmdDiagnose() {
3059
+ export async function cmdDiagnose(args = []) {
2948
3060
  const p = resolvePaths();
2949
3061
  let hasError = false;
3062
+ const runHookLaunchProbe = args.includes('--codex-hook');
2950
3063
  // 1. 检查数据目录
2951
3064
  console.log(`[diagnose] EVOLCORE_HOME = ${p.root}`);
2952
3065
  if (!fs.existsSync(p.root)) {
@@ -3010,6 +3123,24 @@ export async function cmdDiagnose() {
3010
3123
  const hook = inspectCodexManagedHook({ packageRoot: getPackageRoot() });
3011
3124
  if (hook.status === 'installed') {
3012
3125
  console.log(`[diagnose] ✓ Codex managed hook 已安装: ${hook.hookPath}`);
3126
+ if (runHookLaunchProbe) {
3127
+ try {
3128
+ const launch = runCodexHookLaunchDiagnostic({ packageRoot: getPackageRoot() });
3129
+ if (launch.status === 'ok') {
3130
+ console.log('[diagnose] ✓ Codex managed hook 启动探针报告: ' + launch.output);
3131
+ for (const result of launch.results) {
3132
+ console.log('[diagnose] ' + result.label + ': exit=' + result.exitCode + ' pid=' + (result.pid ?? 'unknown'));
3133
+ }
3134
+ }
3135
+ else {
3136
+ console.log('[diagnose] - Codex managed hook 启动探针: 跳过(' + (launch.reason || 'not applicable') + ')');
3137
+ }
3138
+ }
3139
+ catch (error) {
3140
+ console.error('[diagnose] ❌ Codex managed hook 启动探针失败: ' + (error instanceof Error ? error.message : String(error)));
3141
+ hasError = true;
3142
+ }
3143
+ }
3013
3144
  }
3014
3145
  else if (hook.status === 'skipped') {
3015
3146
  console.log(`[diagnose] - Codex managed hook: 跳过(${hook.reason})`);
@@ -3129,21 +3260,21 @@ export async function cmdWatchCommand(args) {
3129
3260
  }
3130
3261
  else if (args[0] === 'msg') {
3131
3262
  if (isHelpFlag(args[1])) {
3132
- console.log(`用法: ec watch msg
3133
-
3134
- 三面板交互式消息监控 TUI。
3135
-
3136
- 面板:
3137
- 左 (Scope) 本地 AID 列表,显示收发统计和对端数量
3138
- 中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
3139
- 右 (Messages) 消息流,带滚动条
3140
-
3141
- 操作:
3142
- ↑↓ 当前面板内导航
3143
- ←→ / Tab 切换面板
3144
- Enter 选中 AID / 选中对端
3145
- Backspace 返回上一级
3146
- Page Up/Down 消息滚动
3263
+ console.log(`用法: ec watch msg
3264
+
3265
+ 三面板交互式消息监控 TUI。
3266
+
3267
+ 面板:
3268
+ 左 (Scope) 本地 AID 列表,显示收发统计和对端数量
3269
+ 中 (Stats) 选中 AID 的对端列表(默认 All),显示 per-peer 收发数
3270
+ 右 (Messages) 消息流,带滚动条
3271
+
3272
+ 操作:
3273
+ ↑↓ 当前面板内导航
3274
+ ←→ / Tab 切换面板
3275
+ Enter 选中 AID / 选中对端
3276
+ Backspace 返回上一级
3277
+ Page Up/Down 消息滚动
3147
3278
  ESC 退出`);
3148
3279
  return;
3149
3280
  }
@@ -19,73 +19,73 @@ class FsCliError extends Error {
19
19
  this.details = details;
20
20
  }
21
21
  }
22
- const HELP = `用法: ec fs <command> [args...] [options]
23
-
24
- Commands:
25
- ls <AID>:<path> 列目录
26
- stat [-L] <AID>:<path> 查看节点元数据(默认不跟随软链;-L 跟随)
27
- lstat <AID>:<path> 查看节点本身(不跟随末级软链)
28
- cat <AID>:<path> 输出文本文件内容;二进制/大文件返回头部摘要
29
- cp <local> <AID>:<path> 上传本地文件
30
- cp <AID>:<path> <local> 下载远程文件
31
- cp <AID>:<path> <AID>:<path> 远程复制(同后端)
32
- mv <AID>:<path> <AID>:<path> 移动/改名(同后端)
33
- rm [-r] <AID>:<path> 删除文件或目录
34
- mkdir [-p] <AID>:<path> 创建目录
35
- ln -s <target> <AID>:<path> 创建软链(personal storage)
36
- chmod [mode] <AID>:<path> 切换公开/私有(personal storage)
37
- setfacl <AID>:<path> -m|-x ... 设置/移除 ACL(群路径使用 role:member|role:admin)
38
- getfacl <AID>:<path> 查看 ACL
39
- token issue|revoke|ls <path> 管理访问 token(personal storage)
40
- find <AID>:<path> [filters] 查找节点
41
- df <AID>: 查看容量/配额
42
- mount <target> --volume <id> 挂载实体卷
43
- mount <target> --source <src> 挂载远程子树
44
- approve <AID>:<path> 批准待审挂载(personal storage)
45
- reject <AID>:<path> 拒绝待审挂载(personal storage)
46
- umount <AID>:<path> 卸载挂载点
47
-
48
- Options:
49
- --as <aid> 操作者 AID;也可由 EVOLCORE_SELF_AID 注入
50
- --format json 输出 JSON
51
- --overwrite, --force 覆盖目标(用于 cp/mv/ln)或强制删除(用于 rm)
52
- -r, --recursive 递归(用于 rm/cp)
53
- -p, --parents 自动创建父目录(用于 mkdir/group 上传)
54
- -L, --follow stat 跟随末级软链
55
- --token <token> 读取时携带访问 token(personal storage)
56
- --content-type <mime> 上传时指定内容类型
57
- --public 上传后公开可读(personal storage)
58
- --visibility <public|private> chmod 可见性
59
- --allow-roles <roles> chmod 角色约束,逗号分隔
60
- -m aid:<aid>:<perms> setfacl 新增/更新 ACL
61
- -x aid:<aid> setfacl 移除 ACL
62
- --source <AID>:<path> mount 虚拟卷来源
63
- --volume <id> mount 实体卷 ID
64
- --require-approval mount 需要来源 owner 审批
65
- --expires <time> mount/token/ACL 过期时间,Unix 秒或 ISO 日期
66
- --max-uses <n> ACL 最大使用次数
67
- --max-reads <n> token 最大读取次数
68
- --readonly, --readwrite mount 只读/读写
69
- --name <glob> find 名称过滤
70
- --type <f|d|l> find 类型过滤
71
- --size <expr> find 大小过滤,如 +1M
72
- --mtime <expr> find 修改时间过滤
73
- --head-bytes <n> cat 二进制头部字节数,默认 256
74
- --max-bytes <n> cat 最大直接输出字节数,默认 1048576
75
- --aun-path <path> 指定 AUN keystore 根
76
- --app <name> 指定 AUN app slot
77
-
78
- 示例:
79
- ec fs ls alice.agentid.pub:/private/
80
- ec fs cp ./report.md alice.agentid.pub:/private/report.md --as alice.agentid.pub
81
- ec fs cp alice.agentid.pub:/private/report.md ./report.md --as alice.agentid.pub
82
- ec fs cp alice.agentid.pub:/private/a.md bob.agentid.pub:/inbox/a.md --as alice.agentid.pub
83
- ec fs cat alice.agentid.pub:/private/report.md --as alice.agentid.pub
84
- ec fs ln -s alice.agentid.pub:/private/report.md alice.agentid.pub:/public/report.md --as alice.agentid.pub
85
- ec fs chmod +r alice.agentid.pub:/public/report.md --as alice.agentid.pub
86
- ec fs setfacl alice.agentid.pub:/private/report.md -m aid:bob.agentid.pub:r --as alice.agentid.pub
87
- ec fs token issue alice.agentid.pub:/public/report.md --expires 2026-12-31 --as alice.agentid.pub
88
- ec fs find alice.agentid.pub:/private/ --name "*.md" --as alice.agentid.pub
22
+ const HELP = `用法: ec fs <command> [args...] [options]
23
+
24
+ Commands:
25
+ ls <AID>:<path> 列目录
26
+ stat [-L] <AID>:<path> 查看节点元数据(默认不跟随软链;-L 跟随)
27
+ lstat <AID>:<path> 查看节点本身(不跟随末级软链)
28
+ cat <AID>:<path> 输出文本文件内容;二进制/大文件返回头部摘要
29
+ cp <local> <AID>:<path> 上传本地文件
30
+ cp <AID>:<path> <local> 下载远程文件
31
+ cp <AID>:<path> <AID>:<path> 远程复制(同后端)
32
+ mv <AID>:<path> <AID>:<path> 移动/改名(同后端)
33
+ rm [-r] <AID>:<path> 删除文件或目录
34
+ mkdir [-p] <AID>:<path> 创建目录
35
+ ln -s <target> <AID>:<path> 创建软链(personal storage)
36
+ chmod [mode] <AID>:<path> 切换公开/私有(personal storage)
37
+ setfacl <AID>:<path> -m|-x ... 设置/移除 ACL(群路径使用 role:member|role:admin)
38
+ getfacl <AID>:<path> 查看 ACL
39
+ token issue|revoke|ls <path> 管理访问 token(personal storage)
40
+ find <AID>:<path> [filters] 查找节点
41
+ df <AID>: 查看容量/配额
42
+ mount <target> --volume <id> 挂载实体卷
43
+ mount <target> --source <src> 挂载远程子树
44
+ approve <AID>:<path> 批准待审挂载(personal storage)
45
+ reject <AID>:<path> 拒绝待审挂载(personal storage)
46
+ umount <AID>:<path> 卸载挂载点
47
+
48
+ Options:
49
+ --as <aid> 操作者 AID;也可由 EVOLCORE_SELF_AID 注入
50
+ --format json 输出 JSON
51
+ --overwrite, --force 覆盖目标(用于 cp/mv/ln)或强制删除(用于 rm)
52
+ -r, --recursive 递归(用于 rm/cp)
53
+ -p, --parents 自动创建父目录(用于 mkdir/group 上传)
54
+ -L, --follow stat 跟随末级软链
55
+ --token <token> 读取时携带访问 token(personal storage)
56
+ --content-type <mime> 上传时指定内容类型
57
+ --public 上传后公开可读(personal storage)
58
+ --visibility <public|private> chmod 可见性
59
+ --allow-roles <roles> chmod 角色约束,逗号分隔
60
+ -m aid:<aid>:<perms> setfacl 新增/更新 ACL
61
+ -x aid:<aid> setfacl 移除 ACL
62
+ --source <AID>:<path> mount 虚拟卷来源
63
+ --volume <id> mount 实体卷 ID
64
+ --require-approval mount 需要来源 owner 审批
65
+ --expires <time> mount/token/ACL 过期时间,Unix 秒或 ISO 日期
66
+ --max-uses <n> ACL 最大使用次数
67
+ --max-reads <n> token 最大读取次数
68
+ --readonly, --readwrite mount 只读/读写
69
+ --name <glob> find 名称过滤
70
+ --type <f|d|l> find 类型过滤
71
+ --size <expr> find 大小过滤,如 +1M
72
+ --mtime <expr> find 修改时间过滤
73
+ --head-bytes <n> cat 二进制头部字节数,默认 256
74
+ --max-bytes <n> cat 最大直接输出字节数,默认 1048576
75
+ --aun-path <path> 指定 AUN keystore 根
76
+ --app <name> 指定 AUN app slot
77
+
78
+ 示例:
79
+ ec fs ls alice.agentid.pub:/private/
80
+ ec fs cp ./report.md alice.agentid.pub:/private/report.md --as alice.agentid.pub
81
+ ec fs cp alice.agentid.pub:/private/report.md ./report.md --as alice.agentid.pub
82
+ ec fs cp alice.agentid.pub:/private/a.md bob.agentid.pub:/inbox/a.md --as alice.agentid.pub
83
+ ec fs cat alice.agentid.pub:/private/report.md --as alice.agentid.pub
84
+ ec fs ln -s alice.agentid.pub:/private/report.md alice.agentid.pub:/public/report.md --as alice.agentid.pub
85
+ ec fs chmod +r alice.agentid.pub:/public/report.md --as alice.agentid.pub
86
+ ec fs setfacl alice.agentid.pub:/private/report.md -m aid:bob.agentid.pub:r --as alice.agentid.pub
87
+ ec fs token issue alice.agentid.pub:/public/report.md --expires 2026-12-31 --as alice.agentid.pub
88
+ ec fs find alice.agentid.pub:/private/ --name "*.md" --as alice.agentid.pub
89
89
  ec fs df alice.agentid.pub: --as alice.agentid.pub`;
90
90
  const VALUE_FLAGS = new Set([
91
91
  '--as',
@@ -153,13 +153,13 @@ function formatTimestamp(value) {
153
153
  export async function cmdHandoff(args) {
154
154
  const sub = args[0];
155
155
  if (!sub || isHelpFlag(sub) || wantsHelp(args)) {
156
- console.log(`用法: ec handoff <command> [args]
157
-
158
- Commands:
159
- return [handoff-id] [content] 确认完成;required 策略需提供回流内容
160
- return [handoff-id] --text-from-file <path>
161
- status <handoff-id> 查询 handoff 状态
162
- list [--state <state>] [--session <id>] [--limit <n>] [--agent <aid>]
156
+ console.log(`用法: ec handoff <command> [args]
157
+
158
+ Commands:
159
+ return [handoff-id] [content] 确认完成;required 策略需提供回流内容
160
+ return [handoff-id] --text-from-file <path>
161
+ status <handoff-id> 查询 handoff 状态
162
+ list [--state <state>] [--session <id>] [--limit <n>] [--agent <aid>]
163
163
  trace <handoff-id> [--limit <n>] [--agent <aid>]`);
164
164
  return;
165
165
  }