evolcore 0.0.26 → 0.0.28

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 (177) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/bin/codex-managed-acl.ps1 +43 -0
  3. package/dist/agents/baseagent-availability.js +68 -0
  4. package/dist/agents/baseagent.js +10 -5
  5. package/dist/agents/claude-runner.js +123 -22
  6. package/dist/agents/codex/app-server-client.js +70 -26
  7. package/dist/agents/codex/catalog.js +7 -1
  8. package/dist/agents/codex-runner.js +363 -421
  9. package/dist/agents/ecagent-runner.js +170 -25
  10. package/dist/agents/gemini-runner.js +6 -0
  11. package/dist/agents/runner-types.js +50 -2
  12. package/dist/aun/aid/agentmd.js +73 -31
  13. package/dist/aun/aid/client.js +1 -1
  14. package/dist/aun/aid/control-aid.js +180 -1
  15. package/dist/aun/aid/identity.js +3 -3
  16. package/dist/aun/group/history.js +303 -0
  17. package/dist/aun/group/identity.js +43 -0
  18. package/dist/aun/group/index.js +5 -0
  19. package/dist/aun/{msg/group.js → group/operations.js} +161 -38
  20. package/dist/aun/{menu-client.js → menu/client.js} +13 -7
  21. package/dist/aun/menu/index.js +2 -0
  22. package/dist/aun/menu/transport.js +49 -0
  23. package/dist/aun/msg/index.js +2 -1
  24. package/dist/aun/msg/managed-operation.js +84 -18
  25. package/dist/aun/msg/mention-schema.js +51 -0
  26. package/dist/aun/msg/p2p.js +13 -8
  27. package/dist/aun/msg/upload.js +43 -88
  28. package/dist/aun/outbox.js +29 -7
  29. package/dist/aun/rpc/client.js +1 -0
  30. package/dist/aun/storage/client.js +39 -50
  31. package/dist/channels/aun.js +544 -239
  32. package/dist/channels/daemon.js +10 -6
  33. package/dist/cli/agent-command.js +108 -6
  34. package/dist/cli/agent-create.js +515 -2
  35. package/dist/cli/agent.js +109 -8
  36. package/dist/cli/aun-commands.js +191 -42
  37. package/dist/cli/config.js +8 -5
  38. package/dist/cli/contact.js +2 -2
  39. package/dist/cli/ctl-command.js +2 -2
  40. package/dist/cli/daemon-commands.js +111 -162
  41. package/dist/cli/diag.js +3 -3
  42. package/dist/cli/fs-command.js +3 -3
  43. package/dist/cli/handoff-command.js +6 -6
  44. package/dist/cli/index.js +8 -2
  45. package/dist/cli/init.js +34 -1
  46. package/dist/cli/managed-command-guard.js +2 -1
  47. package/dist/cli/menu-client.js +13 -5
  48. package/dist/cli/model.js +3 -3
  49. package/dist/cli/queue-command.js +2 -2
  50. package/dist/cli/response.js +2 -2
  51. package/dist/cli/restart-monitor.js +81 -19
  52. package/dist/cli/task-command.js +59 -0
  53. package/dist/cli/task-context.js +97 -49
  54. package/dist/cli/trigger-command.js +20 -10
  55. package/dist/config/builtin-roles.js +10 -0
  56. package/dist/config/config-field-policy.js +11 -0
  57. package/dist/config/config-manager.js +32 -4
  58. package/dist/config/config-operation-service.js +20 -5
  59. package/dist/config/contact-book-store.js +1 -1
  60. package/dist/config/contact-book.js +1 -1
  61. package/dist/config/contact-operation-service.js +1 -1
  62. package/dist/config/peer-role-resolver.js +1 -1
  63. package/dist/config/resolved-config-op.js +3 -0
  64. package/dist/config-store.js +1 -1
  65. package/dist/core/agent-application-service.js +5 -0
  66. package/dist/core/audit/event-key.js +17 -2
  67. package/dist/core/audit/log-integrity.js +34 -8
  68. package/dist/core/auth/agent-delegation.js +48 -14
  69. package/dist/core/auth/auth-gateway.js +2 -0
  70. package/dist/core/auth/authorization-audit.js +34 -38
  71. package/dist/core/auth/operation-authorizer.js +67 -5
  72. package/dist/core/auth/operation-catalog.js +110 -0
  73. package/dist/core/auth/remote-access-store.js +115 -9
  74. package/dist/core/bootstrap-messages.js +66 -7
  75. package/dist/core/bootstrap-service.js +110 -19
  76. package/dist/core/command/agent-control.js +88 -7
  77. package/dist/core/command/agent-storage-menu.js +443 -0
  78. package/dist/core/command/cli-intent-parser.js +19 -0
  79. package/dist/core/command/command-handler.js +105 -40
  80. package/dist/core/command/data-root-resolver.js +273 -0
  81. package/dist/core/command/diag-service.js +292 -27
  82. package/dist/core/command/group-menu.js +7 -2
  83. package/dist/core/command/menu-catalog.js +34 -4
  84. package/dist/core/command/menu-handler.js +364 -96
  85. package/dist/core/command/menu-protocol.js +43 -6
  86. package/dist/core/command/role-menu.js +2 -2
  87. package/dist/core/command/slash-handler.js +61 -37
  88. package/dist/core/event-catalog.js +4 -0
  89. package/dist/core/evolagent-registry.js +28 -2
  90. package/dist/core/group/invite-service.js +924 -0
  91. package/dist/core/interaction-router.js +22 -8
  92. package/dist/core/message/im-renderer.js +94 -16
  93. package/dist/core/message/message-bridge.js +140 -13
  94. package/dist/core/message/message-log.js +5 -3
  95. package/dist/core/message/message-queue.js +73 -41
  96. package/dist/core/message/response-engine.js +729 -118
  97. package/dist/core/permission/approval-gateway.js +36 -3
  98. package/dist/core/permission/ec-command-parser.js +76 -36
  99. package/dist/core/permission/protected-paths.js +134 -16
  100. package/dist/core/permission/sandbox-runtime.js +72 -3
  101. package/dist/core/permission/tool-error-code.js +15 -0
  102. package/dist/core/permission/tool-policy.js +8 -8
  103. package/dist/core/relation/peer-identity.js +57 -6
  104. package/dist/core/relation/shared-data.js +106 -0
  105. package/dist/core/role/runtime-policy.js +64 -0
  106. package/dist/core/runtime-lock.js +10 -26
  107. package/dist/core/session/runner-task-history.js +170 -0
  108. package/dist/core/session/session-manager.js +38 -6
  109. package/dist/core/session/session-mapper.js +41 -0
  110. package/dist/core/session/session-turn-coordinator.js +37 -7
  111. package/dist/core/session/session-turns.js +48 -7
  112. package/dist/core/task/task-recovery-service.js +176 -0
  113. package/dist/core/task/task-resume-operation.js +32 -0
  114. package/dist/eck/group-rules-sync.js +5 -3
  115. package/dist/eck/kit-renderer.js +1 -0
  116. package/dist/index.js +322 -207
  117. package/dist/ipc.js +141 -15
  118. package/dist/paths.js +17 -4
  119. package/dist/product.js +3 -0
  120. package/dist/trigger/event-source.js +19 -0
  121. package/dist/trigger/feedback.js +233 -40
  122. package/dist/trigger/parser.js +55 -5
  123. package/dist/trigger/patch.js +9 -0
  124. package/dist/trigger/scheduler.js +30 -4
  125. package/dist/trigger/validation.js +20 -3
  126. package/dist/utils/atomic-write.js +98 -0
  127. package/dist/utils/cross-platform.js +87 -16
  128. package/dist/utils/ecweb-utils.js +1 -0
  129. package/dist/utils/error-utils.js +40 -2
  130. package/dist/utils/logger.js +23 -13
  131. package/dist/utils/npm-ops.js +119 -4
  132. package/dist/utils/package-version-info.js +244 -0
  133. package/dist/utils/tool-summary.js +59 -3
  134. package/dist/utils/welcome.js +174 -1
  135. package/dist/utils/windows-shell-trust.js +37 -0
  136. package/ecagent/dist/harness/agent-harness.js +3 -0
  137. package/ecagent/dist/harness/session/jsonl-storage.js +21 -2
  138. package/kits/docs/INDEX.md +0 -6
  139. package/kits/docs/channels/aun.md +23 -2
  140. package/kits/docs/channels/feishu.md +1 -1
  141. package/kits/docs/context-assembly.md +29 -17
  142. package/kits/docs/evolcore/INDEX.md +8 -3
  143. package/kits/docs/evolcore/agent-create.md +39 -7
  144. package/kits/docs/evolcore/agent.md +33 -1
  145. package/kits/docs/evolcore/aid.md +9 -1
  146. package/kits/docs/evolcore/config.md +40 -1
  147. package/kits/docs/evolcore/group-collaboration.md +1 -1
  148. package/kits/docs/evolcore/group.md +117 -2
  149. package/kits/docs/evolcore/menu-client.md +16 -0
  150. package/kits/docs/evolcore/msg.md +3 -0
  151. package/kits/docs/evolcore/storage.md +3 -0
  152. package/kits/docs/evolcore/task.md +14 -0
  153. package/kits/docs/evolcore/trigger.md +51 -3
  154. package/kits/docs/venues/group.md +5 -0
  155. package/kits/eck_manifest.json +27 -0
  156. package/kits/rules/01-overview.md +11 -7
  157. package/kits/rules/04-relation.md +2 -1
  158. package/kits/rules/05-venue.md +1 -1
  159. package/kits/rules/06-channel.md +6 -4
  160. package/kits/schemas/agent-config.schema.12.json +25 -1
  161. package/kits/schemas/daemon.schema.6.json +2 -2
  162. package/kits/schemas/defaults.schema.5.json +1 -1
  163. package/kits/schemas/relation-config.schema.1.json +1 -1
  164. package/kits/schemas/relation-config.schema.5.json +1 -1
  165. package/kits/schemas/role-config.schema.1.json +14 -0
  166. package/kits/templates/roles/member.json +5 -0
  167. package/kits/templates/roles/visitor.json +5 -0
  168. package/kits/templates/system-fragments/baseagent.md +1 -1
  169. package/kits/templates/system-fragments/bootstrap.md +26 -9
  170. package/kits/templates/system-fragments/channel.md +8 -44
  171. package/kits/templates/system-fragments/commands.md +10 -2
  172. package/kits/templates/system-fragments/group-unread-history.md +7 -0
  173. package/kits/templates/system-fragments/reply.md +56 -0
  174. package/package.json +7 -3
  175. package/dist/aun/group-identity.js +0 -9
  176. /package/dist/aun/{group-fs-download.js → group/fs-download.js} +0 -0
  177. /package/dist/aun/{msg/group-index.js → group/index-rpc.js} +0 -0
