evolcore 0.0.11 → 0.0.13

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 (164) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/bin/codex-managed-hook.mjs +80 -0
  3. package/bin/ec-safe-output.js +26 -7
  4. package/dist/agents/claude-runner.js +86 -7
  5. package/dist/agents/codex-app-server-client.js +174 -20
  6. package/dist/agents/codex-runner.js +375 -92
  7. package/dist/agents/ecagent-runner.js +39 -4
  8. package/dist/agents/gemini-runner.js +1 -0
  9. package/dist/aun/aid/client.js +11 -21
  10. package/dist/aun/aid/control-aid.js +36 -13
  11. package/dist/aun/aid/managed-operation.js +107 -0
  12. package/dist/aun/aid/store.js +13 -7
  13. package/dist/aun/group-fs-download.js +56 -0
  14. package/dist/aun/group-identity.js +1 -2
  15. package/dist/aun/msg/group.js +91 -44
  16. package/dist/aun/msg/index.js +1 -2
  17. package/dist/aun/msg/managed-operation.js +865 -0
  18. package/dist/aun/msg/mention-schema.js +20 -0
  19. package/dist/aun/msg/p2p.js +7 -0
  20. package/dist/aun/msg/upload.js +16 -1
  21. package/dist/aun/outbox.js +31 -2
  22. package/dist/aun/rpc/client.js +66 -0
  23. package/dist/aun/rpc/index.js +1 -2
  24. package/dist/aun/storage/{upload.js → client.js} +11 -2
  25. package/dist/aun/storage/index.js +1 -2
  26. package/dist/channels/aun.js +655 -240
  27. package/dist/channels/daemon.js +13 -0
  28. package/dist/cli/agent-command.js +56 -8
  29. package/dist/cli/agent.js +108 -31
  30. package/dist/cli/aun-commands.js +270 -69
  31. package/dist/cli/bench.js +12 -3
  32. package/dist/cli/cli-argv.js +10 -0
  33. package/dist/cli/config.js +9 -17
  34. package/dist/cli/ctl-command.js +1 -1
  35. package/dist/cli/daemon-commands.js +70 -55
  36. package/dist/cli/fs-command.js +79 -10
  37. package/dist/cli/handoff-command.js +3 -0
  38. package/dist/cli/index.js +30 -2
  39. package/dist/cli/init.js +77 -8
  40. package/dist/cli/managed-command-guard.js +41 -0
  41. package/dist/cli/model.js +11 -4
  42. package/dist/cli/queue-command.js +53 -1
  43. package/dist/cli/response.js +71 -0
  44. package/dist/cli/restart-monitor.js +7 -32
  45. package/dist/cli/trigger-command.js +11 -0
  46. package/dist/config/access-policy.js +1 -2
  47. package/dist/config/builtin-roles.js +9 -0
  48. package/dist/config/config-manager.js +21 -1
  49. package/dist/config/contact-book-store.js +11 -3
  50. package/dist/config/contact-request-service.js +161 -15
  51. package/dist/config/mention-mode.js +8 -24
  52. package/dist/config/peer-role-resolver.js +6 -2
  53. package/dist/config/role-migration-startup.js +53 -0
  54. package/dist/config/role-store.js +1 -1
  55. package/dist/core/auth/agent-delegation.js +1 -2
  56. package/dist/core/auth/auth-gateway.js +29 -1
  57. package/dist/core/auth/authorization-audit.js +15 -0
  58. package/dist/core/auth/operation-authorizer.js +31 -7
  59. package/dist/core/auth/operation-catalog.js +196 -25
  60. package/dist/core/bootstrap-messages.js +25 -0
  61. package/dist/core/bootstrap-service.js +64 -4
  62. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  63. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  64. package/dist/core/capability/skill-discovery.js +55 -0
  65. package/dist/core/channel-loader.js +1 -1
  66. package/dist/core/command/cli-intent-parser.js +9 -0
  67. package/dist/core/command/command-handler.js +650 -42
  68. package/dist/core/command/connect-menu.js +15 -0
  69. package/dist/core/command/group-menu.js +4 -4
  70. package/dist/core/command/menu-catalog.js +370 -0
  71. package/dist/core/command/menu-handler.js +230 -51
  72. package/dist/core/command/menu-protocol.js +94 -2
  73. package/dist/core/command/slash-gate.js +5 -2
  74. package/dist/core/command/slash-handler.js +99 -31
  75. package/dist/core/daemon-file-cache.js +2 -1
  76. package/dist/core/data-migration.js +9 -2
  77. package/dist/core/event-catalog.js +6 -0
  78. package/dist/core/evolagent.js +4 -2
  79. package/dist/core/handoff/dispatcher.js +5 -2
  80. package/dist/core/handoff/runtime.js +157 -22
  81. package/dist/core/handoff/store.js +29 -1
  82. package/dist/core/handoff/types.js +1 -0
  83. package/dist/core/interaction-router.js +10 -0
  84. package/dist/core/message/im-renderer.js +19 -0
  85. package/dist/core/message/logical-queue-bridge.js +1 -0
  86. package/dist/core/message/mention-schema.js +126 -0
  87. package/dist/core/message/message-bridge.js +298 -88
  88. package/dist/core/message/message-log.js +3 -0
  89. package/dist/core/message/message-queue.js +268 -39
  90. package/dist/core/message/message-utils.js +81 -4
  91. package/dist/core/message/response-engine.js +161 -77
  92. package/dist/core/message/stream-debouncer.js +10 -2
  93. package/dist/core/permission/approval-gateway.js +1 -0
  94. package/dist/core/permission/ec-command-parser.js +243 -18
  95. package/dist/core/permission/index.js +1 -1
  96. package/dist/core/permission/mode.js +15 -0
  97. package/dist/core/permission/readonly-shell-query.js +148 -8
  98. package/dist/core/permission/sandbox-runtime.js +43 -1
  99. package/dist/core/permission/tool-policy.js +322 -57
  100. package/dist/core/protected-paths.js +114 -4
  101. package/dist/core/session/session-manager.js +42 -4
  102. package/dist/core/session/session-mapper.js +20 -1
  103. package/dist/eck/detect.js +18 -1
  104. package/dist/eck/group-rules-sync.js +15 -44
  105. package/dist/eck/manifest-engine.js +39 -13
  106. package/dist/index.js +541 -180
  107. package/dist/ipc.js +232 -10
  108. package/dist/paths.js +3 -0
  109. package/dist/response-system/coordinator.js +6 -4
  110. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  111. package/dist/response-system/modes/single-session/index.js +14 -1
  112. package/dist/response-system/selector.js +6 -5
  113. package/dist/trigger/anomaly-store.js +4 -0
  114. package/dist/trigger/feedback.js +64 -11
  115. package/dist/trigger/manager.js +21 -1
  116. package/dist/trigger/parser.js +14 -2
  117. package/dist/trigger/scheduler.js +1 -0
  118. package/dist/trigger/script-executor.js +1 -0
  119. package/dist/trigger/validation.js +67 -6
  120. package/dist/utils/codex-app-server-registry.js +90 -0
  121. package/dist/utils/codex-cli.js +5 -1
  122. package/dist/utils/cross-platform.js +15 -0
  123. package/dist/utils/ecweb-supervisor.js +332 -0
  124. package/dist/utils/error-utils.js +10 -0
  125. package/dist/utils/npm-ops.js +5 -12
  126. package/dist/utils/tool-summary.js +11 -0
  127. package/kits/docs/channels/aun.md +1 -1
  128. package/kits/docs/context-assembly.md +2 -2
  129. package/kits/docs/evolcore/agent.md +11 -6
  130. package/kits/docs/evolcore/aid.md +14 -0
  131. package/kits/docs/evolcore/trigger.md +17 -1
  132. package/kits/docs/prompt-loading-architecture.md +1 -2
  133. package/kits/docs/venues/group.md +1 -1
  134. package/kits/eck_manifest.json +0 -12
  135. package/kits/migrations/migrate-contact-book-v2.mjs +1 -2
  136. package/kits/rules/04-relation.md +1 -1
  137. package/kits/rules/05-venue.md +2 -2
  138. package/kits/schemas/role-config.schema.1.json +1 -0
  139. package/kits/schemas/single-session.schema.1.json +3 -3
  140. package/kits/schemas/single-session.schema.2.json +3 -3
  141. package/kits/templates/roles/admin.json +27 -0
  142. package/kits/templates/roles/member.json +34 -1
  143. package/kits/templates/roles/visitor.json +35 -3
  144. package/kits/templates/system-fragments/bootstrap.md +1 -1
  145. package/kits/templates/system-fragments/channel.md +1 -1
  146. package/kits/templates/system-fragments/session.md +1 -1
  147. package/package.json +2 -2
  148. package/dist/aun/msg/payload-type.js +0 -27
  149. package/dist/aun/rpc/caller.js +0 -42
  150. package/dist/aun/rpc/connection.js +0 -25
  151. package/dist/aun/storage/manage.js +0 -10
  152. package/dist/config/access-policy-domain.js +0 -18
  153. package/dist/config/config-batch-get.js +0 -11
  154. package/dist/config/owner-policy.js +0 -4
  155. package/dist/config/role-config-v4-startup.js +0 -32
  156. package/dist/config/role-config-v5-startup.js +0 -27
  157. package/dist/core/auth/trigger-authorization.js +0 -15
  158. package/dist/core/command/evol-menu-version-gate.js +0 -39
  159. package/dist/core/interaction-registration.js +0 -10
  160. package/dist/core/permission/execution-sandbox.js +0 -16
  161. package/dist/core/relation/peer-key.js +0 -1
  162. package/dist/core/session/session-key.js +0 -24
  163. package/dist/eck/baseagent-caps.js +0 -18
  164. package/dist/eck/rules-loader.js +0 -28
