evolcore 0.0.11 → 0.0.12

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 (102) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bin/codex-managed-hook.mjs +80 -0
  3. package/dist/agents/claude-runner.js +35 -2
  4. package/dist/agents/codex-app-server-client.js +120 -14
  5. package/dist/agents/codex-runner.js +273 -35
  6. package/dist/agents/ecagent-runner.js +36 -4
  7. package/dist/agents/gemini-runner.js +1 -0
  8. package/dist/aun/aid/client.js +11 -21
  9. package/dist/aun/aid/managed-operation.js +107 -0
  10. package/dist/aun/msg/group.js +81 -12
  11. package/dist/aun/msg/managed-operation.js +804 -0
  12. package/dist/aun/msg/mention-schema.js +20 -0
  13. package/dist/aun/msg/p2p.js +7 -0
  14. package/dist/channels/aun.js +288 -108
  15. package/dist/channels/daemon.js +13 -0
  16. package/dist/cli/agent-command.js +56 -8
  17. package/dist/cli/agent.js +170 -6
  18. package/dist/cli/aun-commands.js +270 -69
  19. package/dist/cli/bench.js +12 -3
  20. package/dist/cli/daemon-commands.js +31 -31
  21. package/dist/cli/fs-command.js +60 -0
  22. package/dist/cli/handoff-command.js +3 -0
  23. package/dist/cli/index.js +30 -2
  24. package/dist/cli/managed-command-guard.js +41 -0
  25. package/dist/cli/model.js +11 -4
  26. package/dist/cli/queue-command.js +11 -1
  27. package/dist/cli/response.js +71 -0
  28. package/dist/cli/restart-monitor.js +4 -18
  29. package/dist/cli/trigger-command.js +4 -0
  30. package/dist/config/builtin-roles.js +4 -0
  31. package/dist/config/contact-book-store.js +11 -3
  32. package/dist/config/contact-request-service.js +161 -15
  33. package/dist/config/mention-mode.js +8 -24
  34. package/dist/core/auth/agent-delegation.js +0 -1
  35. package/dist/core/auth/operation-authorizer.js +30 -7
  36. package/dist/core/auth/operation-catalog.js +187 -25
  37. package/dist/core/bootstrap-messages.js +18 -0
  38. package/dist/core/bootstrap-service.js +63 -4
  39. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  40. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  41. package/dist/core/capability/skill-discovery.js +55 -0
  42. package/dist/core/channel-loader.js +1 -1
  43. package/dist/core/command/cli-intent-parser.js +9 -0
  44. package/dist/core/command/command-handler.js +467 -6
  45. package/dist/core/command/connect-menu.js +15 -0
  46. package/dist/core/command/group-menu.js +4 -4
  47. package/dist/core/command/menu-catalog.js +366 -0
  48. package/dist/core/command/menu-handler.js +147 -35
  49. package/dist/core/command/menu-protocol.js +71 -0
  50. package/dist/core/command/slash-gate.js +5 -2
  51. package/dist/core/command/slash-handler.js +41 -21
  52. package/dist/core/daemon-file-cache.js +2 -1
  53. package/dist/core/data-migration.js +9 -2
  54. package/dist/core/evolagent.js +4 -2
  55. package/dist/core/handoff/dispatcher.js +5 -2
  56. package/dist/core/handoff/runtime.js +145 -21
  57. package/dist/core/handoff/store.js +24 -0
  58. package/dist/core/handoff/types.js +1 -0
  59. package/dist/core/message/logical-queue-bridge.js +1 -0
  60. package/dist/core/message/mention-schema.js +126 -0
  61. package/dist/core/message/message-bridge.js +236 -78
  62. package/dist/core/message/message-log.js +1 -0
  63. package/dist/core/message/message-queue.js +1 -0
  64. package/dist/core/message/response-engine.js +54 -36
  65. package/dist/core/permission/ec-command-parser.js +156 -10
  66. package/dist/core/permission/sandbox-runtime.js +22 -1
  67. package/dist/core/permission/tool-policy.js +73 -30
  68. package/dist/core/protected-paths.js +7 -2
  69. package/dist/core/session/session-manager.js +21 -2
  70. package/dist/eck/manifest-engine.js +39 -13
  71. package/dist/index.js +384 -98
  72. package/dist/ipc.js +218 -9
  73. package/dist/response-system/coordinator.js +6 -4
  74. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  75. package/dist/response-system/modes/single-session/index.js +14 -1
  76. package/dist/response-system/selector.js +6 -5
  77. package/dist/trigger/anomaly-store.js +4 -0
  78. package/dist/trigger/script-executor.js +1 -0
  79. package/dist/utils/codex-app-server-registry.js +90 -0
  80. package/dist/utils/codex-cli.js +5 -1
  81. package/dist/utils/cross-platform.js +15 -0
  82. package/dist/utils/npm-ops.js +5 -12
  83. package/dist/utils/tool-summary.js +11 -0
  84. package/kits/docs/channels/aun.md +1 -1
  85. package/kits/docs/context-assembly.md +2 -2
  86. package/kits/docs/evolcore/agent.md +11 -6
  87. package/kits/docs/evolcore/aid.md +14 -0
  88. package/kits/docs/prompt-loading-architecture.md +1 -2
  89. package/kits/docs/venues/group.md +1 -1
  90. package/kits/eck_manifest.json +0 -12
  91. package/kits/rules/04-relation.md +1 -1
  92. package/kits/rules/05-venue.md +2 -2
  93. package/kits/schemas/single-session.schema.1.json +3 -3
  94. package/kits/schemas/single-session.schema.2.json +3 -3
  95. package/kits/templates/roles/admin.json +22 -0
  96. package/kits/templates/roles/member.json +27 -0
  97. package/kits/templates/roles/visitor.json +33 -3
  98. package/kits/templates/system-fragments/bootstrap.md +1 -1
  99. package/kits/templates/system-fragments/channel.md +1 -1
  100. package/kits/templates/system-fragments/session.md +1 -1
  101. package/package.json +2 -2
  102. package/dist/core/command/evol-menu-version-gate.js +0 -39
