evolcore 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +583 -516
- package/LICENSE +21 -21
- package/README.md +455 -453
- package/bin/codex-managed-acl.ps1 +160 -155
- package/bin/codex-managed-hook.mjs +209 -92
- package/bin/ec-safe-output.js +327 -245
- package/bin/ec.js +29 -29
- package/bin/install-codex-managed-hooks.mjs +555 -544
- package/dist/agents/baseagent-availability.js +4 -4
- package/dist/agents/baseagent.js +29 -1
- package/dist/agents/claude-runner.js +152 -14
- package/dist/agents/codex/app-server-client.js +18 -8
- package/dist/agents/codex/catalog.js +1 -1
- package/dist/agents/codex/diagnostics.js +215 -0
- package/dist/agents/codex-runner.js +445 -63
- package/dist/agents/ecagent-runner.js +31 -16
- package/dist/agents/gemini-runner.js +82 -4
- package/dist/agents/runner-types.js +1 -1
- package/dist/aun/aid/agentmd.js +56 -4
- package/dist/aun/aid/index.js +1 -0
- package/dist/aun/aid/managed-operation.js +80 -6
- package/dist/aun/aid/store.js +41 -0
- package/dist/aun/msg/managed-operation.js +6 -1
- package/dist/aun/outbox.js +56 -18
- package/dist/aun/rpc/client.js +4 -5
- package/dist/aun/storage/client.js +4 -1
- package/dist/aun/storage/index.js +1 -1
- package/dist/channels/aun.js +147 -76
- package/dist/channels/daemon.js +7 -1
- package/dist/channels/dingtalk.js +1 -0
- package/dist/channels/feishu.js +10 -4
- package/dist/channels/wecom.js +2 -1
- package/dist/cli/agent-command.js +214 -89
- package/dist/cli/agent-create.js +576 -0
- package/dist/cli/agent.js +129 -676
- package/dist/cli/aun-commands.js +419 -313
- package/dist/cli/bench.js +20 -20
- package/dist/cli/config.js +20 -20
- package/dist/cli/contact.js +10 -10
- package/dist/cli/ctl-command.js +22 -20
- package/dist/cli/daemon-commands.js +163 -32
- package/dist/cli/fs-command.js +67 -67
- package/dist/cli/handoff-command.js +7 -7
- package/dist/cli/index.js +79 -79
- package/dist/cli/link-rules.js +21 -21
- package/dist/cli/managed-command-guard.js +3 -0
- package/dist/cli/menu-client.js +11 -11
- package/dist/cli/net-check.js +22 -22
- package/dist/cli/queue-command.js +29 -29
- package/dist/cli/response.js +30 -30
- package/dist/cli/restart-monitor.js +462 -38
- package/dist/cli/stats.js +161 -51
- package/dist/cli/trigger-command.js +56 -56
- package/dist/config/builtin-roles.js +3 -0
- package/dist/config/config-manager.js +15 -0
- package/dist/config/config-operation-service.js +20 -3
- package/dist/config/resolved-config-op.js +39 -1
- package/dist/core/auth/auth-gateway.js +3 -2
- package/dist/core/auth/authorization-audit.js +72 -19
- package/dist/core/auth/operation-authorizer.js +125 -7
- package/dist/core/auth/operation-catalog.js +26 -2
- package/dist/core/auth/remote-access-store.js +3 -2
- package/dist/core/baseagent-loader.js +4 -4
- package/dist/core/bootstrap-messages.js +39 -18
- package/dist/core/bootstrap-service.js +32 -26
- package/dist/core/capability/capability-manager.js +8 -4
- package/dist/core/capability/providers/codex-capability-provider.js +1 -1
- package/dist/core/command/agent-control.js +60 -26
- package/dist/core/command/cli-intent-parser.js +18 -0
- package/dist/core/command/command-handler.js +173 -36
- package/dist/core/command/menu-catalog.js +4 -1
- package/dist/core/command/menu-handler.js +315 -75
- package/dist/core/command/menu-protocol.js +7 -2
- package/dist/core/command/slash-gate.js +1 -3
- package/dist/core/command/slash-handler.js +166 -57
- package/dist/core/data-migration.js +5 -15
- package/dist/core/event-catalog.js +8 -0
- package/dist/core/evolagent.js +3 -3
- package/dist/core/handoff/runtime.js +3 -1
- package/dist/core/handoff/store.js +7 -1
- package/dist/core/message/im-renderer.js +13 -6
- package/dist/core/message/message-bridge.js +5 -36
- package/dist/core/message/message-utils.js +6 -3
- package/dist/core/message/response-engine.js +85 -27
- package/dist/core/model/catalog-service.js +3 -1
- package/dist/core/model/model-catalog.js +10 -0
- package/dist/core/model/model-permission.js +4 -1
- package/dist/core/permission/approval-gateway.js +169 -33
- package/dist/core/permission/tool-policy.js +56 -10
- package/dist/core/session/adapters/codex-session-file-adapter.js +71 -3
- package/dist/core/session/session-manager.js +49 -13
- package/dist/core/session/session-renew.js +1 -0
- package/dist/index.js +327 -134
- package/dist/ipc.js +68 -21
- package/dist/paths.js +23 -1
- package/dist/stats/billing.js +18 -4
- package/dist/stats/db.js +159 -159
- package/dist/stats/eck-vars.js +9 -9
- package/dist/stats/query.js +139 -139
- package/dist/stats/role-budget.js +6 -6
- package/dist/stats/writer.js +51 -51
- package/dist/utils/atomic-write.js +26 -2
- package/dist/utils/avatar-upload.js +282 -23
- package/dist/utils/cross-platform.js +436 -1
- package/dist/utils/error-dict.json +160 -160
- package/dist/utils/error-utils.js +11 -4
- package/dist/utils/macos-autostart.js +22 -22
- package/dist/utils/model-prices.jsonl +23 -20
- package/dist/utils/npm-ops.js +24 -1
- package/dist/utils/welcome.js +22 -22
- package/dist/utils/windows-autostart.js +1 -1
- package/ecagent/LICENSE +21 -21
- package/ecagent/NOTICE +11 -11
- package/ecagent/README.md +61 -61
- package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
- package/ecagent/dist/harness/compaction/compaction.js +83 -83
- package/ecagent/dist/harness/messages.js +7 -7
- package/kits/docs/GUIDE.md +20 -20
- package/kits/docs/INDEX.md +66 -66
- package/kits/docs/aun/CHEATSHEET.md +19 -19
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
- package/kits/docs/channels/aun.md +56 -56
- package/kits/docs/channels/feishu.md +56 -56
- package/kits/docs/context-assembly.md +365 -364
- package/kits/docs/eck_templates/GUIDE.template.md +22 -22
- package/kits/docs/eck_templates/INDEX.template.md +28 -28
- package/kits/docs/eck_templates/path-registry.template.md +33 -33
- package/kits/docs/eck_templates/runtime.template.md +19 -19
- package/kits/docs/evolcore/INDEX.md +71 -69
- package/kits/docs/evolcore/agent-create.md +170 -156
- package/kits/docs/evolcore/agent.md +83 -73
- package/kits/docs/evolcore/aid.md +64 -62
- package/kits/docs/evolcore/codex-windows-sandbox.md +146 -0
- package/kits/docs/evolcore/config.md +195 -195
- package/kits/docs/evolcore/contact.md +68 -68
- package/kits/docs/evolcore/ctl.md +46 -46
- package/kits/docs/evolcore/event.md +216 -216
- package/kits/docs/evolcore/fs-architecture.md +1215 -1215
- package/kits/docs/evolcore/fs.md +110 -110
- package/kits/docs/evolcore/group-collaboration.md +243 -243
- package/kits/docs/evolcore/group-fs.md +17 -17
- package/kits/docs/evolcore/group-rules.md +251 -251
- package/kits/docs/evolcore/group.md +152 -152
- package/kits/docs/evolcore/menu-client.md +34 -34
- package/kits/docs/evolcore/model.md +50 -50
- package/kits/docs/evolcore/msg.md +165 -165
- package/kits/docs/evolcore/response.md +75 -75
- package/kits/docs/evolcore/rpc.md +37 -37
- package/kits/docs/evolcore/self-summary.md +29 -29
- package/kits/docs/evolcore/stats.md +83 -83
- package/kits/docs/evolcore/storage.md +50 -50
- package/kits/docs/evolcore/trigger.md +575 -575
- package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
- package/kits/docs/identity/PATH_OPS.md +16 -16
- package/kits/docs/identity/ROLE_DETAIL.md +25 -25
- package/kits/docs/identity/identity-tools.md +26 -26
- package/kits/docs/path-registry.md +62 -62
- package/kits/docs/prompt-loading-architecture.md +270 -269
- package/kits/docs/venues/aun-group.md +45 -45
- package/kits/docs/venues/aun-private.md +10 -10
- package/kits/docs/venues/client-desktop.md +10 -10
- package/kits/docs/venues/client-mobile.md +10 -10
- package/kits/docs/venues/feishu-group.md +13 -13
- package/kits/docs/venues/feishu-private.md +9 -9
- package/kits/docs/venues/group.md +25 -25
- package/kits/docs/venues/private.md +10 -10
- package/kits/eck_manifest.auxiliary.json +43 -43
- package/kits/eck_manifest.json +195 -183
- package/kits/eck_message_manifest.json +74 -74
- package/kits/migrations/README-role-config-v4.md +32 -32
- package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
- package/kits/migrations/migrate-role-config-v4.mjs +614 -614
- package/kits/migrations/migrate-role-config-v5.mjs +365 -365
- package/kits/migrations/rename-config-file.mjs +99 -99
- package/kits/rules/01-overview.md +162 -162
- package/kits/rules/02-navigation.md +96 -96
- package/kits/rules/03-identity.md +39 -37
- package/kits/rules/04-relation.md +75 -75
- package/kits/rules/05-venue.md +60 -60
- package/kits/rules/06-channel.md +63 -63
- package/kits/schemas/_meta.json +53 -53
- package/kits/schemas/agent-config.schema.1.json +177 -177
- package/kits/schemas/agent-config.schema.10.json +395 -395
- package/kits/schemas/agent-config.schema.11.json +421 -421
- package/kits/schemas/agent-config.schema.12.json +427 -427
- package/kits/schemas/agent-config.schema.2.json +239 -239
- package/kits/schemas/agent-config.schema.3.json +119 -119
- package/kits/schemas/agent-config.schema.4.json +208 -208
- package/kits/schemas/agent-config.schema.5.json +326 -326
- package/kits/schemas/agent-config.schema.6.json +322 -322
- package/kits/schemas/agent-config.schema.7.json +303 -303
- package/kits/schemas/agent-config.schema.8.json +304 -304
- package/kits/schemas/agent-config.schema.9.json +364 -364
- package/kits/schemas/contact-book.schema.1.json +36 -36
- package/kits/schemas/contact-book.schema.2.json +43 -43
- package/kits/schemas/contact-book.schema.3.json +67 -67
- package/kits/schemas/daemon.schema.1.json +91 -91
- package/kits/schemas/daemon.schema.2.json +101 -101
- package/kits/schemas/daemon.schema.3.json +123 -123
- package/kits/schemas/daemon.schema.4.json +136 -136
- package/kits/schemas/daemon.schema.5.json +135 -135
- package/kits/schemas/daemon.schema.6.json +131 -131
- package/kits/schemas/defaults.schema.1.json +81 -81
- package/kits/schemas/defaults.schema.2.json +85 -85
- package/kits/schemas/defaults.schema.3.json +73 -73
- package/kits/schemas/defaults.schema.4.json +107 -107
- package/kits/schemas/defaults.schema.5.json +119 -119
- package/kits/schemas/menu-exec-schema-commands.md +208 -208
- package/kits/schemas/migrations/README.md +30 -30
- package/kits/schemas/relation-config.schema.1.json +158 -158
- package/kits/schemas/relation-config.schema.2.json +73 -73
- package/kits/schemas/relation-config.schema.3.json +50 -50
- package/kits/schemas/relation-config.schema.4.json +47 -47
- package/kits/schemas/relation-config.schema.5.json +47 -47
- package/kits/schemas/relation-config.schema.6.json +46 -46
- package/kits/schemas/relation-config.schema.7.json +59 -59
- package/kits/schemas/relation-config.schema.8.json +103 -103
- package/kits/schemas/role-config.schema.1.json +201 -201
- package/kits/schemas/role-registry.schema.1.json +35 -35
- package/kits/schemas/single-session.schema.1.json +31 -31
- package/kits/schemas/single-session.schema.2.json +57 -57
- package/kits/schemas/single-session.schema.3.json +32 -32
- package/kits/templates/bootstrap-welcome.md +17 -17
- package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
- package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
- package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
- package/kits/templates/message-fragments/inject-default.md +2 -2
- package/kits/templates/message-fragments/item.md +2 -2
- package/kits/templates/roles/admin.json +96 -82
- package/kits/templates/roles/member.json +97 -96
- package/kits/templates/roles/owner.json +9 -9
- package/kits/templates/roles/visitor.json +86 -85
- package/kits/templates/system-fragments/baseagent.md +14 -14
- package/kits/templates/system-fragments/bootstrap.md +38 -29
- package/kits/templates/system-fragments/channel.md +64 -64
- package/kits/templates/system-fragments/commands.md +28 -28
- package/kits/templates/system-fragments/identity.md +13 -13
- package/kits/templates/system-fragments/relation.md +19 -19
- package/kits/templates/system-fragments/session.md +59 -59
- package/kits/templates/system-fragments/venue.md +31 -31
- package/package.json +98 -94
- package/AGENTS.md +0 -62
- package/dist/utils/codex-cli.js +0 -43
- package/skills/eclink/SKILL.md +0 -84
- package/skills/eclink/agents/openai.yaml +0 -4
package/dist/index.js
CHANGED
|
@@ -100,6 +100,7 @@ import { MAIN_PACKAGE_NAME } from './product.js';
|
|
|
100
100
|
import fs from 'fs';
|
|
101
101
|
import crypto from 'crypto';
|
|
102
102
|
import { fileURLToPath } from 'url';
|
|
103
|
+
import * as platform from './utils/cross-platform.js';
|
|
103
104
|
const controlMenuDeduper = new MenuRequestDeduper();
|
|
104
105
|
/** 出站 payload 摘要(用于 channel-out.log) */
|
|
105
106
|
function summarizeOutboundPayload(payload) {
|
|
@@ -134,6 +135,7 @@ function summarizeOutboundPayload(payload) {
|
|
|
134
135
|
break;
|
|
135
136
|
case 'status.started':
|
|
136
137
|
case 'status.progress':
|
|
138
|
+
case 'status.notice':
|
|
137
139
|
case 'status.requires_action':
|
|
138
140
|
case 'status.queued':
|
|
139
141
|
case 'status.completed':
|
|
@@ -326,102 +328,158 @@ function seedUpgradeCheckTrigger(manager, owner) {
|
|
|
326
328
|
const cliPath = path.join(packageRoot, 'dist', 'cli', 'index.js');
|
|
327
329
|
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
328
330
|
const devMode = fs.existsSync(path.join(packageRoot, 'src', 'index.ts'));
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
331
|
+
// Resolve the launch argv at generation time: in a checkout this points the
|
|
332
|
+
// monitor at src/ through tsx, so a `npm run build` that wipes dist/ cannot
|
|
333
|
+
// take the watchdog down with it.
|
|
334
|
+
const monitorEntry = platform.resolveCliEntry(packageRoot);
|
|
335
|
+
const stageParent = path.join(resolvePaths().root, 'data', 'monitor-stage');
|
|
336
|
+
fs.writeFileSync(scriptPath, `#!/usr/bin/env node
|
|
337
|
+
const fs = require('node:fs');
|
|
338
|
+
const path = require('node:path');
|
|
339
|
+
const { existsSync, readFileSync } = fs;
|
|
340
|
+
const { spawn } = require('node:child_process');
|
|
341
|
+
|
|
342
|
+
const CLI_PATH = ${JSON.stringify(monitorEntry.entry)};
|
|
343
|
+
const CLI_ARGS = ${JSON.stringify(monitorEntry.args)};
|
|
344
|
+
const PACKAGE_ROOT = ${JSON.stringify(packageRoot)};
|
|
345
|
+
const STAGE_PARENT = ${JSON.stringify(stageParent)};
|
|
346
|
+
const PACKAGE_JSON = ${JSON.stringify(packageJsonPath)};
|
|
347
|
+
const PACKAGE_NAME = ${JSON.stringify(MAIN_PACKAGE_NAME)};
|
|
348
|
+
const DEV_MODE = ${devMode ? 'true' : 'false'};
|
|
349
|
+
|
|
350
|
+
function emit(outcome, text) {
|
|
351
|
+
process.stdout.write(JSON.stringify({ outcome, text, files: [] }));
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function compareVersions(a, b) {
|
|
355
|
+
const pa = a.split('-')[0].split('.').map(Number);
|
|
356
|
+
const pb = b.split('-')[0].split('.').map(Number);
|
|
357
|
+
const count = Math.max(pa.length, pb.length);
|
|
358
|
+
for (let i = 0; i < count; i += 1) {
|
|
359
|
+
const av = Number.isFinite(pa[i]) ? pa[i] : 0;
|
|
360
|
+
const bv = Number.isFinite(pb[i]) ? pb[i] : 0;
|
|
361
|
+
if (av < bv) return -1;
|
|
362
|
+
if (av > bv) return 1;
|
|
363
|
+
}
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function latestVersion() {
|
|
368
|
+
const controller = new AbortController();
|
|
369
|
+
const timer = setTimeout(() => controller.abort(), 10_000);
|
|
370
|
+
try {
|
|
371
|
+
const response = await fetch('https://registry.npmjs.org/' + encodeURIComponent(PACKAGE_NAME) + '/latest', {
|
|
372
|
+
signal: controller.signal,
|
|
373
|
+
headers: { Accept: 'application/json' },
|
|
374
|
+
});
|
|
375
|
+
if (!response.ok) return null;
|
|
376
|
+
const data = await response.json();
|
|
377
|
+
return typeof data.version === 'string' ? data.version : null;
|
|
378
|
+
} finally {
|
|
379
|
+
clearTimeout(timer);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
async function main() {
|
|
384
|
+
if (DEV_MODE) {
|
|
385
|
+
emit('noop', 'upgrade check skipped in dev mode');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
let localVersion;
|
|
390
|
+
try {
|
|
391
|
+
localVersion = JSON.parse(readFileSync(PACKAGE_JSON, 'utf8')).version;
|
|
392
|
+
} catch {
|
|
393
|
+
emit('error', 'failed to read local ec version');
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (typeof localVersion !== 'string' || !localVersion) {
|
|
397
|
+
emit('error', 'failed to read local ec version');
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let remoteVersion;
|
|
402
|
+
try {
|
|
403
|
+
remoteVersion = await latestVersion();
|
|
404
|
+
} catch {
|
|
405
|
+
remoteVersion = null;
|
|
406
|
+
}
|
|
407
|
+
if (!remoteVersion) {
|
|
408
|
+
emit('error', 'failed to check evolcore latest version');
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (compareVersions(localVersion, remoteVersion) >= 0) {
|
|
412
|
+
emit('noop', 'evolcore is already up to date (' + localVersion + '; latest ' + remoteVersion + ')');
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (!existsSync(CLI_PATH)) {
|
|
416
|
+
emit('error', 'restart-monitor entry not found: ' + CLI_PATH);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Installed mode: copy the monitor out of the package before it upgrades that
|
|
421
|
+
// same package. Mirrors prepareMonitorStage(); kept inline because this file
|
|
422
|
+
// is generated standalone CJS. Any failure degrades to launching in place —
|
|
423
|
+
// losing upgrade isolation beats losing the upgrade.
|
|
424
|
+
let launchArgs = CLI_ARGS;
|
|
425
|
+
const launchEnv = { ...process.env };
|
|
426
|
+
if (!DEV_MODE && STAGE_PARENT) {
|
|
427
|
+
try {
|
|
428
|
+
const stageDir = path.join(STAGE_PARENT, 'upgrade-' + process.pid + '-' + Date.now());
|
|
429
|
+
fs.mkdirSync(stageDir, { recursive: true });
|
|
430
|
+
fs.cpSync(path.join(PACKAGE_ROOT, 'dist'), path.join(stageDir, 'dist'), { recursive: true });
|
|
431
|
+
if (existsSync(PACKAGE_JSON)) fs.copyFileSync(PACKAGE_JSON, path.join(stageDir, 'package.json'));
|
|
432
|
+
const modulesSource = path.join(PACKAGE_ROOT, 'node_modules');
|
|
433
|
+
if (existsSync(modulesSource)) {
|
|
434
|
+
const staged = path.join(stageDir, 'node_modules');
|
|
435
|
+
try {
|
|
436
|
+
// junction works unelevated on Windows; dir symlink elsewhere.
|
|
437
|
+
fs.symlinkSync(modulesSource, staged, process.platform === 'win32' ? 'junction' : 'dir');
|
|
438
|
+
fs.readdirSync(staged);
|
|
439
|
+
} catch (linkError) {
|
|
440
|
+
fs.rmSync(staged, { recursive: true, force: true });
|
|
441
|
+
fs.cpSync(modulesSource, staged, { recursive: true });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const stagedEntry = path.join(stageDir, 'dist', 'cli', 'index.js');
|
|
445
|
+
if (existsSync(stagedEntry)) {
|
|
446
|
+
launchArgs = [stagedEntry];
|
|
447
|
+
launchEnv.EVOLCORE_TARGET_PACKAGE_ROOT = PACKAGE_ROOT;
|
|
448
|
+
launchEnv.EVOLCORE_MONITOR_STAGE = stageDir;
|
|
449
|
+
}
|
|
450
|
+
} catch (stageError) {
|
|
451
|
+
// Fall through with the in-place entry.
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
try {
|
|
456
|
+
const child = spawn(process.execPath, [...launchArgs, 'restart-monitor'], {
|
|
457
|
+
detached: true,
|
|
458
|
+
stdio: 'ignore',
|
|
459
|
+
windowsHide: process.platform === 'win32',
|
|
460
|
+
env: launchEnv,
|
|
461
|
+
});
|
|
462
|
+
child.unref();
|
|
463
|
+
const pid = child.pid;
|
|
464
|
+
// The daemon is still running here — the monitor is what stops it. So a
|
|
465
|
+
// monitor that dies on load costs the upgrade, not the service; still,
|
|
466
|
+
// report it accurately instead of claiming success.
|
|
467
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
468
|
+
let alive = false;
|
|
469
|
+
try { process.kill(pid, 0); alive = true; } catch (e) { alive = false; }
|
|
470
|
+
if (!alive) {
|
|
471
|
+
emit('error', 'restart-monitor exited during startup; upgrade to ' + remoteVersion + ' not applied');
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
emit('success', 'evolcore upgrade available: ' + localVersion + ' -> ' + remoteVersion + '; restart-monitor started');
|
|
475
|
+
} catch (error) {
|
|
476
|
+
emit('error', 'failed to start restart-monitor: ' + (error && error.message ? error.message : String(error)));
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
main().catch((error) => {
|
|
481
|
+
emit('error', 'upgrade check failed: ' + (error && error.message ? error.message : String(error)));
|
|
482
|
+
});
|
|
425
483
|
`);
|
|
426
484
|
// Remove the pre-Node script left by older installations so it cannot be
|
|
427
485
|
// selected by a stale trigger definition or run manually by accident.
|
|
@@ -1066,7 +1124,7 @@ async function main() {
|
|
|
1066
1124
|
agentLoader.register(new GeminiAgentPlugin());
|
|
1067
1125
|
agentLoader.register(new EcagentAgentPlugin());
|
|
1068
1126
|
const creationErrors = [];
|
|
1069
|
-
const agentInstances = agentLoader.createAll(agentRegistry, {
|
|
1127
|
+
const agentInstances = await agentLoader.createAll(agentRegistry, {
|
|
1070
1128
|
onSessionIdUpdate: async (sessionId, agentSessionId, context) => {
|
|
1071
1129
|
return await sessionManager.updateAgentSessionIdBySessionId(sessionId, agentSessionId, context?.turn);
|
|
1072
1130
|
},
|
|
@@ -1493,8 +1551,9 @@ async function main() {
|
|
|
1493
1551
|
}
|
|
1494
1552
|
if (definition.execution.effort && !actor.daemonPrivileged) {
|
|
1495
1553
|
const baseagent = definition.execution.baseagent
|
|
1496
|
-
?? agentRegistry.get(definition.agentAid)?.baseagent
|
|
1497
|
-
|
|
1554
|
+
?? agentRegistry.get(definition.agentAid)?.baseagent;
|
|
1555
|
+
if (!baseagent)
|
|
1556
|
+
throw new Error('cannot determine Trigger baseagent');
|
|
1498
1557
|
const effortDecision = validateRuntimeStringFieldOverride({
|
|
1499
1558
|
selfAid: definition.agentAid,
|
|
1500
1559
|
role: actor.role,
|
|
@@ -2154,6 +2213,7 @@ async function main() {
|
|
|
2154
2213
|
const pendingRouteContext = restartDelivery.delivery ? { delivery: restartDelivery.delivery } : {};
|
|
2155
2214
|
const replyContext = {
|
|
2156
2215
|
...(pendingRouteContext ?? {}),
|
|
2216
|
+
...(pending.threadId ? { threadId: pending.threadId } : {}),
|
|
2157
2217
|
...(pending.rootId ? { replyToMessageId: pending.rootId, replyInThread: !!pending.threadId } : {}),
|
|
2158
2218
|
};
|
|
2159
2219
|
const owningAgent = agentRegistry.resolveByChannel(adapter.channelKey);
|
|
@@ -2165,10 +2225,23 @@ async function main() {
|
|
|
2165
2225
|
...(restartDelivery.delivery ? { delivery: restartDelivery.delivery } : {}),
|
|
2166
2226
|
replyContext: Object.keys(replyContext).length > 0 ? replyContext : undefined,
|
|
2167
2227
|
});
|
|
2228
|
+
// restart-monitor 会在回滚/升级时写入 outcome:必须如实告诉发起方这次跑的是
|
|
2229
|
+
// 哪个版本,否则 agent 会以为自己的改动或升级已经生效。
|
|
2230
|
+
const restartNotice = pending.outcome === 'rolled-back'
|
|
2231
|
+
? {
|
|
2232
|
+
text: `⚠️ 服务已重启,但运行的是上一个版本。${pending.outcomeReason ? `原因:${pending.outcomeReason}。` : ''}本次改动未生效,请检查后重试。`,
|
|
2233
|
+
subtype: 'restarted-rolled-back',
|
|
2234
|
+
}
|
|
2235
|
+
: pending.outcome === 'upgraded'
|
|
2236
|
+
? {
|
|
2237
|
+
text: `✅ 服务重启成功!${pending.outcomeReason ? `${pending.outcomeReason}` : ''}`,
|
|
2238
|
+
subtype: 'restarted-upgraded',
|
|
2239
|
+
}
|
|
2240
|
+
: { text: '✅ 服务重启成功!', subtype: 'restarted' };
|
|
2168
2241
|
await sendSystemPayload(adapter, envelope, {
|
|
2169
2242
|
kind: 'system.notice',
|
|
2170
|
-
text:
|
|
2171
|
-
subtype:
|
|
2243
|
+
text: restartNotice.text,
|
|
2244
|
+
subtype: restartNotice.subtype,
|
|
2172
2245
|
});
|
|
2173
2246
|
pendingRestartNoticeSent = true;
|
|
2174
2247
|
fs.rmSync(pendingFile, { force: true });
|
|
@@ -2658,9 +2731,18 @@ async function main() {
|
|
|
2658
2731
|
continue;
|
|
2659
2732
|
}
|
|
2660
2733
|
const evolName = owningAgent.aid;
|
|
2661
|
-
const baseagentName = session.baseagent
|
|
2662
|
-
|
|
2734
|
+
const baseagentName = typeof session.baseagent === 'string' ? session.baseagent.trim() : '';
|
|
2735
|
+
if (!baseagentName) {
|
|
2736
|
+
logger.error(`[Resume] session ${session.id}: missing baseagent binding, refusing implicit runner fallback`);
|
|
2737
|
+
sessionManager.clearProcessing(session.id);
|
|
2738
|
+
continue;
|
|
2739
|
+
}
|
|
2740
|
+
// Recovery must resume on the exact Agent × baseagent runner recorded by
|
|
2741
|
+
// the Session. Never fall back to the primary runner: doing so can bind
|
|
2742
|
+
// an in-flight session to a different backend.
|
|
2743
|
+
const agent = agentMap.get(`${evolName}::${baseagentName}`);
|
|
2663
2744
|
if (!agent) {
|
|
2745
|
+
logger.error(`[Resume] session ${session.id}: runner unavailable for ${evolName}::${baseagentName}; refusing fallback`);
|
|
2664
2746
|
sessionManager.clearProcessing(session.id);
|
|
2665
2747
|
continue;
|
|
2666
2748
|
}
|
|
@@ -2727,11 +2809,12 @@ async function main() {
|
|
|
2727
2809
|
return owner?.aid === aid;
|
|
2728
2810
|
});
|
|
2729
2811
|
const welcome = aunInstance?.channel;
|
|
2730
|
-
const ownerAid = getFirstStaticAgentOwner(aid);
|
|
2731
2812
|
const owningAgent = agentRegistry.get(aid);
|
|
2732
|
-
const
|
|
2813
|
+
const firstOwnerAid = getFirstStaticAgentOwner(aid);
|
|
2814
|
+
const sessions = aunInstance && firstOwnerAid && owningAgent
|
|
2733
2815
|
? {
|
|
2734
|
-
ensurePostBootstrapMainSession: async () => {
|
|
2816
|
+
ensurePostBootstrapMainSession: async (owner) => {
|
|
2817
|
+
const ownerAid = owner || firstOwnerAid;
|
|
2735
2818
|
const channel = aunInstance.adapter.channelName;
|
|
2736
2819
|
const active = await sessionManager.getActiveSession(channel, ownerAid);
|
|
2737
2820
|
const ensured = await sessionManager.ensureNewMainSessionForOperation({
|
|
@@ -2739,7 +2822,7 @@ async function main() {
|
|
|
2739
2822
|
channelId: ownerAid,
|
|
2740
2823
|
projectPath: active?.projectPath || owningAgent.projectPath || defaultProjectPath,
|
|
2741
2824
|
baseagent: owningAgent.baseagent || active?.baseagent || primaryBaseagent,
|
|
2742
|
-
operationId: postBootstrapWelcomeOperationId(aid),
|
|
2825
|
+
operationId: postBootstrapWelcomeOperationId(aid, ownerAid),
|
|
2743
2826
|
identityMetadata: {
|
|
2744
2827
|
...(active?.metadata ?? {}),
|
|
2745
2828
|
channelKey: aunInstance.adapter.channelKey,
|
|
@@ -2851,15 +2934,18 @@ async function main() {
|
|
|
2851
2934
|
for (const runner of new Set(agentMap.values())) {
|
|
2852
2935
|
if (typeof runner?.evaluatePreToolUse !== 'function')
|
|
2853
2936
|
continue;
|
|
2854
|
-
const result = await runner.evaluatePreToolUse(params.threadId, params.toolName, params.toolInput, params.signal, params.callId);
|
|
2937
|
+
const result = await runner.evaluatePreToolUse(params.threadId, params.toolName, params.toolInput, params.signal, params.callId, params.sessionToken);
|
|
2855
2938
|
if (result.applicable)
|
|
2856
2939
|
return result;
|
|
2857
2940
|
}
|
|
2941
|
+
// A credential that no runner issued is forged or belongs to a thread
|
|
2942
|
+
// whose rollout is gone. Never allow it; uncredentialed calls were
|
|
2943
|
+
// already allowed by the IPC layer before reaching this executor.
|
|
2858
2944
|
return {
|
|
2859
2945
|
ok: false,
|
|
2860
2946
|
applicable: true,
|
|
2861
2947
|
decision: 'deny',
|
|
2862
|
-
reason: 'No active EvolCore Codex runner accepted this managed hook
|
|
2948
|
+
reason: 'No active EvolCore Codex runner accepted this managed hook credential',
|
|
2863
2949
|
};
|
|
2864
2950
|
});
|
|
2865
2951
|
const resolveManagedHandoffScope = async (params, operation) => {
|
|
@@ -3192,7 +3278,7 @@ async function main() {
|
|
|
3192
3278
|
const creationErrors = [];
|
|
3193
3279
|
const staged = candidate.config.enabled === false
|
|
3194
3280
|
? []
|
|
3195
|
-
: agentLoader.createForAgent(candidate, {
|
|
3281
|
+
: await agentLoader.createForAgent(candidate, {
|
|
3196
3282
|
onSessionIdUpdate: async (sessionId, agentSessionId, context) => {
|
|
3197
3283
|
return await sessionManager.updateAgentSessionIdBySessionId(sessionId, agentSessionId, context?.turn);
|
|
3198
3284
|
},
|
|
@@ -3292,7 +3378,7 @@ async function main() {
|
|
|
3292
3378
|
throw new Error(agentRuntimeError);
|
|
3293
3379
|
}
|
|
3294
3380
|
const creationErrors = [];
|
|
3295
|
-
const newAgentInstances = agentLoader.createForAgent(agent, {
|
|
3381
|
+
const newAgentInstances = await agentLoader.createForAgent(agent, {
|
|
3296
3382
|
onSessionIdUpdate: async (sessionId, agentSessionId, context) => {
|
|
3297
3383
|
return await sessionManager.updateAgentSessionIdBySessionId(sessionId, agentSessionId, context?.turn);
|
|
3298
3384
|
},
|
|
@@ -3483,7 +3569,7 @@ async function main() {
|
|
|
3483
3569
|
hotLoad: coreHotLoadAgent,
|
|
3484
3570
|
resync: coreResyncAgents,
|
|
3485
3571
|
create: async (options) => {
|
|
3486
|
-
const { agentCreateNonInteractive } = await import('./cli/agent.js');
|
|
3572
|
+
const { agentCreateNonInteractive } = await import('./cli/agent-create.js');
|
|
3487
3573
|
return await agentCreateNonInteractive(options, { hotLoadAgent: coreHotLoadAgent });
|
|
3488
3574
|
},
|
|
3489
3575
|
aunAids: () => channelInstances.flatMap((inst) => {
|
|
@@ -3577,7 +3663,8 @@ async function main() {
|
|
|
3577
3663
|
});
|
|
3578
3664
|
if (params.targetAid
|
|
3579
3665
|
&& params.targetAid !== delegation.grant.selfAid
|
|
3580
|
-
&& subject.dataScope !== 'daemon'
|
|
3666
|
+
&& subject.dataScope !== 'daemon'
|
|
3667
|
+
&& !(operation === 'agent.show' && isManagementRole(subject.role))) {
|
|
3581
3668
|
return { ok: false, code: 'SCOPE_MISMATCH', error: 'only the current Agent can be targeted' };
|
|
3582
3669
|
}
|
|
3583
3670
|
const decision = authorizeOperation({
|
|
@@ -3624,18 +3711,21 @@ async function main() {
|
|
|
3624
3711
|
const taskAid = delegation.grant.selfAid;
|
|
3625
3712
|
const targetAid = sub === 'list'
|
|
3626
3713
|
? undefined
|
|
3627
|
-
: sub === '
|
|
3628
|
-
?
|
|
3629
|
-
: sub === '
|
|
3630
|
-
? (argv[2] && !argv[2].startsWith('--') ? argv[2] :
|
|
3631
|
-
:
|
|
3714
|
+
: sub === 'persona'
|
|
3715
|
+
? taskAid
|
|
3716
|
+
: sub === 'show'
|
|
3717
|
+
? (argv[2] && !argv[2].startsWith('--') ? argv[2] : taskAid)
|
|
3718
|
+
: sub === 'reload'
|
|
3719
|
+
? (argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined)
|
|
3720
|
+
: (argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined);
|
|
3632
3721
|
const operation = sub === 'list' ? 'agent.list'
|
|
3633
3722
|
: sub === 'show' ? 'agent.show'
|
|
3634
|
-
: sub === '
|
|
3635
|
-
: sub === '
|
|
3636
|
-
: sub === '
|
|
3637
|
-
: sub === '
|
|
3638
|
-
: sub === '
|
|
3723
|
+
: sub === 'persona' ? 'agent.persona'
|
|
3724
|
+
: sub === 'new' ? 'agent.create'
|
|
3725
|
+
: sub === 'enable' ? 'agent.enable'
|
|
3726
|
+
: sub === 'disable' ? 'agent.disable'
|
|
3727
|
+
: sub === 'reload' ? 'agent.reload'
|
|
3728
|
+
: sub === 'delete' ? 'agent.delete' : undefined;
|
|
3639
3729
|
if (!operation)
|
|
3640
3730
|
return fail('INVALID_ARGS', `unsupported managed agent command: ${sub}`);
|
|
3641
3731
|
if (sub === 'new' && !argv.includes('--non-interactive')) {
|
|
@@ -3667,7 +3757,7 @@ async function main() {
|
|
|
3667
3757
|
subject,
|
|
3668
3758
|
intent: {
|
|
3669
3759
|
operation,
|
|
3670
|
-
scope: operation === 'agent.show'
|
|
3760
|
+
scope: operation === 'agent.show' || operation === 'agent.persona'
|
|
3671
3761
|
? 'agent'
|
|
3672
3762
|
: operation === 'agent.reload' && targetAid
|
|
3673
3763
|
? 'agent'
|
|
@@ -3723,45 +3813,148 @@ async function main() {
|
|
|
3723
3813
|
},
|
|
3724
3814
|
connection: agent.connection ?? null,
|
|
3725
3815
|
sessions: agent.sessions ?? { active: 0, last_activity: null },
|
|
3726
|
-
paths:
|
|
3727
|
-
|
|
3816
|
+
paths: subject.dataScope === 'daemon'
|
|
3817
|
+
? (agent.paths ?? { config: null, agent_md: null, project: null, data: null })
|
|
3818
|
+
: { config: null, agent_md: null, project: null, data: null },
|
|
3819
|
+
...(subject.dataScope === 'daemon' ? {} : { redacted: true }),
|
|
3728
3820
|
...(agent.createProgress ? { createProgress: agent.createProgress } : {}),
|
|
3729
3821
|
} };
|
|
3730
3822
|
}
|
|
3823
|
+
if (operation === 'agent.persona') {
|
|
3824
|
+
const rawPersonaArgs = argv.slice(2);
|
|
3825
|
+
const hasFormatSuffix = rawPersonaArgs.length >= 2
|
|
3826
|
+
&& rawPersonaArgs.at(-2) === '--format'
|
|
3827
|
+
&& rawPersonaArgs.at(-1) === 'json';
|
|
3828
|
+
const personaArgs = hasFormatSuffix ? rawPersonaArgs.slice(0, -2) : rawPersonaArgs;
|
|
3829
|
+
if (!hasFormatSuffix && rawPersonaArgs.includes('--format')) {
|
|
3830
|
+
return fail('INVALID_ARGS', 'persona 仅支持末尾的 --format json');
|
|
3831
|
+
}
|
|
3832
|
+
if (personaArgs.length === 2 && personaArgs[0] === '--file') {
|
|
3833
|
+
return fail('INVALID_ARGS', '托管 persona --file 必须由 CLI 读取后作为文本提交');
|
|
3834
|
+
}
|
|
3835
|
+
const wantsShow = personaArgs.length === 1 && personaArgs[0] === 'show';
|
|
3836
|
+
const text = personaArgs.length === 2 && personaArgs[0] === '--text'
|
|
3837
|
+
? personaArgs[1]
|
|
3838
|
+
: undefined;
|
|
3839
|
+
if (!wantsShow && !(personaArgs.length === 2 && personaArgs[0] === '--text')) {
|
|
3840
|
+
return fail('INVALID_ARGS', '用法: ec agent persona show | --text <text>');
|
|
3841
|
+
}
|
|
3842
|
+
if (text === undefined && !wantsShow)
|
|
3843
|
+
return fail('INVALID_ARGS', 'persona --text 缺少参数');
|
|
3844
|
+
const { agentPersona } = await import('./cli/agent.js');
|
|
3845
|
+
const result = await agentPersona(taskAid, wantsShow ? { trustedLocal: true } : { text, trustedLocal: true });
|
|
3846
|
+
if (!result.ok)
|
|
3847
|
+
return fail(result.code ?? 'INTERNAL', result.error);
|
|
3848
|
+
return { ok: true, result: {
|
|
3849
|
+
ok: true,
|
|
3850
|
+
aid: taskAid,
|
|
3851
|
+
content: result.content,
|
|
3852
|
+
...(result.saved ? { saved: true } : {}),
|
|
3853
|
+
} };
|
|
3854
|
+
}
|
|
3731
3855
|
if (operation === 'agent.create') {
|
|
3732
3856
|
const aid = argv[2] && !argv[2].startsWith('--') ? argv[2] : undefined;
|
|
3733
3857
|
if (!aid)
|
|
3734
3858
|
return fail('INVALID_ARGS', 'ec agent new requires an AID');
|
|
3735
|
-
const { agentCreateNonInteractive, resolveAgentCreatePlan, validateAgentCreatePlan } = await import('./cli/agent.js');
|
|
3859
|
+
const { agentCreateNonInteractive, resolveAgentCreatePlan, validateAgentCreatePlan, parseAgentOwnerArgs, parseAgentTags } = await import('./cli/agent-create.js');
|
|
3860
|
+
let ownerOptions;
|
|
3861
|
+
try {
|
|
3862
|
+
ownerOptions = parseAgentOwnerArgs(argv);
|
|
3863
|
+
}
|
|
3864
|
+
catch (error) {
|
|
3865
|
+
return fail('INVALID_ARGS', error instanceof Error ? error.message : String(error));
|
|
3866
|
+
}
|
|
3867
|
+
let tags;
|
|
3868
|
+
try {
|
|
3869
|
+
tags = parseAgentTags(value('--tags'));
|
|
3870
|
+
}
|
|
3871
|
+
catch (error) {
|
|
3872
|
+
return fail('INVALID_ARGS', error instanceof Error ? error.message : String(error));
|
|
3873
|
+
}
|
|
3736
3874
|
const plan = resolveAgentCreatePlan({
|
|
3737
3875
|
aid,
|
|
3738
3876
|
project: value('--project'),
|
|
3739
3877
|
baseagent: value('--baseagent'),
|
|
3740
|
-
|
|
3878
|
+
...ownerOptions,
|
|
3879
|
+
handoff: value('--handoff'),
|
|
3741
3880
|
name: value('--name'),
|
|
3742
3881
|
description: value('--description'),
|
|
3882
|
+
tags,
|
|
3743
3883
|
force: argv.includes('--force'),
|
|
3744
3884
|
});
|
|
3745
3885
|
const validationError = validateAgentCreatePlan(plan);
|
|
3746
3886
|
if (validationError)
|
|
3747
3887
|
return fail('INVALID_ARGS', validationError);
|
|
3888
|
+
if (argv.includes('--handoff')) {
|
|
3889
|
+
if (!delegation.grant.messageId)
|
|
3890
|
+
return fail('INVALID_ARGS', '--handoff requires an originating message');
|
|
3891
|
+
if (!plan.handoff?.trim())
|
|
3892
|
+
return fail('INVALID_ARGS', '--handoff requires non-empty context');
|
|
3893
|
+
if ((plan.owners?.[0] ?? plan.owner) !== taskAid) {
|
|
3894
|
+
return fail('INVALID_ARGS', '--handoff requires the creating Agent to be the first Owner');
|
|
3895
|
+
}
|
|
3896
|
+
if (plan.configExists)
|
|
3897
|
+
return fail('INVALID_ARGS', '--handoff requires a new Agent');
|
|
3898
|
+
}
|
|
3748
3899
|
if (argv.includes('--dry-run'))
|
|
3749
3900
|
return { ok: true, result: { ok: true, dryRun: true, plan } };
|
|
3901
|
+
let handoffId;
|
|
3902
|
+
if (plan.handoff) {
|
|
3903
|
+
try {
|
|
3904
|
+
const created = await handoffRuntime.createOutbound({
|
|
3905
|
+
selfAid: taskAid,
|
|
3906
|
+
to: aid,
|
|
3907
|
+
originSessionId: sessionId,
|
|
3908
|
+
originMessageId: delegation.grant.messageId,
|
|
3909
|
+
payload: { type: 'text', text: plan.handoff },
|
|
3910
|
+
encrypt: true,
|
|
3911
|
+
targetChatType: 'private',
|
|
3912
|
+
explicitReturnPolicy: 'required',
|
|
3913
|
+
contextOnly: true,
|
|
3914
|
+
originAuthorization: {
|
|
3915
|
+
actorId: delegation.grant.actorId,
|
|
3916
|
+
channelKey: delegation.grant.channel,
|
|
3917
|
+
channelType: delegation.grant.channelType,
|
|
3918
|
+
chatType: delegation.grant.chatType,
|
|
3919
|
+
peerKey: delegation.grant.peerKey,
|
|
3920
|
+
},
|
|
3921
|
+
causation: responseEngine.getTaskRuntimeContext(sessionId)?.causation,
|
|
3922
|
+
});
|
|
3923
|
+
handoffId = created.handoff?.handoff_id;
|
|
3924
|
+
if (!handoffId)
|
|
3925
|
+
return fail('INVALID_ARGS', '--handoff requires a different target session');
|
|
3926
|
+
}
|
|
3927
|
+
catch (error) {
|
|
3928
|
+
return fail('HANDOFF_PREPARE_FAILED', error instanceof Error ? error.message : String(error));
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3750
3931
|
const createOptions = {
|
|
3751
3932
|
aid: plan.aid,
|
|
3752
3933
|
project: plan.project,
|
|
3753
3934
|
baseagent: plan.baseagent,
|
|
3754
3935
|
owner: plan.owner,
|
|
3936
|
+
owners: plan.owners,
|
|
3755
3937
|
name: plan.name,
|
|
3756
3938
|
description: plan.description,
|
|
3939
|
+
tags: plan.tags,
|
|
3757
3940
|
force: argv.includes('--force'),
|
|
3758
3941
|
};
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3942
|
+
try {
|
|
3943
|
+
const result = agentApplicationService
|
|
3944
|
+
? await agentApplicationService.create(createOptions)
|
|
3945
|
+
: await agentCreateNonInteractive(createOptions);
|
|
3946
|
+
if (!result.ok) {
|
|
3947
|
+
if (handoffId)
|
|
3948
|
+
handoffRuntime.store.discard(taskAid, handoffId, 'operation_failed');
|
|
3949
|
+
return fail(result.code ?? 'INTERNAL', result.error);
|
|
3950
|
+
}
|
|
3951
|
+
return { ok: true, result: { ...result, configPath: '[redacted]', ...(handoffId ? { handoff_id: handoffId } : {}) } };
|
|
3952
|
+
}
|
|
3953
|
+
catch (error) {
|
|
3954
|
+
if (handoffId)
|
|
3955
|
+
handoffRuntime.store.discard(taskAid, handoffId, 'operation_failed');
|
|
3956
|
+
return fail('INTERNAL', error instanceof Error ? error.message : String(error));
|
|
3957
|
+
}
|
|
3765
3958
|
}
|
|
3766
3959
|
if (operation === 'agent.delete') {
|
|
3767
3960
|
const result = agentApplicationService
|