@@ -415,7 +415,11 @@ function normalizeExecutionAnomaly(value) {
415
415
  : Date.now();
416
416
  const toolName = nonEmptyString(value.toolName);
417
417
  const requestId = nonEmptyString(value.requestId);
418
+ const policyCode = nonEmptyString(value.policyCode);
418
419
  const policy = normalizeApproverPolicy(value.policy);
420
+ const agentAid = nonEmptyString(value.agentAid);
421
+ const sessionId = nonEmptyString(value.sessionId);
422
+ const permissionMode = normalizePermissionMode(value.permissionMode);
419
423
  const summary = nonEmptyString(value.summary);
420
424
  return {
421
425
  code: code,
@@ -425,7 +429,11 @@ function normalizeExecutionAnomaly(value) {
425
429
  effect,
426
430
  ...(toolName ? { toolName } : {}),
427
431
  ...(requestId ? { requestId } : {}),
432
+ ...(policyCode ? { policyCode } : {}),
428
433
  ...(policy ? { policy } : {}),
434
+ ...(agentAid ? { agentAid } : {}),
435
+ ...(sessionId ? { sessionId } : {}),
436
+ ...(permissionMode ? { permissionMode } : {}),
429
437
  ...(summary ? { summary: summary.slice(0, 512) } : {}),
430
438
  };
431
439
  }
@@ -437,3 +445,8 @@ function normalizeApproverPolicy(value) {
437
445
  ? value
438
446
  : undefined;
439
447
  }
448
+ function normalizePermissionMode(value) {
449
+ return value === 'readonly' || value === 'auto' || value === 'request' || value === 'bypass'
450
+ ? value
451
+ : undefined;
452
+ }
@@ -59,6 +59,13 @@ Options:
59
59
  ec agent delete mybot.agentid.pub --purge`);
60
60
  return;
61
61
  }
62
+ if (process.env.EVOLCORE_SESSION_ID && !wantsHelp(args) && !new Set(['get', 'set', 'ready']).has(sub)) {
63
+ if (formatJson)
64
+ console.log(JSON.stringify({ ok: false, code: 'NOT_ALLOWED', error: `agent ${sub} is not available in a managed task` }));
65
+ else
66
+ console.error(`❌ [NOT_ALLOWED] agent ${sub} is not available in a managed task`);
67
+ process.exit(1);
68
+ }
62
69
  const { agentList, agentShow, agentCreateInteractive, agentCreateNonInteractive, agentReload, agentEnable, agentDisable, agentGet, agentSet, agentRename, agentDelete, agentReady, } = await import('./agent.js');
63
70
  // --- list ---
64
71
  if (sub === 'list') {
@@ -137,17 +144,21 @@ Options:
137
144
  ec agent new <aid> --non-interactive [选项]
138
145
 
139
146
  非交互模式选项:
140
- --baseagent <claude|codex|gemini|ecagent> 默认: PATH 中第一个可用;ecagent 需显式选择
141
- --project <absolute path> 必填
142
- --owner <aid>
143
- --name <display-name>
144
- --description <text>
147
+ --project <path> 默认: 当前目录
148
+ --baseagent <claude|codex|gemini|ecagent>
149
+ 默认: defaults 配置,否则检测本机可用基座
150
+ --owner <aid> 默认: daemon.json 第一个 owner
151
+ --name <display-name> 默认: package.json name,否则目录名
152
+ --description <text> 默认: package.json description,否则留空
153
+ --dry-run 只预览最终参数,不注册 AID、不写文件
145
154
  --force 覆盖已有 config.json
146
155
  --format json 输出 JSON
147
156
 
148
157
  示例:
149
158
  ec agent new mybot.agentid.pub
150
- ec agent new mybot.agentid.pub --non-interactive --project /abs/path --baseagent claude`);
159
+ ec agent new mybot.agentid.pub --non-interactive
160
+ ec agent new mybot.agentid.pub --non-interactive --dry-run --format json
161
+ ec agent new mybot.agentid.pub --non-interactive --project ../project --baseagent claude`);
151
162
  return;
152
163
  }
153
164
  const name = args[1];
@@ -161,15 +172,52 @@ Options:
161
172
  const idx = args.indexOf(flag);
162
173
  return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : undefined;
163
174
  };
164
- const result = await agentCreateNonInteractive({
175
+ const { resolveAgentCreatePlan, validateAgentCreatePlan } = await import('./agent.js');
176
+ const plan = resolveAgentCreatePlan({
165
177
  aid: name,
178
+ project: getArg('--project'),
166
179
  baseagent: getArg('--baseagent'),
167
- project: getArg('--project') || '',
168
180
  owner: getArg('--owner'),
169
181
  name: getArg('--name'),
170
182
  description: getArg('--description'),
171
183
  force: args.includes('--force'),
172
184
  });
185
+ const validationError = validateAgentCreatePlan(plan);
186
+ if (validationError) {
187
+ const error = { ok: false, error: validationError };
188
+ if (formatJson)
189
+ console.log(JSON.stringify(error));
190
+ else
191
+ console.error(`❌ ${error.error}`);
192
+ process.exitCode = 1;
193
+ return;
194
+ }
195
+ if (args.includes('--dry-run')) {
196
+ const preview = { ok: true, dryRun: true, plan };
197
+ if (formatJson)
198
+ console.log(JSON.stringify(preview, null, 2));
199
+ else {
200
+ console.log('EvolAgent 创建计划(dry-run)');
201
+ console.log(` AID: ${plan.aid}`);
202
+ console.log(` Project: ${plan.project}`);
203
+ console.log(` Baseagent: ${plan.baseagent} (${plan.baseagentSource})`);
204
+ console.log(` Owner: ${plan.owner || '未设置'} (${plan.ownerSource})`);
205
+ console.log(` Name: ${plan.name} (${plan.nameSource})`);
206
+ if (plan.description)
207
+ console.log(` Description: ${plan.description} (${plan.descriptionSource})`);
208
+ console.log(` Existing config: ${plan.configExists ? (plan.force ? '将覆盖' : '是') : '否'}`);
209
+ }
210
+ return;
211
+ }
212
+ const result = await agentCreateNonInteractive({
213
+ aid: plan.aid,
214
+ baseagent: plan.baseagent,
215
+ project: plan.project,
216
+ owner: plan.owner,
217
+ name: plan.name,
218
+ description: plan.description,
219
+ force: args.includes('--force'),
220
+ });
173
221
  if (!result.ok) {
174
222
  if (formatJson) {
175
223
  console.log(JSON.stringify(result));
package/dist/cli/agent.js CHANGED
@@ -2,14 +2,12 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import readline from 'readline';
4
4
  import { resolvePaths, agentMdPath as getAgentMdPathFromPaths, aunPath as defaultAunPath } from '../paths.js';
5
- import { loadDefaults, loadAllAgents, loadAgent, saveAgent, ensureAgentDirSkeleton } from '../config-store.js';
5
+ import { loadDefaults, loadAllAgents, loadAgent, saveAgent, ensureAgentDirSkeleton, loadDaemonConfig } from '../config-store.js';
6
6
  import { ConfigTarget, write as cfgWrite, ensureFile as cfgEnsure, read as cfgRead, initConfigManager } from '../config/config-manager.js';
7
7
  import { resolveConfigCommand } from '../config/resolved-config-op.js';
8
8
  import { executeResolvedConfigCommand } from '../config/config-operation-service.js';
9
9
  import { ipcQuery } from '../ipc.js';
10
10
  import { CONFIG_SCHEMA_VERSION } from '../types.js';
11
- import { normalizeAgentLifecycle, withLifecycleForWrite } from '../config/lifecycle.js';
12
- import { preparePostBootstrapWelcomeOutbox } from '../core/bootstrap-messages.js';
13
11
  import { ensureInitialRoleRegistry } from '../config/role-service.js';
14
12
  import { isValidChannelName } from '../core/channel-loader.js';
15
13
  import { commandExists } from '../utils/cross-platform.js';
@@ -18,6 +16,7 @@ import { resolveEcagentConfig } from '../agents/baseagent.js';
18
16
  import { agentProjectRootFromDefaults, deriveAgentProjectPath } from '../utils/project-path.js';
19
17
  import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
20
18
  import { readTaskRuntimeContextFromEnv } from './task-context.js';
19
+ import { isValidAid } from '../aun/aid/validation.js';
21
20
  function withStaticOwner(config, owner) {
22
21
  const value = owner?.trim();
23
22
  if (!value)
@@ -43,6 +42,100 @@ function detectAvailableBaseagents() {
43
42
  function pickDefaultBaseagent(available) {
44
43
  return AUTO_BASEAGENT_CANDIDATES.find(candidate => available.includes(candidate)) ?? null;
45
44
  }
45
+ function readProjectMetadata(project) {
46
+ try {
47
+ const packageJsonPath = path.join(project, 'package.json');
48
+ if (!fs.existsSync(packageJsonPath))
49
+ return {};
50
+ const parsed = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
51
+ return {
52
+ name: typeof parsed.name === 'string' ? parsed.name.trim() : undefined,
53
+ description: typeof parsed.description === 'string' ? parsed.description.trim() : undefined,
54
+ };
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ function projectSlug(project) {
61
+ const basename = path.basename(project) || 'agent';
62
+ const slug = basename
63
+ .normalize('NFKD')
64
+ .replace(/[^a-zA-Z0-9-]+/g, '-')
65
+ .replace(/^-+|-+$/g, '')
66
+ .toLowerCase()
67
+ .slice(0, 63)
68
+ .replace(/-+$/g, '');
69
+ return slug || 'agent';
70
+ }
71
+ /**
72
+ * Resolve non-interactive creation defaults without performing any network or
73
+ * filesystem mutation. The CLI uses this for both execution and --dry-run.
74
+ */
75
+ export function resolveAgentCreatePlan(options) {
76
+ const aid = options.aid.trim();
77
+ const project = path.resolve(options.project || process.cwd());
78
+ const metadata = readProjectMetadata(project);
79
+ const defaults = loadDefaults();
80
+ const daemon = loadDaemonConfig();
81
+ const configuredBaseagent = defaults?.active_baseagent;
82
+ const available = detectAvailableBaseagents();
83
+ const defaultBaseagent = configuredBaseagent && available.includes(configuredBaseagent)
84
+ ? configuredBaseagent
85
+ : pickDefaultBaseagent(available) ?? undefined;
86
+ const baseagent = options.baseagent || defaultBaseagent;
87
+ const baseagentSource = options.baseagent
88
+ ? 'argument'
89
+ : configuredBaseagent && baseagent === configuredBaseagent
90
+ ? 'defaults'
91
+ : 'detected';
92
+ const owner = options.owner?.trim() || daemon.owners?.[0];
93
+ const ownerSource = options.owner?.trim() ? 'argument' : owner ? 'daemon' : 'none';
94
+ const name = options.name?.trim() || metadata.name || projectSlug(project);
95
+ const description = options.description?.trim() || metadata.description || '';
96
+ const configExists = isValidAid(aid)
97
+ && fs.existsSync(path.join(resolvePaths().agentsDir, aid, 'config.json'));
98
+ return {
99
+ aid,
100
+ project,
101
+ baseagent,
102
+ owner,
103
+ name,
104
+ description,
105
+ force: options.force === true,
106
+ configExists,
107
+ baseagentSource,
108
+ ownerSource,
109
+ nameSource: options.name?.trim() ? 'argument' : metadata.name ? 'package' : 'directory',
110
+ descriptionSource: options.description?.trim() ? 'argument' : metadata.description ? 'package' : 'none',
111
+ };
112
+ }
113
+ export function validateAgentCreatePlan(plan) {
114
+ if (!isValidAid(plan.aid)) {
115
+ return `Invalid AID "${plan.aid}": must be a valid multi-level domain (e.g. mybot.agentid.pub)`;
116
+ }
117
+ if (plan.configExists && !plan.force) {
118
+ return `Agent "${plan.aid}" already exists (use --force to overwrite)`;
119
+ }
120
+ if (!plan.baseagent) {
121
+ return 'No usable baseagent detected. Pass --baseagent or configure a baseagent in agents/defaults.json.';
122
+ }
123
+ if (!BASEAGENT_CANDIDATES.includes(plan.baseagent)) {
124
+ return `Invalid baseagent: ${plan.baseagent} (options: ${BASEAGENT_CANDIDATES.join('/')})`;
125
+ }
126
+ if (!isBaseagentAvailable(plan.baseagent)) {
127
+ return `${plan.baseagent} is not available in the current environment`;
128
+ }
129
+ if (plan.baseagent === 'ecagent') {
130
+ const reason = ecagentUnavailableReason();
131
+ if (reason)
132
+ return reason;
133
+ }
134
+ if (plan.owner && !isValidAid(plan.owner)) {
135
+ return `Invalid owner: ${plan.owner}`;
136
+ }
137
+ return null;
138
+ }
46
139
  function ecagentUnavailableReason() {
47
140
  try {
48
141
  resolveEcagentConfig({ agents: { ecagent: {} } });
@@ -1100,7 +1193,8 @@ export async function agentRename(aid, name) {
1100
1193
  }
1101
1194
  // ==================== agentReady ====================
1102
1195
  export async function agentReady(aid) {
1103
- const taskSelfAid = readTaskRuntimeContextFromEnv()?.selfAid;
1196
+ const managedSessionId = process.env.EVOLCORE_SESSION_ID;
1197
+ const taskSelfAid = managedSessionId ? readTaskRuntimeContextFromEnv()?.selfAid : undefined;
1104
1198
  if (taskSelfAid && taskSelfAid.replace(/^@/, '') !== aid.replace(/^@/, '')) {
1105
1199
  return {
1106
1200
  ok: false,
@@ -1109,35 +1203,18 @@ export async function agentReady(aid) {
1109
1203
  };
1110
1204
  }
1111
1205
  const p = resolvePaths();
1112
- const config = loadAgent(aid);
1113
- if (!config)
1114
- return { ok: false, error: `Agent "${aid}" not found` };
1115
1206
  try {
1116
- const result = await ipcQuery(p.socket, { type: 'evolagent.bootstrapComplete', aid }, 30_000);
1117
- if (!result) {
1118
- const offlineConfig = loadAgent(aid) || config;
1119
- const lifecycle = normalizeAgentLifecycle(offlineConfig).lifecycle;
1120
- if (lifecycle === 'active')
1121
- return { ok: true, aid, reloaded: false };
1122
- if (lifecycle !== 'bootstrapping') {
1123
- return { ok: false, code: 'INVALID_LIFECYCLE', error: `Agent "${aid}" is ${lifecycle}; only a bootstrapping agent can become ready` };
1124
- }
1125
- const owner = offlineConfig.owners?.[0];
1126
- if (!owner)
1127
- return { ok: false, code: 'OWNER_REQUIRED', error: `Agent "${aid}" has no owner for the completion welcome` };
1128
- try {
1129
- preparePostBootstrapWelcomeOutbox(aid, owner);
1130
- saveAgent(withLifecycleForWrite(offlineConfig, 'active'));
1131
- }
1132
- catch (e) {
1133
- return {
1134
- ok: false,
1135
- code: 'READY_PERSIST_FAILED',
1136
- error: e instanceof Error ? e.message : 'Failed to persist bootstrap completion',
1137
- };
1138
- }
1139
- return { ok: true, aid, reloaded: false };
1207
+ const delegationToken = managedSessionId ? process.env[AGENT_DELEGATION_TOKEN_ENV] : undefined;
1208
+ if (managedSessionId && !delegationToken) {
1209
+ return { ok: false, code: 'DELEGATION_REQUIRED', error: `${AGENT_DELEGATION_TOKEN_ENV} is not set for the active task` };
1140
1210
  }
1211
+ const result = await ipcQuery(p.socket, {
1212
+ type: 'evolagent.bootstrapComplete',
1213
+ aid,
1214
+ ...(managedSessionId ? { sessionId: managedSessionId, delegationToken } : {}),
1215
+ }, 30_000);
1216
+ if (!result)
1217
+ return { ok: false, code: 'DAEMON_UNAVAILABLE', error: 'Unable to connect to the evolcore daemon; agent ready requires daemon IPC' };
1141
1218
  if (!result.ok) {
1142
1219
  return { ok: false, code: result.code, error: result.error || 'Failed to complete bootstrap' };
1143
1220
  }