package/dist/cli/agent.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { resolvePaths, agentMdPath as getAgentMdPathFromPaths, agentPersonalDir, aunPath as defaultAunPath } from '../paths.js';
3
+ import { SESSION_ID_ENV } from '../product.js';
4
+ import { resolvePaths, agentMdPath as getAgentMdPathFromPaths, agentPersonalDir, agentWelcomePath, aunPath as defaultAunPath } from '../paths.js';
4
5
  import { loadDefaults, loadAllAgents, loadAgent, saveAgent, ensureAgentDirSkeleton } from '../config-store.js';
5
6
  import { initConfigManager } from '../config/config-manager.js';
6
7
  import { resolveConfigCommand } from '../config/resolved-config-op.js';
@@ -10,16 +11,21 @@ import { CONFIG_SCHEMA_VERSION } from '../types.js';
10
11
  import { ensureInitialRoleRegistry } from '../config/role-service.js';
11
12
  import { agentProjectRootFromDefaults, deriveAgentProjectPath } from '../utils/project-path.js';
12
13
  import { isValidChannelName } from '../core/channel-loader.js';
13
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
14
+ import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
14
15
  import { readTaskRuntimeContextFromEnv } from './task-context.js';
16
+ import { isValidAid } from '../aun/aid/validation.js';
15
17
  import { isHClassPath, isLClassPath, isSameOrDescendant } from '../core/permission/protected-paths.js';