@@ -3,6 +3,8 @@ import path from 'path';
3
3
  import { agentMdPath, resolvePaths, resolveRoot } from '../paths.js';
4
4
  import { isExplicitGroupId } from '../aun/group-identity.js';
5
5
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
6
+ import { ipcQuery } from '../ipc.js';
7
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
6
8
  // ==================== AID ====================
7
9
  function resolveAunPath(args) {
8
10
  const idx = args.indexOf('--aun-path');
@@ -10,6 +12,238 @@ function resolveAunPath(args) {
10
12
  return args[idx + 1];
11
13
  return process.env.AUN_HOME || undefined;
12
14
  }
15
+ function renderAidShow(info, formatJson) {
16
+ if (formatJson) {
17
+ console.log(JSON.stringify(info, null, 2));
18
+ return;
19
+ }
20
+ console.log(`AID: ${info.aid}`);
21
+ console.log(` 私钥: ${info.hasPrivateKey ? '有' : '无'}`);
22
+ console.log(` agent.md: ${info.hasAgentMd ? '有' : '无'}`);
23
+ if (info.hasAgentMd) {
24
+ const sigLabel = info.agentMdSignature === 'verified' ? '✓ 已验签'
25
+ : info.agentMdSignature === 'unsigned' ? '⚠ 未签名'
26
+ : info.agentMdSignature === 'invalid' ? `✗ 签名无效${info.agentMdSignatureReason ? ': ' + info.agentMdSignatureReason : ''}`
27
+ : '? 未知';
28
+ console.log(` 签名状态: ${sigLabel}`);
29
+ }
30
+ console.log(` 证书到期: ${info.certExpiresAt ?? '无证书'}${info.certExpired ? ' (已过期!)' : ''}`);
31
+ if (info.certSubject)
32
+ console.log(` 证书主体: ${info.certSubject}`);
33
+ if (info.keyMatchesCert === false)
34
+ console.log(' 密钥/证书: ✗ 公钥不匹配(cert.pem 与 key.json 公钥不一致)');
35
+ else if (info.keyMatchesCert === true)
36
+ console.log(' 密钥/证书: ✓ 公钥一致');
37
+ if (info.signVerified === true)
38
+ console.log(' 可签名/验签: ✓ 实测通过');
39
+ else if (info.signVerified === false)
40
+ console.log(` 可签名/验签: ✗ 失败${info.signError ? `(${info.signError})` : ''}`);
41
+ else
42
+ console.log(' 可签名/验签: ? 未知');
43
+ }
44
+ function renderAidLookup(result, formatJson) {
45
+ if (formatJson) {
46
+ console.log(JSON.stringify(result, null, 2));
47
+ return;
48
+ }
49
+ if (result.exists) {
50
+ console.log(`✓ ${result.aid} 已注册`);
51
+ if (result.gateway)
52
+ console.log(` 网关: ${result.gateway}`);
53
+ if (result.content) {
54
+ const hasSig = result.content.includes('AUN-SIGNATURE');
55
+ console.log(` 签名: ${hasSig ? '有(未验证,如需验证请用 ec aid agentmd get ' + result.aid + ')' : '无'}`);
56
+ console.log('');
57
+ console.log(result.content);
58
+ }
59
+ }
60
+ else {
61
+ console.log(`✗ ${result.aid} 未注册`);
62
+ if (result.gateway)
63
+ console.log(` 网关: ${result.gateway}`);
64
+ if (result.error)
65
+ console.log(` 原因: ${result.error}`);
66
+ }
67
+ }
68
+ function renderAgentmdGet(aid, result, formatJson) {
69
+ if (!result.content || !result.content.trim()) {
70
+ console.log(`ℹ️ ${aid} 尚未设置 agent.md`);
71
+ return;
72
+ }
73
+ if (formatJson) {
74
+ console.log(JSON.stringify(result, null, 2));
75
+ return;
76
+ }
77
+ console.log(result.content);
78
+ const verification = result.verification;
79
+ if (verification.status === 'verified')
80
+ console.error('✓ 签名验证通过');
81
+ else if (verification.status === 'invalid')
82
+ console.error(`⚠ 签名验证失败: ${verification.reason ?? '未知原因'}`);
83
+ else
84
+ console.error('ℹ️ 未签名');
85
+ }
86
+ function failManagedAid(formatJson, code, error) {
87
+ if (formatJson)
88
+ console.log(JSON.stringify({ ok: false, code, error }, null, 2));
89
+ else
90
+ console.error(`❌ ${error}`);
91
+ process.exit(1);
92
+ }
93
+ async function runManagedAid(args, formatJson) {
94
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
95
+ if (!sessionId)
96
+ failManagedAid(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
97
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
98
+ if (!delegationToken) {
99
+ failManagedAid(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
100
+ }
101
+ const response = await ipcQuery(resolvePaths().socket, {
102
+ type: 'aid.op',
103
+ argv: ['aid', ...args],
104
+ sessionId,
105
+ delegationToken,
106
+ }, 30_000);
107
+ if (!response)
108
+ failManagedAid(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
109
+ if (!response.ok || !response.result) {
110
+ const error = response.error || 'AID operation failed';
111
+ const aid = args[0] === 'agentmd' ? args[2] : args[1];
112
+ if (args[0] === 'agentmd' && args[1] === 'get' && (error.includes('not found') || error.includes('404'))) {
113
+ console.log(`ℹ️ ${aid} 尚未设置 agent.md`);
114
+ return;
115
+ }
116
+ if (response.code === 'LOCAL_AGENTMD_MISSING') {
117
+ failManagedAid(formatJson, response.code, `本地无 agent.md: ${aid}`);
118
+ }
119
+ failManagedAid(formatJson, response.code || 'AID_OPERATION_FAILED', error);
120
+ }
121
+ switch (response.result.kind) {
122
+ case 'show':
123
+ renderAidShow(response.result.value, formatJson);
124
+ return;
125
+ case 'lookup':
126
+ renderAidLookup(response.result.value, formatJson);
127
+ return;
128
+ case 'agentmd.get':
129
+ renderAgentmdGet(response.result.aid, response.result.value, formatJson);
130
+ return;
131
+ case 'agentmd.put':
132
+ if (formatJson)
133
+ console.log(JSON.stringify({ ok: true, aid: response.result.aid, path: response.result.path }, null, 2));
134
+ else
135
+ console.log('✓ agent.md 已发布');
136
+ }
137
+ }
138
+ function failManagedGroup(formatJson, code, error) {
139
+ if (formatJson)
140
+ console.log(JSON.stringify({ ok: false, code, error }));
141
+ else
142
+ console.error(`❌ ${error}`);
143
+ process.exit(1);
144
+ }
145
+ async function runManagedGroup(args, formatJson) {
146
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
147
+ if (!sessionId)
148
+ failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
149
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
150
+ if (!delegationToken) {
151
+ failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
152
+ }
153
+ if (args.includes('--aun-path') || args.includes('--app')) {
154
+ failManagedGroup(formatJson, 'NOT_ALLOWED', '--aun-path and --app are not allowed in a managed task');
155
+ }
156
+ const response = await ipcQuery(resolvePaths().socket, {
157
+ type: 'group.op',
158
+ argv: ['group', ...args],
159
+ sessionId,
160
+ delegationToken,
161
+ }, 60_000);
162
+ if (!response)
163
+ failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
164
+ if (!response.ok || !response.result) {
165
+ failManagedGroup(formatJson, response.code || 'GROUP_OPERATION_FAILED', response.error || 'Group operation failed');
166
+ }
167
+ return response.result;
168
+ }
169
+ async function runManagedMsg(args, formatJson) {
170
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
171
+ if (!sessionId)
172
+ failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
173
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
174
+ if (!delegationToken) {
175
+ failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
176
+ }
177
+ const response = await ipcQuery(resolvePaths().socket, {
178
+ type: 'msg.op',
179
+ argv: ['msg', ...args],
180
+ sessionId,
181
+ delegationToken,
182
+ }, 30_000);
183
+ if (!response)
184
+ failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
185
+ if (!response.ok || !response.result) {
186
+ failManagedGroup(formatJson, response.code || 'MSG_OPERATION_FAILED', response.error || 'Msg operation failed');
187
+ }
188
+ return response.result;
189
+ }
190
+ function renderManagedMsgResult(sub, result, formatJson) {
191
+ if (formatJson) {
192
+ console.log(JSON.stringify(result));
193
+ return;
194
+ }
195
+ if (sub === 'online') {
196
+ for (const [aid, online] of Object.entries(result.online ?? {})) {
197
+ console.log(` ${online ? '🟢' : '⚫'} ${aid}`);
198
+ }
199
+ return;
200
+ }
201
+ if (result.count === 0) {
202
+ console.log('暂无消息历史');
203
+ return;
204
+ }
205
+ console.log(`✓ ${result.count} 条消息${result.session_id ? `,session=${result.session_id}` : ''}`);
206
+ for (const message of result.messages ?? []) {
207
+ const arrow = message.dir === 'in' ? '←' : '→';
208
+ const peer = message.dir === 'in' ? message.from : message.to;
209
+ const content = String(message.content ?? '').replace(/\r?\n/g, '\n ');
210
+ console.log(` [${message.time}] ${arrow} ${peer} [${message.msgType}] ${content}`);
211
+ }
212
+ }
213
+ function renderManagedGroupResult(args, result, formatJson) {
214
+ if (formatJson) {
215
+ console.log(JSON.stringify(result));
216
+ return;
217
+ }
218
+ const sub = args[0];
219
+ if (sub === 'list') {
220
+ if (!result.items?.length)
221
+ console.log('(没有加入任何群)');
222
+ else {
223
+ console.log(`共 ${result.total ?? result.items.length} 个群:`);
224
+ for (const group of result.items)
225
+ console.log(` ${group.group_id} ${group.name} (${group.member_count ?? '?'} 人)`);
226
+ }
227
+ return;
228
+ }
229
+ if (sub === 'create') {
230
+ console.log(`✓ 已创建群 ${result.group?.group_id ?? '-'}`);
231
+ return;
232
+ }
233
+ if (sub === 'rules' && args[3] === 'get' && result.status === 'ok') {
234
+ process.stdout.write(String(result.content ?? ''));
235
+ return;
236
+ }
237
+ if (sub === 'rules' && (args[3] === 'set' || args[3] === 'publish') && result.status !== 'ok') {
238
+ console.error(`❌ ${result.error ?? `群规则操作状态: ${result.status ?? 'unknown'}`}`);
239
+ process.exit(1);
240
+ }
241
+ if (sub === 'invite') {
242
+ console.log(`✓ 成功 ${result.added?.length ?? 0},失败 ${result.failed?.length ?? 0}`);
243
+ return;
244
+ }
245
+ console.log(`✓ group ${sub} 完成`);
246
+ }
13
247
  export async function cmdAid(args) {
14
248
  const sub = args[0];
15
249
  const formatJson = getArgValue(args, '--format') === 'json';
@@ -48,6 +282,10 @@ Options:
48
282
  ec aid agentmd get someone.agentid.pub`);
49
283
  return;
50
284
  }
285
+ if (process.env.EVOLCORE_SESSION_ID && !wantsHelp(args)) {
286
+ await runManagedAid(args, formatJson);
287
+ return;
288
+ }
51
289
  const { aidList, aidListVerified, aidCreate, aidShow, aidDelete, aidLookup, agentmdPut, agentmdGet, buildInitialAgentMd, isValidAid } = await import('../aun/aid/index.js');
52
290
  if (sub === 'list') {
53
291
  if (wantsHelp(args)) {
@@ -140,33 +378,7 @@ Options:
140
378
  process.exit(1);
141
379
  }
142
380
  const info = await aidShow(aid, { aunPath });
143
- if (formatJson) {
144
- console.log(JSON.stringify(info, null, 2));
145
- return;
146
- }
147
- console.log(`AID: ${info.aid}`);
148
- console.log(` 私钥: ${info.hasPrivateKey ? '有' : '无'}`);
149
- console.log(` agent.md: ${info.hasAgentMd ? '有' : '无'}`);
150
- if (info.hasAgentMd) {
151
- const sigLabel = info.agentMdSignature === 'verified' ? '✓ 已验签'
152
- : info.agentMdSignature === 'unsigned' ? '⚠ 未签名'
153
- : info.agentMdSignature === 'invalid' ? `✗ 签名无效${info.agentMdSignatureReason ? ': ' + info.agentMdSignatureReason : ''}`
154
- : '? 未知';
155
- console.log(` 签名状态: ${sigLabel}`);
156
- }
157
- console.log(` 证书到期: ${info.certExpiresAt ?? '无证书'}${info.certExpired ? ' (已过期!)' : ''}`);
158
- if (info.certSubject)
159
- console.log(` 证书主体: ${info.certSubject}`);
160
- if (info.keyMatchesCert === false)
161
- console.log(` 密钥/证书: ✗ 公钥不匹配(cert.pem 与 key.json 公钥不一致)`);
162
- else if (info.keyMatchesCert === true)
163
- console.log(` 密钥/证书: ✓ 公钥一致`);
164
- if (info.signVerified === true)
165
- console.log(` 可签名/验签: ✓ 实测通过`);
166
- else if (info.signVerified === false)
167
- console.log(` 可签名/验签: ✗ 失败${info.signError ? `(${info.signError})` : ''}`);
168
- else
169
- console.log(` 可签名/验签: ? 未知`);
381
+ renderAidShow(info, formatJson);
170
382
  return;
171
383
  }
172
384
  if (sub === 'new') {
@@ -435,28 +647,7 @@ Options:
435
647
  process.exit(1);
436
648
  }
437
649
  const result = await aidLookup(aid);
438
- if (formatJson) {
439
- console.log(JSON.stringify(result, null, 2));
440
- return;
441
- }
442
- if (result.exists) {
443
- console.log(`✓ ${aid} 已注册`);
444
- if (result.gateway)
445
- console.log(` 网关: ${result.gateway}`);
446
- if (result.content) {
447
- const hasSig = result.content.includes('AUN-SIGNATURE');
448
- console.log(` 签名: ${hasSig ? '有(未验证,如需验证请用 ec aid agentmd get ' + aid + ')' : '无'}`);
449
- console.log('');
450
- console.log(result.content);
451
- }
452
- }
453
- else {
454
- console.log(`✗ ${aid} 未注册`);
455
- if (result.gateway)
456
- console.log(` 网关: ${result.gateway}`);
457
- if (result.error)
458
- console.log(` 原因: ${result.error}`);
459
- }
650
+ renderAidLookup(result, formatJson);
460
651
  return;
461
652
  }
462
653
  if (sub === 'agentmd') {
@@ -504,26 +695,7 @@ Options:
504
695
  }
505
696
  try {
506
697
  const result = await agentmdGet(aid, { withVerification: true, aunPath });
507
- if (!result.content || !result.content.trim()) {
508
- console.log(`ℹ️ ${aid} 尚未设置 agent.md`);
509
- return;
510
- }
511
- if (formatJson) {
512
- console.log(JSON.stringify(result, null, 2));
513
- }
514
- else {
515
- console.log(result.content);
516
- const v = result.verification;
517
- if (v.status === 'verified') {
518
- console.error(`✓ 签名验证通过`);
519
- }
520
- else if (v.status === 'invalid') {
521
- console.error(`⚠ 签名验证失败: ${v.reason ?? '未知原因'}`);
522
- }
523
- else {
524
- console.error(`ℹ️ 未签名`);
525
- }
526
- }
698
+ renderAgentmdGet(aid, result, formatJson);
527
699
  }
528
700
  catch (e) {
529
701
  const msg = String(e.message || e);
@@ -667,6 +839,25 @@ Options:
667
839
  console.error(`❌ 无效 AID 格式: ${aid}`);
668
840
  process.exit(1);
669
841
  }
842
+ if (process.env.EVOLCORE_SESSION_ID) {
843
+ const operation = { ls: 'storage.list', quota: 'storage.quota', upload: 'storage.upload', download: 'storage.download', rm: 'storage.delete' }[sub];
844
+ if (!operation)
845
+ failManagedGroup(formatJson, 'NOT_ALLOWED', `unsupported managed storage command: ${sub}`);
846
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
847
+ if (!delegationToken)
848
+ failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
849
+ const authorization = await ipcQuery(resolvePaths().socket, {
850
+ type: 'storage.auth',
851
+ operation,
852
+ aid,
853
+ sessionId: process.env.EVOLCORE_SESSION_ID,
854
+ delegationToken,
855
+ }, 10_000);
856
+ if (!authorization)
857
+ failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
858
+ if (!authorization.ok)
859
+ failManagedGroup(formatJson, authorization.code || 'STORAGE_AUTH_FAILED', authorization.error || 'Storage operation denied');
860
+ }
670
861
  const { storageUpload, storageDownload, storageLs, storageRm, storageQuota } = await import('../aun/storage/index.js');
671
862
  if (sub === 'upload') {
672
863
  const localFile = args[2];
@@ -874,6 +1065,11 @@ Options:
874
1065
  console.error(`❌ 无效 AID 格式: ${from}`);
875
1066
  process.exit(1);
876
1067
  }
1068
+ if (process.env.EVOLCORE_SESSION_ID && sub !== 'send') {
1069
+ const result = await runManagedMsg(args, formatJson);
1070
+ renderManagedMsgResult(sub, result, formatJson);
1071
+ return;
1072
+ }
877
1073
  const { msgSend, msgPull, msgAck, msgRecall, msgOnline, msgHistory } = await import('../aun/msg/index.js');
878
1074
  const commonOpts = { aunPath, slotId: appSlot };
879
1075
  if (sub === 'history') {
@@ -1334,6 +1530,11 @@ Options:
1334
1530
  printGroupSendAidHint();
1335
1531
  process.exit(1);
1336
1532
  }
1533
+ if (process.env.EVOLCORE_SESSION_ID && sub !== 'send') {
1534
+ const result = await runManagedGroup(args, formatJson);
1535
+ renderManagedGroupResult(args, result, formatJson);
1536
+ return;
1537
+ }
1337
1538
  const { groupSend, groupPull, groupAck, groupCreate, groupInfo, groupList, groupUpdate, groupDissolve, groupSuspend, groupResume, groupJoin, groupLeave, groupInvite, groupKick, groupMembers, groupOnline, groupSetRole, groupTransferOwner, groupBan, groupUnban, groupBanlist, groupRules, groupUpdateRules, groupRulesFileGet, groupRulesFileSet, groupRulesFilePublish, } = await import('../aun/msg/index.js');
1338
1539
  const commonOpts = { aunPath, slotId: appSlot };
1339
1540
  // 通用 group_id 提取(第三参数)
package/dist/cli/bench.js CHANGED
@@ -333,7 +333,10 @@ async function cliSend(from, to, text, slotId, encrypt) {
333
333
  if (encrypt)
334
334
  sendArgs.push('--encrypt');
335
335
  try {
336
- const { stdout } = await execFileAsync('node', sendArgs, { timeout: 30000 });
336
+ const { stdout } = await execFileAsync('node', sendArgs, {
337
+ timeout: 30000,
338
+ windowsHide: process.platform === 'win32',
339
+ });
337
340
  const res = JSON.parse(stdout.trim());
338
341
  return { ok: true, timestamp: res.timestamp };
339
342
  }
@@ -349,7 +352,10 @@ async function cliPull(from, slotId, afterSeq) {
349
352
  if (afterSeq !== undefined)
350
353
  pullArgs.push('--after-seq', String(afterSeq));
351
354
  try {
352
- const { stdout } = await execFileAsync('node', pullArgs, { timeout: 30000 });
355
+ const { stdout } = await execFileAsync('node', pullArgs, {
356
+ timeout: 30000,
357
+ windowsHide: process.platform === 'win32',
358
+ });
353
359
  const res = JSON.parse(stdout.trim());
354
360
  return { ok: true, messages: res.messages ?? [] };
355
361
  }
@@ -362,7 +368,10 @@ async function cliAuth(aid, slotId) {
362
368
  const bin = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
363
369
  const start = Date.now();
364
370
  try {
365
- await execFileAsync('node', [bin, 'msg', 'online', aid, aid, '--app', slotId, '--format', 'json'], { timeout: 15000 });
371
+ await execFileAsync('node', [bin, 'msg', 'online', aid, aid, '--app', slotId, '--format', 'json'], {
372
+ timeout: 15000,
373
+ windowsHide: process.platform === 'win32',
374
+ });
366
375
  return { ok: true, authMs: Date.now() - start };
367
376
  }
368
377
  catch {
@@ -14,21 +14,21 @@ import { isHelpFlag } from './help.js';
14
14
  import { cmdInit, needsControlAidInit, initTail } from './init.js';
15
15
  import * as platform from '../utils/cross-platform.js';
16
16
  import { EventBus } from '../core/event-bus.js';
17
- import { tryUpgrade, tryUpgradeAunSdk, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
17
+ import { tryUpgrade, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
18
18
  import { ecwebVersionRequirementError, fetchEcwebPairCode, resolveEcwebLaunchCommand } from '../utils/ecweb-utils.js';
19
19
  import { isHostChinese } from '../utils/locale.js';
20
- import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
21
20
  import { scanInstances, cleanupInstances, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
22
21
  import { filterLogFiles, deriveLogTypes, computePreChecked, validateLogTypes, shortLogName as shortLogNameLocal } from './watch-logs.js';
23
22
  import { displaySessionTitle } from '../core/session/session-title.js';
24
23
  import { isNonAgentSessionChannel } from '../core/system-channels.js';
25
24
  import { printCodeStats } from './code-stats.js';
26
- import { getProcessStartTime } from '../utils/process-introspect.js';
25
+ import { getProcessStartTime, startTimeMatches } from '../utils/process-introspect.js';
27
26
  import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
28
27
  import { WEB_CLI_BIN, WEB_PACKAGE_LATEST, WEB_PACKAGE_NAME } from '../product.js';
29
28
  import { rotateStdoutLog } from '../utils/log-writer.js';
30
29
  import { inspectDataMigrationRequirement } from '../core/data-migration.js';
31
30
  import { isInitCancelledError, printInitCancelHint } from './init-cancel.js';
31
+ import { listCodexAppServerProcesses, unregisterCodexAppServerProcess } from '../utils/codex-app-server-registry.js';
32
32
  const execFileAsync = promisify(execFile);
33
33
  async function runAutomaticInit(action) {
34
34
  try {
@@ -668,19 +668,7 @@ export async function cmdRestart(opts = {}) {
668
668
  console.log(`⚠ Upgrade failed (${upgrade.from} → ${upgrade.to}), continuing with current version`);
669
669
  break;
670
670
  }
671
- // AUN SDK 版本检查与升级
672
- const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
673
- switch (aunUpgrade.status) {
674
- case 'upgraded':
675
- console.log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
676
- break;
677
- case 'no-update':
678
- break; // silent
679
- case 'failed':
680
- console.log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to})`);
681
- break;
682
- }
683
- // EC Web 版本检查与升级(已安装才检查,与 AUN SDK 同级)
671
+ // EC Web 是独立全局包,已安装时单独检查升级。
684
672
  const ecwebUpgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
685
673
  switch (ecwebUpgrade.status) {
686
674
  case 'upgraded':
@@ -753,22 +741,20 @@ export async function cmdRestart(opts = {}) {
753
741
  reportOrphans(otherHome);
754
742
  }
755
743
  }
756
- // 清理 codex app-server 孤儿进程(无 HOME 区分,全局清理)
744
+ // 只清理 EvolCore 自己登记的 codex app-server,不能影响桌面端实例。
757
745
  {
758
746
  const killed = stopCodexAppServerOrphans();
759
747
  if (killed > 0) {
760
- console.log(`☠ 已清理 ${killed} 个 codex app-server 孤儿进程`);
748
+ console.log(`☠ 已清理 ${killed} 个 EvolCore codex app-server 孤儿进程`);
761
749
  await sleep(500);
762
750
  }
763
751
  }
764
752
  console.log(`⏱ restart prep done in ${((Date.now() - cmdStartedAt) / 1000).toFixed(1)}s, starting...`);
765
753
  // 通过 restart-monitor 启动,避免在 agent 内调用时自杀
766
754
  const appCli = path.join(getPackageRoot(), 'dist', 'cli', 'index.js');
767
- spawn('node', [appCli, 'restart-monitor'], {
768
- detached: true,
769
- stdio: 'ignore',
770
- env: { ...process.env, EVOLCORE_HOME: resolvePaths().root }
771
- }).unref();
755
+ platform.spawnDetachedNode([appCli, 'restart-monitor'], {
756
+ EVOLCORE_HOME: resolvePaths().root,
757
+ });
772
758
  console.log('🔄 Restart monitor started, waiting for service to come back online...');
773
759
  await sleep(2000);
774
760
  // 代码统计(开发环境)
@@ -2513,15 +2499,29 @@ function removeEcwebInstanceFiles(p) {
2513
2499
  catch { }
2514
2500
  }
2515
2501
  }
2516
- /** 清理所有 codex app-server 孤儿进程,返回清理的进程数。 */
2517
- function stopCodexAppServerOrphans() {
2518
- // 查找所有 codex app-server 进程(无论是 node 启动的还是原生二进制)
2519
- const codexProcs = platform.findProcesses('codex app-server');
2502
+ /** 清理 EvolCore 登记的 codex app-server 孤儿进程,返回清理的进程数。 */
2503
+ export function stopCodexAppServerOrphans() {
2504
+ const codexProcs = new Set(platform.findProcesses('codex app-server'));
2520
2505
  let killed = 0;
2521
- for (const pid of codexProcs) {
2506
+ for (const entry of listCodexAppServerProcesses()) {
2507
+ const { pid, startedAt } = entry.record;
2508
+ if (!platform.isProcessRunning(pid)) {
2509
+ unregisterCodexAppServerProcess(entry.filePath);
2510
+ continue;
2511
+ }
2512
+ // PID 复用时丢弃登记,不发送信号;命令行探测失败则保留登记,等待下次重试。
2513
+ const actualStartedAt = getProcessStartTime(pid);
2514
+ if (!startTimeMatches(startedAt, actualStartedAt)) {
2515
+ unregisterCodexAppServerProcess(entry.filePath);
2516
+ continue;
2517
+ }
2518
+ if (!codexProcs.has(pid))
2519
+ continue;
2522
2520
  try {
2523
- platform.killProcess(pid, true);
2524
- killed++;
2521
+ if (platform.killProcess(pid, true)) {
2522
+ killed++;
2523
+ unregisterCodexAppServerProcess(entry.filePath);
2524
+ }
2525
2525
  }
2526
2526
  catch { }
2527
2527
  }
@@ -2777,7 +2777,7 @@ async function cmdWatchWeb() {
2777
2777
  }
2778
2778
  }
2779
2779
  else {
2780
- // 已安装:检查并自动升级到最新版(参考 fastaun 自动升级机制)
2780
+ // 已安装:检查并自动升级独立的 EC Web 全局包。
2781
2781
  const upgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
2782
2782
  switch (upgrade.status) {
2783
2783
  case 'upgraded':
@@ -3,6 +3,9 @@ import path from 'path';
3
3
  import { TextDecoder } from 'util';
4
4
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
5
5
  import { agentmdGet, getAidStore, isValidAid, loadClient, SLOT } from '../aun/aid/index.js';
6
+ import { ipcQuery } from '../ipc.js';
7
+ import { resolvePaths } from '../paths.js';
8
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
6
9
  class FsCliError extends Error {
7
10
  code;
8
11
  suggestion;
@@ -130,6 +133,10 @@ export async function cmdFs(args) {
130
133
  console.log(HELP);
131
134
  return;
132
135
  }
136
+ if (process.env.EVOLCORE_SESSION_ID) {
137
+ await runManagedFs(args, opts.formatJson);
138
+ return;
139
+ }
133
140
  try {
134
141
  switch (sub) {
135
142
  case 'ls':
@@ -199,6 +206,59 @@ export async function cmdFs(args) {
199
206
  process.exit(1);
200
207
  }
201
208
  }
209
+ async function runManagedFs(args, formatJson) {
210
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
211
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
212
+ const fail = (code, message) => {
213
+ if (formatJson)
214
+ console.log(JSON.stringify({ ok: false, code, error: message }));
215
+ else
216
+ console.error(`❌ ${message}`);
217
+ process.exit(1);
218
+ };
219
+ if (!sessionId)
220
+ fail('NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
221
+ if (!delegationToken)
222
+ fail('DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
223
+ const response = await ipcQuery(resolvePaths().socket, {
224
+ type: 'fs.op',
225
+ argv: ['fs', ...args],
226
+ sessionId,
227
+ delegationToken,
228
+ }, 30_000);
229
+ if (!response)
230
+ return fail('DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
231
+ if (!response.ok || !response.result)
232
+ fail(String(response.code || 'FS_OPERATION_FAILED'), response.error || 'Filesystem operation failed');
233
+ const result = response.result;
234
+ if (formatJson) {
235
+ console.log(JSON.stringify(result));
236
+ return;
237
+ }
238
+ switch (result.command) {
239
+ case 'cat':
240
+ if (result.binary)
241
+ console.log(JSON.stringify({ path: result.path, size: result.size, binary: true, head: result.head }, null, 2));
242
+ else
243
+ process.stdout.write(String(result.text ?? '').endsWith('\n') ? result.text : `${result.text ?? ''}\n`);
244
+ return;
245
+ case 'df': {
246
+ const usage = result.usage ?? {};
247
+ console.log(`Filesystem: ${result.path}`);
248
+ console.log(JSON.stringify(usage, null, 2));
249
+ return;
250
+ }
251
+ case 'stat':
252
+ case 'lstat':
253
+ console.log(JSON.stringify(result.node ?? {}, null, 2));
254
+ return;
255
+ case 'ls':
256
+ case 'find':
257
+ for (const item of result.items ?? [])
258
+ console.log(JSON.stringify(item));
259
+ return;
260
+ }
261
+ }
202
262
  function parseCommonOptions(args) {
203
263
  const maxCatBytesRaw = getArgValue(args, '--max-bytes');
204
264
  const maxCatBytes = maxCatBytesRaw === undefined ? 1024 * 1024 : Number(maxCatBytesRaw);
@@ -203,6 +203,7 @@ Commands:
203
203
  }
204
204
  const result = await ipcQuery(resolvePaths().socket, {
205
205
  type: 'handoff-status', sessionId: process.env.EVOLCORE_SESSION_ID, handoffId,
206
+ delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
206
207
  }, 5000);
207
208
  if (!result) {
208
209
  console.error('✗ daemon 暂时不可用');
@@ -234,6 +235,7 @@ Commands:
234
235
  state: parsed.state,
235
236
  filterSessionId: parsed.sessionId,
236
237
  limit: parsed.limit,
238
+ delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
237
239
  }, 5000);
238
240
  if (!result) {
239
241
  console.error('✗ daemon 暂时不可用');
@@ -276,6 +278,7 @@ Commands:
276
278
  agent: parsed.agent,
277
279
  handoffId: parsed.handoffId,
278
280
  limit: parsed.limit,
281
+ delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
279
282
  }, 5000);
280
283
  if (!result) {
281
284
  console.error('✗ daemon 暂时不可用');