18
+ import { findPostBootstrapWelcomeOutbox } from '../core/bootstrap-messages.js';
19
+ import { resolveAgentLifecycle } from '../config/lifecycle.js';
20
+ import { initializationSummary } from './agent-create.js';
21
+ import { parseAgentWelcomeMetadata, readAgentWelcomeTemplate, renderPostBootstrapWelcomeMessage, saveAgentWelcomeTemplate, validateWelcomeTemplate } from '../utils/welcome.js';
16
22
  export { agentCreateInteractive, agentCreateNonInteractive, parseAgentOwnerArgs, resolveAgentCreatePlan, validateAgentCreatePlan, validateAgentOwnerOptions, } from './agent-create.js';
17
23
  /** Route agent lifecycle commands from a managed task through daemon IPC. */
18
24
  export async function runManagedAgentOperation(argv) {
19
25
  const sessionId = process.env.EVOLCORE_SESSION_ID;
20
26
  if (!sessionId)
21
27
  return { ok: false, code: 'MANAGED_ONLY', error: 'agent operation is not running in a managed task' };
22
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
28
+ const delegationToken = readDelegationCredential();
23
29
  if (!delegationToken) {
24
30
  return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
25
31
  }
@@ -74,6 +80,7 @@ function toAgentListItem(info, stale = false) {
74
80
  name: info.name,
75
81
  personalName: info.personalName || null,
76
82
  status: stale && storedStatus !== 'disabled' && storedStatus !== 'error' ? 'unknown' : storedStatus,
83
+ lifecycle: info.lifecycle ?? null,
77
84
  channels: info.channels || [],
78
85
  projectPath: toPosix(info.projectPath || null),
79
86
  baseagent: info.baseagent || null,
@@ -158,6 +165,27 @@ export async function agentShow(aid) {
158
165
  registry.loadAll();
159
166
  const agent = registry.get(aid);
160
167
  if (!agent) {
168
+ const init = initializationSummary(aid);
169
+ if (init) {
170
+ return {
171
+ ok: true,
172
+ aid,
173
+ status: 'initializing',
174
+ lifecycle: loadAgent(aid)?.lifecycle ?? null,
175
+ identity: { name: null, description: null },
176
+ config: { baseagent: null, model: null, effort: null, chatmode: null, channels: [] },
177
+ connection: null,
178
+ sessions: { active: 0, last_activity: null },
179
+ paths: {
180
+ config: toPosix(path.join(p.agentsDir, aid, 'config.json')),
181
+ agent_md: toPosix(getAgentMdPath(aid)),
182
+ project: null,
183
+ data: toPosix(path.join(p.agentsDir, aid, 'data')),
184
+ },
185
+ initialization: init,
186
+ stale: true,
187
+ };
188
+ }
161
189
  const allList = registry.list();
162
190
  const available = allList.map((i) => i.name).join(', ');
163
191
  return { ok: false, error: `Agent "${aid}" not found.${available ? ` Available: ${available}` : ''}` };
@@ -203,6 +231,7 @@ export async function agentShow(aid) {
203
231
  project: toPosix(agentInfo.projectPath || null),
204
232
  data: toPosix(path.join(p.agentsDir, aid, 'data')),
205
233
  },
234
+ ...(initializationSummary(aid) ? { initialization: initializationSummary(aid) } : {}),
206
235
  ...(stale ? { stale: true } : {}),
207
236
  };
208
237
  }
@@ -362,7 +391,7 @@ async function runManagedAgentConfig(args, options) {
362
391
  const sessionId = process.env.EVOLCORE_SESSION_ID;
363
392
  if (!sessionId || options.trustedLocal)
364
393
  return { managed: false };
365
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
394
+ const delegationToken = readDelegationCredential();
366
395
  if (!delegationToken) {
367
396
  return {
368
397
  managed: true,
@@ -469,7 +498,7 @@ export async function agentSet(aid, key, rawValue, options = {}) {
469
498
  return { ok: true, aid, key, value, reloaded };
470
499
  }
471
500
  export const AGENT_PERSONA_MAX_BYTES = 64 * 1024;
472
- function validatePersonaContent(content) {
501
+ export function validatePersonaContent(content) {
473
502
  if (content.includes('\0'))
474
503
  return 'persona 只能包含文本内容';
475
504
  if (Buffer.byteLength(content, 'utf8') > AGENT_PERSONA_MAX_BYTES) {
@@ -569,6 +598,78 @@ export async function agentPersona(aid, options = {}) {
569
598
  return { ok: false, code: 'WRITE_FAILED', error: e?.message || String(e) };
570
599
  }
571
600
  }
601
+ /** Read or replace the current Agent's confirmed Bootstrap welcome template. */
602
+ export async function agentWelcome(aid, options = {}) {
603
+ if (!isValidAid(aid))
604
+ return { ok: false, code: 'INVALID_ARGS', error: 'Invalid Agent AID' };
605
+ if (options.text !== undefined) {
606
+ const validation = validateWelcomeTemplate(options.text);
607
+ if (!validation.valid)
608
+ return { ok: false, code: 'INVALID_ARGS', error: validation.errors.join('; ') };
609
+ }
610
+ const managedSession = !!process.env[SESSION_ID_ENV] && !options.trustedLocal;
611
+ const managedArgs = options.text !== undefined
612
+ ? ['welcome', '--text', options.text]
613
+ : ['welcome', 'show'];
614
+ if (managedSession) {
615
+ if (readTaskRuntimeContextFromEnv()?.selfAid !== aid) {
616
+ return { ok: false, code: 'SELF_AGENT_REQUIRED', error: 'welcome only targets the current Agent' };
617
+ }
618
+ const managed = await runManagedAgentOperation(managedArgs);
619
+ if (!managed.ok)
620
+ return managed;
621
+ return {
622
+ ok: true,
623
+ aid,
624
+ content: managed.content ?? null,
625
+ ...(managed.path ? { path: managed.path } : {}),
626
+ ...(managed.saved ? { saved: true } : {}),
627
+ ...(managed.bytes !== undefined ? { bytes: managed.bytes } : {}),
628
+ ...(managed.sha256 ? { sha256: managed.sha256 } : {}),
629
+ };
630
+ }
631
+ const config = loadAgent(aid);
632
+ if (!config)
633
+ return { ok: false, code: 'NOT_FOUND', error: 'Agent not found' };
634
+ if (options.text === undefined) {
635
+ try {
636
+ return { ok: true, aid, content: readAgentWelcomeTemplate(aid), path: agentWelcomePath(aid) };
637
+ }
638
+ catch (e) {
639
+ return { ok: false, code: 'READ_FAILED', error: e instanceof Error ? e.message : String(e) };
640
+ }
641
+ }
642
+ if (resolveAgentLifecycle(config) !== 'bootstrapping' || config.initialization) {
643
+ return { ok: false, code: 'INVALID_LIFECYCLE', error: 'welcome can only be saved during conversational Bootstrap' };
644
+ }
645
+ try {
646
+ if (findPostBootstrapWelcomeOutbox(aid, { includeTerminal: true }).length) {
647
+ if (readAgentWelcomeTemplate(aid) === options.text) {
648
+ return { ok: true, aid, content: options.text, saved: true, path: agentWelcomePath(aid), bytes: Buffer.byteLength(options.text, 'utf8') };
649
+ }
650
+ return { ok: false, code: 'WELCOME_FROZEN', error: 'welcome delivery has already been prepared; resume ready with the saved text' };
651
+ }
652
+ const mdPath = getAgentMdPath(aid);
653
+ const metadata = parseAgentWelcomeMetadata(fs.existsSync(mdPath) ? fs.readFileSync(mdPath, 'utf8') : '');
654
+ try {
655
+ for (const owner of config.owners?.length ? config.owners : [aid]) {
656
+ renderPostBootstrapWelcomeMessage({
657
+ template: options.text, agentName: metadata.name || aid.split('.')[0], agentAid: aid,
658
+ agentDescription: metadata.description, agentTags: metadata.tags,
659
+ ownerAid: owner, ownerName: owner.split('.')[0],
660
+ });
661
+ }
662
+ }
663
+ catch (error) {
664
+ return { ok: false, code: 'WELCOME_INVALID', error: error.message };
665
+ }
666
+ const saved = saveAgentWelcomeTemplate(aid, options.text);
667
+ return { ok: true, aid, content: options.text, ...saved, saved: true };
668
+ }
669
+ catch (e) {
670
+ return { ok: false, code: 'WRITE_FAILED', error: e instanceof Error ? e.message : String(e) };
671
+ }
672
+ }
572
673
  /**
573
674
  * Add or overwrite a channel instance on a per-agent config.
574
675
  *
@@ -704,7 +805,7 @@ export async function agentReady(aid) {
704
805
  }
705
806
  const p = resolvePaths();
706
807
  try {
707
- const delegationToken = managedSessionId ? process.env[AGENT_DELEGATION_TOKEN_ENV] : undefined;
808
+ const delegationToken = managedSessionId ? readDelegationCredential() : undefined;
708
809
  if (managedSessionId && !delegationToken) {
709
810
  return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
710
811
  }
@@ -714,11 +815,11 @@ export async function agentReady(aid) {
714
815
  ...(managedSessionId ? { sessionId: managedSessionId, delegationToken } : {}),
715
816
  }, 30_000);
716
817
  if (!result)
717
- return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the evolcore daemon; agent ready requires daemon IPC' };
818
+ return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the EvolCore daemon; agent ready requires daemon IPC' };
718
819
  if (!result.ok) {
719
820
  return { ok: false, code: result.code, error: result.error || 'Failed to complete bootstrap' };
720
821
  }
721
- return { ok: true, aid, reloaded: true };
822
+ return { ...result, ok: true, aid, reloaded: result.reloaded === true };
722
823
  }
723
824
  catch (e) {
724
825
  return {
@@ -1,10 +1,10 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { agentMdPath, resolvePaths, resolveRoot } from '../paths.js';
4
- import { isExplicitGroupId } from '../aun/group-identity.js';
4
+ import { isExplicitGroupId, normalizeGroupAid, sameGroupAid } from '../aun/group/index.js';
5
5
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
6
6
  import { ipcQuery } from '../ipc.js';
7
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
7
+ import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
8
8
  import { isManagementRole } from '../config/builtin-roles.js';
9
9
  import { readBestTaskRuntimeContext } from './task-context.js';
10
10
  // ==================== AID ====================
@@ -107,7 +107,7 @@ async function runManagedAid(args, formatJson) {
107
107
  const sessionId = process.env.EVOLCORE_SESSION_ID;
108
108
  if (!sessionId)
109
109
  failManagedAid(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
110
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
110
+ const delegationToken = readDelegationCredential();
111
111
  if (!delegationToken) {
112
112
  failManagedAid(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
113
113
  }
@@ -184,7 +184,7 @@ async function runManagedGroup(args, formatJson) {
184
184
  const sessionId = process.env.EVOLCORE_SESSION_ID;
185
185
  if (!sessionId)
186
186
  failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
187
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
187
+ const delegationToken = readDelegationCredential();
188
188
  if (!delegationToken) {
189
189
  failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
190
190
  }
@@ -214,7 +214,7 @@ async function runManagedMsg(args, formatJson) {
214
214
  const sessionId = process.env.EVOLCORE_SESSION_ID;
215
215
  if (!sessionId)
216
216
  failManagedGroup(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
217
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
217
+ const delegationToken = readDelegationCredential();
218
218
  if (!delegationToken) {
219
219
  failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
220
220
  }
@@ -274,7 +274,7 @@ function validateManagedGroupScope(from, groupId, runtime, formatJson) {
274
274
  if (runtime.channel !== 'aun' || runtime.chatType !== 'group') {
275
275
  failManagedGroup(formatJson, 'ARGUMENT_MISMATCH', `当前角色 ${runtime.peerRole} 只能在 AUN 群聊任务中操作当前群`);
276
276
  }
277
- if (!runtime.channelId || groupId !== runtime.channelId) {
277
+ if (!runtime.channelId || !sameGroupAid(groupId, runtime.channelId)) {
278
278
  failManagedGroup(formatJson, 'ARGUMENT_MISMATCH', `当前角色 ${runtime.peerRole} 只能操作当前群 ${runtime.channelId ?? '<unknown>'},不能操作 ${groupId}`);
279
279
  }
280
280
  }
@@ -307,6 +307,27 @@ function renderManagedGroupResult(args, result, formatJson) {
307
307
  return;
308
308
  }
309
309
  const sub = args[0];
310
+ if (sub === 'history') {
311
+ if (result.mode === 'message')
312
+ console.log(result.content);
313
+ else {
314
+ console.log('本地群历史:' + result.count + ' 条');
315
+ for (const message of result.messages ?? []) {
316
+ console.log('[' + message.time + '] ' + message.from + ' → ' + message.to
317
+ + ' thread=' + (message.threadId || 'main') + '\n' + message.content);
318
+ if (message.content_truncated)
319
+ console.log('正文尚未读完');
320
+ if (message.content_truncated && message.msgId) {
321
+ console.log('--all --message ' + message.msgId + ' --offset ' + message.next_offset);
322
+ }
323
+ }
324
+ }
325
+ if (result.next_offset != null)
326
+ console.log('next_offset=' + result.next_offset);
327
+ if (result.has_more)
328
+ console.log('还有更多历史');
329
+ return;
330
+ }
310
331
  if (sub === 'list') {
311
332
  if (!result.items?.length)
312
333
  console.log('(没有加入任何群)');
@@ -317,8 +338,35 @@ function renderManagedGroupResult(args, result, formatJson) {
317
338
  }
318
339
  return;
319
340
  }
341
+ if (sub === 'blocklist') {
342
+ const items = result.items ?? [];
343
+ console.log(items.length ? `共 ${result.total ?? items.length} 条屏蔽:` : '(没有屏蔽成员)');
344
+ for (const item of items) {
345
+ console.log(` ${item.subject ?? item.aid ?? '-'} blocked_by=${item.blocked_by ?? '-'} reason=${item.reason ?? ''}`);
346
+ }
347
+ return;
348
+ }
349
+ if (sub === 'member-statuses') {
350
+ console.log(`成员上报状态(共 ${result.items?.length ?? 0} 名成员):`);
351
+ for (const item of result.items ?? []) {
352
+ console.log(` ${item.aid ?? '-'} online_status=${item.online_status || '(未上报)'} work_status=${item.work_status || '(未上报)'}`);
353
+ }
354
+ return;
355
+ }
356
+ if (sub === 'report-status') {
357
+ console.log('✓ 已上报当前成员状态');
358
+ console.log(JSON.stringify(result.data?.status ?? {}, null, 2));
359
+ return;
360
+ }
361
+ if (sub === 'block' || sub === 'unblock') {
362
+ const target = result.data?.block?.subject ?? result.data?.subject ?? args[3];
363
+ console.log(`✓ 已${sub === 'block' ? '屏蔽' : '取消屏蔽'} ${target} 接收群消息`);
364
+ return;
365
+ }
320
366
  if (sub === 'create') {
321
- console.log(`✓ 已创建群 ${result.group?.group_id ?? '-'}`);
367
+ console.log(`✓ 已创建群 ${result.group?.group_aid ?? result.group?.group_id ?? '-'}`);
368
+ if (result.warning)
369
+ console.warn(result.warning);
322
370
  return;
323
371
  }
324
372
  if (sub === 'rules' && args[3] === 'get' && result.status === 'ok') {
@@ -338,7 +386,7 @@ function renderManagedGroupResult(args, result, formatJson) {
338
386
  return;
339
387
  }
340
388
  if (sub === 'accept-invite' || sub === 'reject-invite' || sub === 'revoke-invite') {
341
- console.log(`✓ group ${sub} 完成`);
389
+ console.log(typeof result.message === 'string' ? result.message : `✓ group ${sub} 完成`);
342
390
  return;
343
391
  }
344
392
  console.log(`✓ group ${sub} 完成`);
@@ -992,15 +1040,47 @@ Options:
992
1040
  const operation = { ls: 'storage.list', quota: 'storage.quota', upload: 'storage.upload', download: 'storage.download', rm: 'storage.delete' }[sub];
993
1041
  if (!operation)
994
1042
  failManagedGroup(formatJson, 'NOT_ALLOWED', `unsupported managed storage command: ${sub}`);
995
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
1043
+ const delegationToken = readDelegationCredential();
996
1044
  if (!delegationToken)
997
1045
  failManagedGroup(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
1046
+ if (sub === 'upload') {
1047
+ const localFile = args[2];
1048
+ const remotePath = args[3];
1049
+ if (!localFile || !remotePath) {
1050
+ console.error('用法: ec storage upload <aid> <local-file> <remote-path> [--public]');
1051
+ process.exit(1);
1052
+ }
1053
+ if (!fs.existsSync(localFile)) {
1054
+ console.error(`❌ 文件不存在: ${localFile}`);
1055
+ process.exit(1);
1056
+ }
1057
+ const result = await ipcQuery(resolvePaths().socket, {
1058
+ type: 'storage.upload',
1059
+ aid,
1060
+ localFile,
1061
+ remotePath,
1062
+ isPublic: args.includes('--public'),
1063
+ sessionId: process.env.EVOLCORE_SESSION_ID,
1064
+ delegationToken,
1065
+ }, null);
1066
+ if (!result)
1067
+ failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
1068
+ if (!result.ok)
1069
+ failManagedGroup(formatJson, result.code || 'STORAGE_UPLOAD_FAILED', result.error || 'Storage upload failed');
1070
+ if (formatJson)
1071
+ console.log(JSON.stringify({ ok: true, objectKey: remotePath, isPublic: args.includes('--public'), ref: `${aid}/${remotePath}`, publicUrl: result.publicUrl ?? null }));
1072
+ else {
1073
+ console.log(`✓ 已上传: ${remotePath}${args.includes('--public') ? ' (公开)' : ''}`);
1074
+ if (result.publicUrl)
1075
+ console.log(` 🔗 访问: ${result.publicUrl}`);
1076
+ else
1077
+ console.log(` 引用: ${aid}/${remotePath}`);
1078
+ console.log(` 下载: ec storage download ${aid} ${aid}/${remotePath}`);
1079
+ }
1080
+ return;
1081
+ }
998
1082
  const authorization = await ipcQuery(resolvePaths().socket, {
999
- type: 'storage.auth',
1000
- operation,
1001
- aid,
1002
- sessionId: process.env.EVOLCORE_SESSION_ID,
1003
- delegationToken,
1083
+ type: 'storage.auth', operation, aid, sessionId: process.env.EVOLCORE_SESSION_ID, delegationToken,
1004
1084
  }, 10_000);
1005
1085
  if (!authorization)
1006
1086
  failManagedGroup(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
@@ -1443,26 +1523,12 @@ Options:
1443
1523
  console.error(`❌ --return 仅支持 required|none: ${returnPolicyRaw}`);
1444
1524
  process.exit(1);
1445
1525
  }
1446
- // 文件上传进度展示(非 JSON 输出时)。仅在大文件降级到 HTTP PUT 阶段会逐块更新。
1447
- let lastPctShown = -1;
1526
+ // SDK 尚未提供字节进度回调,只展示上传开始和成功完成。
1448
1527
  const onUploadProgress = formatJson ? undefined : (info) => {
1449
- if (info.phase === 'inline')
1450
- return; // 内联阶段不分块,跳过
1451
- if (info.phase === 'http-put') {
1452
- const pct = info.total > 0 ? Math.floor((info.bytes / info.total) * 100) : 0;
1453
- if (pct === lastPctShown && info.bytes < info.total)
1454
- return;
1455
- lastPctShown = pct;
1456
- const mb = (n) => (n / 1024 / 1024).toFixed(2);
1457
- const eol = info.bytes >= info.total ? '\n' : '\r';
1458
- process.stderr.write(` ⏫ uploading: ${pct}% (${mb(info.bytes)}/${mb(info.total)} MB)${eol}`);
1459
- }
1460
- else if (info.phase === 'session-create') {
1461
- process.stderr.write(' ⏫ requesting upload session...\n');
1462
- }
1463
- else if (info.phase === 'session-complete') {
1464
- process.stderr.write(' ⏫ finalizing upload...\n');
1465
- }
1528
+ if (info.phase === 'upload')
1529
+ process.stderr.write(' ⏫ uploading...\n');
1530
+ else if (info.phase === 'done')
1531
+ process.stderr.write(' ✓ upload complete\n');
1466
1532
  };
1467
1533
  const result = await msgSend({ from, to, body, encrypt, thread, returnPolicy: returnPolicyRaw, handoffContext: getArgValue(args, '--handoff-context'), onUploadProgress, ...commonOpts });
1468
1534
  if (!result.ok) {
@@ -1633,6 +1699,23 @@ export async function cmdGroup(args) {
1633
1699
  const aunPath = resolveAunPath(args);
1634
1700
  const formatJson = getArgValue(args, '--format') === 'json';
1635
1701
  const appSlot = getArgValue(args, '--app');
1702
+ if (sub === 'history' && wantsHelp(args)) {
1703
+ console.log(`用法: ec group history <self-aid> <group-aid> --unread|--all [options]
1704
+ 本地 messages.jsonl 查询,不访问 Gateway,不推进 group pull/ack 游标。
1705
+ --unread 返回最早未读的未提及背景,并自动记录本页已读
1706
+ --all 浏览群会话历史(返回最近 N 条),不改变已读状态
1707
+ --limit <N> 默认 50,范围 1–500;另有 24 KiB 单页消息预算
1708
+ --thread <main|all|id> 当前群任务缺省继承当前话题;其他调用缺省 all
1709
+ --direction <in|out|all> 按方向筛选,默认 all
1710
+ --before/--after <time> 按接收时间筛选,开区间;epoch 毫秒或 ISO 时间
1711
+ --format <text|json> 默认 text
1712
+ --message <msg-id> 配合 --all 查看指定长消息正文
1713
+ --offset <bytes> 配合 --message 从 next_offset 继续读取,默认 0
1714
+ --unread 返回的消息会记为已读;--all(包括 --all --message)始终只读,之后仍可回看。
1715
+ visitor 不开放历史;群权限仍由托管会话校验。
1716
+ 旧日志通过 --all 查询,只有带本地未提及标记的新记录参与 --unread。`);
1717
+ return;
1718
+ }
1636
1719
  const rulesActionHelp = sub === 'rules' && isHelpFlag(args[3]);
1637
1720
  if (!sub || isHelpFlag(sub) || (wantsHelp(args) && !rulesActionHelp)) {
1638
1721
  console.log(`用法: ec group <command> <from-aid> [args...] [options]
@@ -1643,6 +1726,7 @@ export async function cmdGroup(args) {
1643
1726
  send <from> <group-id> --payload <json> 发送自定义 payload
1644
1727
  pull <from> <group-id> [--after-seq N] [--limit N] --app <name> 拉取群消息(必须使用独立 slot)
1645
1728
  ack <from> <group-id> <seq> [--app <name>] 确认已读
1729
+ history <from> <group-id> [--unread|--all] 查询本地群消息历史
1646
1730
 
1647
1731
  群管理:
1648
1732
  create <from> <name> [--visibility public|private] [--description D]
@@ -1673,6 +1757,11 @@ export async function cmdGroup(args) {
1673
1757
  owner <from> <group-id> <new-owner-aid> 转让群主
1674
1758
  ban <from> <group-id> [<member-aid>] [--duration N] 封禁成员;不带 member-aid 时列出封禁
1675
1759
  unban <from> <group-id> <member-aid> 解封成员
1760
+ block <from> <group-id> <member-aid> [--reason R] 屏蔽成员接收群消息
1761
+ unblock <from> <group-id> <member-aid> 取消屏蔽
1762
+ blocklist <from> <group-id> 查看屏蔽列表(群管理员)
1763
+ report-status <from> <group-id> --online-status O --work-status W 上报自己的状态
1764
+ member-statuses <from> <group-id> 查看成员上报状态(独立于 online)
1676
1765
 
1677
1766
  Options:
1678
1767
  --app <name> 指定应用 slot(独立消费通道,不影响 daemon)
@@ -1688,7 +1777,7 @@ Options:
1688
1777
  --as <type> 附件类型:image|video|voice|file(仅 --file 模式)
1689
1778
  --text <说明> 附件说明文字(仅 --file 模式)
1690
1779
  --transcript <text> 语音转写(仅 --as voice)
1691
- --group-id <aid> 指定自定义群 AID(仅 create)
1780
+ --group-id <aid> 指定自定义群 AID(仅 create);省略时生成 g- 加五位随机数字
1692
1781
  --member-type <type> 定向邀请成员类型:human|agent(仅 invite)
1693
1782
  -- end-of-options:其后所有参数按正文处理
1694
1783
  (用于发送恰好等于某 flag 的文本,如 send a g -- --encrypt)
@@ -1703,7 +1792,11 @@ Options:
1703
1792
  ec group members sender.example.invalid 12345.example.invalid
1704
1793
 
1705
1794
  查询真实群 AID:
1706
- ec group list <发送方AID>`);
1795
+ ec group list <发送方AID>
1796
+
1797
+ 群 AID 使用 base.issuer(如 ontology.example.invalid、g-12345.example.invalid)。
1798
+ 群命令支持本域 base 简写;不再支持 group.issuer/base 或 base@issuer。
1799
+ g- 是名称的一部分,会完整保留;默认命名格式为 g-10000 至 g-99999。`);
1707
1800
  return;
1708
1801
  }
1709
1802
  const from = args[1];
@@ -1720,13 +1813,55 @@ Options:
1720
1813
  printGroupSendAidHint();
1721
1814
  process.exit(1);
1722
1815
  }
1723
- if (process.env.EVOLCORE_SESSION_ID && sub !== 'send') {
1816
+ if ((process.env.EVOLCORE_SESSION_ID || (sub === 'history' && readDelegationCredential())) && sub !== 'send') {
1724
1817
  const result = await runManagedGroup(args, formatJson);
1725
1818
  renderManagedGroupResult(args, result, formatJson);
1726
1819
  return;
1727
1820
  }
1728
- const { groupSend, groupPull, groupAck, groupCreate, groupInfo, groupList, groupUpdate, groupDissolve, groupSuspend, groupResume, groupJoin, groupLeave, groupInvite, groupInvites, groupAcceptInvite, groupRejectInvite, groupRevokeInvite, groupKick, groupMembers, groupOnline, groupSetRole, groupTransferOwner, groupBan, groupUnban, groupBanlist, groupRules, groupUpdateRules, groupRulesFileGet, groupRulesFileSet, groupRulesFilePublish, } = await import('../aun/msg/index.js');
1821
+ const { groupSend, groupPull, groupAck, groupHistory, parseGroupHistoryArgs, groupCreate, groupInfo, groupList, groupUpdate, groupDissolve, groupSuspend, groupResume, groupJoin, groupLeave, groupInvite, groupInvites, groupAcceptInvite, groupRejectInvite, groupRevokeInvite, groupKick, groupMembers, groupOnline, groupSetRole, groupTransferOwner, groupBan, groupUnban, groupBanlist, groupBlock, groupUnblock, groupBlocklist, groupReportStatus, groupMemberStatuses, groupRules, groupUpdateRules, groupRulesFileGet, groupRulesFileSet, groupRulesFilePublish, } = await import('../aun/msg/index.js');
1729
1822
  const commonOpts = { aunPath, slotId: appSlot };
1823
+ if (['block', 'unblock', 'blocklist', 'report-status', 'member-statuses'].includes(sub)) {
1824
+ // Share validation with the daemon; standalone connection options stay local.
1825
+ const operationArgs = [];
1826
+ for (let i = 0; i < args.length; i++) {
1827
+ if (args[i] === '--aun-path' || args[i] === '--app') {
1828
+ if (args[i + 1] === undefined || args[i + 1].startsWith('--')) {
1829
+ failManagedGroup(formatJson, 'INVALID_ARGUMENT', `${args[i]} requires a value`);
1830
+ }
1831
+ i++;
1832
+ }
1833
+ else {
1834
+ operationArgs.push(args[i]);
1835
+ }
1836
+ }
1837
+ const { resolveManagedGroupOperation } = await import('../aun/msg/managed-operation.js');
1838
+ const parsed = resolveManagedGroupOperation(operationArgs);
1839
+ if (!parsed.ok)
1840
+ failManagedGroup(formatJson, parsed.code, parsed.reason);
1841
+ const command = parsed.command;
1842
+ const base = { from: command.from, groupId: command.groupId, ...commonOpts };
1843
+ let result;
1844
+ switch (sub) {
1845
+ case 'block':
1846
+ result = await groupBlock({ ...base, memberAid: command.memberAid, reason: command.reason });
1847
+ break;
1848
+ case 'unblock':
1849
+ result = await groupUnblock({ ...base, memberAid: command.memberAid });
1850
+ break;
1851
+ case 'blocklist':
1852
+ result = await groupBlocklist(base);
1853
+ break;
1854
+ case 'report-status':
1855
+ result = await groupReportStatus({ ...base, onlineStatus: command.onlineStatus, workStatus: command.workStatus });
1856
+ break;
1857
+ default:
1858
+ result = await groupMemberStatuses(base);
1859
+ }
1860
+ if (!result.ok)
1861
+ failManagedGroup(formatJson, result.code ?? 'GROUP_OPERATION_FAILED', result.error);
1862
+ renderManagedGroupResult(operationArgs, result, formatJson);
1863
+ return;
1864
+ }
1730
1865
  // 通用 group_id 提取(第三参数)
1731
1866
  const requireGroupId = () => {
1732
1867
  const gid = args[2];
@@ -1735,12 +1870,14 @@ Options:
1735
1870
  printGroupSendAidHint();
1736
1871
  process.exit(1);
1737
1872
  }
1738
- if (!isExplicitGroupId(gid)) {
1739
- console.error(`❌ 第 2 个位置参数 <group-aid> 不是有效群 AID: ${gid}`);
1873
+ try {
1874
+ return normalizeGroupAid(gid, from.slice(from.indexOf('.') + 1));
1875
+ }
1876
+ catch (error) {
1877
+ console.error(`❌ 第 2 个位置参数 <group-aid> 不是有效群 AID: ${gid}: ${error.message}`);
1740
1878
  printGroupSendAidHint();
1741
1879
  process.exit(1);
1742
1880
  }
1743
- return gid;
1744
1881
  };
1745
1882
  // 收集 --mention(可多次;每次的值支持逗号分隔多个 aid)
1746
1883
  const collectMentions = () => {
@@ -1853,6 +1990,16 @@ Options:
1853
1990
  return parts.join(' ');
1854
1991
  };
1855
1992
  // ---- 消息 ----
1993
+ if (sub === 'history') {
1994
+ try {
1995
+ const result = groupHistory(parseGroupHistoryArgs(args));
1996
+ renderManagedGroupResult(args, result, formatJson);
1997
+ }
1998
+ catch (error) {
1999
+ failManagedGroup(formatJson, error.code || 'HISTORY_READ_FAILED', error instanceof Error ? error.message : String(error));
2000
+ }
2001
+ return;
2002
+ }
1856
2003
  if (sub === 'send') {
1857
2004
  const groupId = requireGroupId();
1858
2005
  // Group sends use the dedicated AUN message daemon route rather than the
@@ -2050,9 +2197,11 @@ Options:
2050
2197
  });
2051
2198
  outputResult(result, () => {
2052
2199
  const r = result;
2053
- console.log(`✓ 已创建群 ${r.group?.group_id}`);
2200
+ console.log(`✓ 已创建群 ${r.group?.group_aid ?? r.group?.group_id}`);
2054
2201
  console.log(` 名称: ${r.group?.name}`);
2055
2202
  console.log(` 可见性: ${r.group?.visibility}`);
2203
+ if (r.warning)
2204
+ console.warn(r.warning);
2056
2205
  });
2057
2206
  return;
2058
2207
  }
@@ -2450,7 +2599,7 @@ Options:
2450
2599
  });
2451
2600
  return;
2452
2601
  }
2453
- console.error(`未知子命令: ${sub}\n用法: ec group [send|pull|ack|create|list|info|update|dissolve|suspend|resume|rules|join|leave|invite|invites|accept-invite|reject-invite|revoke-invite|kick|members|online|role|owner|ban|unban]`);
2602
+ console.error(`未知子命令: ${sub}\n用法: ec group [send|pull|ack|history|create|list|info|update|dissolve|suspend|resume|rules|join|leave|invite|invites|accept-invite|reject-invite|revoke-invite|kick|members|online|role|owner|ban|unban|block|unblock|blocklist|report-status|member-statuses]`);
2454
2603
  process.exit(1);
2455
2604
  }
2456
2605
  // ==================== Main ====================
@@ -4,7 +4,7 @@ import { resolveConfigCommand } from '../config/resolved-config-op.js';
4
4
  import { AUTHENTICATED_CONFIG_ROLE_ENV, executeResolvedConfigCommandAsync, } from '../config/config-operation-service.js';
5
5
  import { ipcQuery } from '../ipc.js';
6
6
  import { resolvePaths } from '../paths.js';
7
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
7
+ import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
8
8
  import { splitConfigBatchGetArgv } from './cli-argv.js';
9
9
  function emit(formatJson, payload, text) {
10
10
  if (formatJson)
@@ -128,7 +128,7 @@ function managedSession(formatJson) {
128
128
  const sessionId = process.env.EVOLCORE_SESSION_ID;
129
129
  if (!sessionId)
130
130
  fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
131
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
131
+ const delegationToken = readDelegationCredential();
132
132
  if (!delegationToken) {
133
133
  fail(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`);
134
134
  }
@@ -158,10 +158,13 @@ async function runManagedConfig(args, formatJson) {
158
158
  renderConfigExecution(response.result, formatJson);
159
159
  }
160
160
  function renderBatchGet(results, formatJson) {
161
- const allOk = results.every(entry => entry.ok);
161
+ // Unsupported runner fields are compatibility misses, not a failure of the
162
+ // supported fields in the same aggregate request. Keep the per-field error
163
+ // while allowing clients to consume the successful values.
164
+ const batchOk = results.every(entry => entry.ok || entry.code === 'UNSUPPORTED_FIELD');
162
165
  if (formatJson) {
163
166
  console.log(JSON.stringify({
164
- ok: allOk,
167
+ ok: batchOk,
165
168
  results: results.map(entry => entry.ok
166
169
  ? getResultPayload(entry)
167
170
  : { ok: false, field: entry.field, code: entry.code, error: entry.error }),
@@ -175,7 +178,7 @@ function renderBatchGet(results, formatJson) {
175
178
  console.error(`${entry.field}: Error: ${entry.error} (${entry.code})`);
176
179
  }
177
180
  }
178
- if (!allOk)
181
+ if (!batchOk)
179
182
  process.exit(1);
180
183
  }
181
184
  async function runDirectBatchGet(fields, rest, formatJson) {
@@ -2,7 +2,7 @@ import { resolvePaths } from '../paths.js';
2
2
  import { loadAllAgents } from '../config-store.js';
3
3
  import { executeResolvedContactCommand, resolveContactCommand, } from '../config/contact-operation-service.js';
4
4
  import { ipcQuery } from '../ipc.js';
5
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
5
+ import { AGENT_DELEGATION_TOKEN_ENV, readDelegationCredential } from '../core/auth/agent-delegation.js';
6
6
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
7
7
  export async function cmdContact(args) {
8
8
  if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
@@ -39,7 +39,7 @@ function output(value, json) {
39
39
  }
40
40
  async function runManaged(args, json) {
41
41
  const sessionId = process.env.EVOLCORE_SESSION_ID;
42
- const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
42
+ const delegationToken = readDelegationCredential();
43
43
  if (!delegationToken)
44
44
  fail(`${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task`, 'DELEGATION_REQUIRED');
45
45
  let response = null;
@@ -1,7 +1,7 @@
1
1
  import { resolvePaths } from '../paths.js';
2
2
  import { ipcQuery } from '../ipc.js';
3
3
  import { isHelpFlag, wantsHelp } from './help.js';
4
- import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
4
+ import { readDelegationCredential } from '../core/auth/agent-delegation.js';
5
5
  // ==================== Ctl ====================
6
6
  const CTL_HELP = `用法: ec ctl <command> [args...]
7
7
 
@@ -47,7 +47,7 @@ export async function cmdCtl(args) {
47
47
  type: 'ctl',
48
48
  cmd,
49
49
  sessionId,
50
- delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
50
+ delegationToken: readDelegationCredential(),
51
51
  }, 10_000);
52
52
  if (!result) {
53
53
  console.error('错误: 无法连接 evolcore 服务');