evolcore 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +3 -3
  3. package/bin/codex-managed-hook.mjs +80 -0
  4. package/dist/agents/baseagent.js +4 -0
  5. package/dist/agents/claude-runner.js +158 -44
  6. package/dist/agents/codex-app-server-client.js +153 -23
  7. package/dist/agents/codex-runner.js +331 -43
  8. package/dist/agents/ecagent-runner.js +53 -6
  9. package/dist/agents/gemini-runner.js +1 -0
  10. package/dist/agents/request-identity.js +55 -0
  11. package/dist/aun/aid/client.js +11 -21
  12. package/dist/aun/aid/managed-operation.js +107 -0
  13. package/dist/aun/msg/group.js +81 -12
  14. package/dist/aun/msg/managed-operation.js +804 -0
  15. package/dist/aun/msg/mention-schema.js +20 -0
  16. package/dist/aun/msg/p2p.js +7 -0
  17. package/dist/aun/outbox.js +28 -31
  18. package/dist/channels/aun.js +418 -235
  19. package/dist/channels/daemon.js +13 -0
  20. package/dist/cli/agent-command.js +72 -17
  21. package/dist/cli/agent.js +249 -22
  22. package/dist/cli/aun-commands.js +270 -69
  23. package/dist/cli/bench.js +12 -3
  24. package/dist/cli/daemon-commands.js +52 -33
  25. package/dist/cli/fs-command.js +60 -0
  26. package/dist/cli/handoff-command.js +3 -0
  27. package/dist/cli/index.js +106 -63
  28. package/dist/cli/init-cancel.js +208 -0
  29. package/dist/cli/init-channel.js +343 -195
  30. package/dist/cli/init.js +21 -9
  31. package/dist/cli/managed-command-guard.js +41 -0
  32. package/dist/cli/model.js +11 -4
  33. package/dist/cli/queue-command.js +11 -1
  34. package/dist/cli/response.js +71 -0
  35. package/dist/cli/restart-monitor.js +4 -18
  36. package/dist/cli/trigger-command.js +4 -0
  37. package/dist/config/builtin-roles.js +5 -0
  38. package/dist/config/contact-book-store.js +11 -3
  39. package/dist/config/contact-request-service.js +161 -15
  40. package/dist/config/gateway-config.js +26 -10
  41. package/dist/config/mention-mode.js +8 -24
  42. package/dist/core/agent-reload-coordinator.js +53 -0
  43. package/dist/core/auth/agent-delegation.js +0 -1
  44. package/dist/core/auth/operation-authorizer.js +62 -154
  45. package/dist/core/auth/operation-catalog.js +264 -22
  46. package/dist/core/bootstrap-messages.js +68 -0
  47. package/dist/core/bootstrap-service.js +144 -10
  48. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  49. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  50. package/dist/core/capability/skill-discovery.js +55 -0
  51. package/dist/core/channel-loader.js +24 -7
  52. package/dist/core/command/agent-control.js +14 -11
  53. package/dist/core/command/cli-intent-parser.js +9 -0
  54. package/dist/core/command/command-handler.js +467 -6
  55. package/dist/core/command/connect-menu.js +15 -0
  56. package/dist/core/command/group-menu.js +4 -4
  57. package/dist/core/command/menu-catalog.js +366 -0
  58. package/dist/core/command/menu-handler.js +213 -110
  59. package/dist/core/command/menu-protocol.js +71 -0
  60. package/dist/core/command/slash-gate.js +5 -2
  61. package/dist/core/command/slash-handler.js +45 -25
  62. package/dist/core/daemon-file-cache.js +2 -1
  63. package/dist/core/data-migration.js +9 -2
  64. package/dist/core/evolagent-registry.js +125 -35
  65. package/dist/core/evolagent.js +12 -5
  66. package/dist/core/handoff/dispatcher.js +5 -2
  67. package/dist/core/handoff/runtime.js +145 -21
  68. package/dist/core/handoff/store.js +24 -0
  69. package/dist/core/handoff/types.js +1 -0
  70. package/dist/core/inference/text-inference.js +38 -4
  71. package/dist/core/message/logical-queue-bridge.js +1 -0
  72. package/dist/core/message/mention-schema.js +126 -0
  73. package/dist/core/message/message-bridge.js +237 -79
  74. package/dist/core/message/message-log.js +23 -0
  75. package/dist/core/message/message-queue.js +20 -4
  76. package/dist/core/message/response-engine.js +54 -36
  77. package/dist/core/model/model-catalog.js +143 -24
  78. package/dist/core/model/model-diagnostics.js +28 -10
  79. package/dist/core/permission/ec-command-parser.js +156 -10
  80. package/dist/core/permission/index.js +1 -0
  81. package/dist/core/permission/readonly-shell-query.js +532 -0
  82. package/dist/core/permission/sandbox-runtime.js +22 -1
  83. package/dist/core/permission/shell-environment.js +46 -0
  84. package/dist/core/permission/tool-policy.js +292 -111
  85. package/dist/core/protected-paths.js +17 -9
  86. package/dist/core/runner-reload-transaction.js +57 -0
  87. package/dist/core/session/session-manager.js +21 -2
  88. package/dist/eck/manifest-engine.js +39 -13
  89. package/dist/index.js +644 -180
  90. package/dist/ipc.js +246 -19
  91. package/dist/response-system/coordinator.js +6 -4
  92. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  93. package/dist/response-system/modes/single-session/index.js +14 -1
  94. package/dist/response-system/selector.js +6 -5
  95. package/dist/trigger/anomaly-store.js +4 -0
  96. package/dist/trigger/script-executor.js +1 -0
  97. package/dist/utils/aid-bind.js +3 -8
  98. package/dist/utils/codex-app-server-registry.js +90 -0
  99. package/dist/utils/codex-cli.js +5 -1
  100. package/dist/utils/cross-platform.js +15 -0
  101. package/dist/utils/log-writer.js +6 -10
  102. package/dist/utils/logger.js +5 -5
  103. package/dist/utils/npm-ops.js +5 -12
  104. package/dist/utils/tool-summary.js +11 -0
  105. package/kits/docs/channels/aun.md +1 -1
  106. package/kits/docs/context-assembly.md +2 -2
  107. package/kits/docs/evolcore/agent.md +11 -6
  108. package/kits/docs/evolcore/aid.md +14 -0
  109. package/kits/docs/evolcore/msg.md +13 -0
  110. package/kits/docs/prompt-loading-architecture.md +1 -2
  111. package/kits/docs/venues/group.md +1 -1
  112. package/kits/eck_manifest.json +0 -12
  113. package/kits/rules/01-overview.md +9 -0
  114. package/kits/rules/04-relation.md +1 -1
  115. package/kits/rules/05-venue.md +2 -2
  116. package/kits/schemas/agent-config.schema.3.json +1 -1
  117. package/kits/schemas/agent-config.schema.4.json +1 -1
  118. package/kits/schemas/relation-config.schema.2.json +1 -1
  119. package/kits/schemas/role-config.schema.1.json +1 -1
  120. package/kits/schemas/single-session.schema.1.json +3 -3
  121. package/kits/schemas/single-session.schema.2.json +3 -3
  122. package/kits/templates/roles/admin.json +27 -0
  123. package/kits/templates/roles/member.json +44 -0
  124. package/kits/templates/roles/visitor.json +40 -2
  125. package/kits/templates/system-fragments/bootstrap.md +12 -6
  126. package/kits/templates/system-fragments/channel.md +6 -0
  127. package/kits/templates/system-fragments/session.md +2 -0
  128. package/package.json +3 -2
  129. package/skills/eclink/SKILL.md +15 -3
  130. package/skills/eclink/agents/openai.yaml +3 -3
  131. package/dist/core/command/evol-menu-version-gate.js +0 -39
package/dist/cli/init.js CHANGED
@@ -12,9 +12,10 @@ import { resolveEcagentConfig } from '../agents/baseagent.js';
12
12
  import { defaultProjectsRoot } from '../utils/project-path.js';
13
13
  import { WEB_CLI_BIN, WEB_PACKAGE_LATEST } from '../product.js';
14
14
  import { autostartInstalled, autostartPlatformLabel, configureAutostart } from '../utils/autostart.js';
15
+ import { askInit, isInitCancelledError, printInitCancelHint } from './init-cancel.js';
15
16
  // ==================== Helpers ====================
16
17
  function ask(rl, question) {
17
- return new Promise(resolve => rl.question(question, resolve));
18
+ return askInit(rl, question);
18
19
  }
19
20
  /** 展开用户在交互式输入中使用的 home 目录简写(shell 不会替 readline 自动做这件事)。 */
20
21
  export function expandLeadingTildePath(value, homeDir = os.homedir()) {
@@ -254,6 +255,7 @@ export async function cmdInit(options) {
254
255
  }
255
256
  else {
256
257
  // ── 4. 交互式分支(rl 生命周期封装在内部函数,tail 不引用 rl)──
258
+ printInitCancelHint();
257
259
  await runInteractive();
258
260
  }
259
261
  // ── 共享 tail(单一出口):提示创建 agent + 生成控制 AID ──
@@ -373,6 +375,7 @@ export async function initTail(options = {}) {
373
375
  const daemonConfig = loadDaemonConfig();
374
376
  let controlAidReady = !!daemonConfig.aid;
375
377
  let autoStartReady = true;
378
+ let ownerBindingInterrupted = false;
376
379
  if (daemonConfig.aid) {
377
380
  console.log(`✓ 控制 AID 已存在: ${daemonConfig.aid}`);
378
381
  }
@@ -394,8 +397,10 @@ export async function initTail(options = {}) {
394
397
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
395
398
  try {
396
399
  await handleOwnersPrompt(rl);
397
- await handleEcwebPrompt(rl);
398
- await handleAutostartPrompt(rl);
400
+ if (!ownerBindingInterrupted) {
401
+ await handleEcwebPrompt(rl);
402
+ await handleAutostartPrompt(rl);
403
+ }
399
404
  }
400
405
  finally {
401
406
  try {
@@ -407,6 +412,8 @@ export async function initTail(options = {}) {
407
412
  else if (options.autoStart !== undefined) {
408
413
  autoStartReady = applyAutostart(options.autoStart);
409
414
  }
415
+ if (ownerBindingInterrupted)
416
+ return false;
410
417
  async function handleAutostartPrompt(rl) {
411
418
  if (options.autoStart !== undefined) {
412
419
  autoStartReady = applyAutostart(options.autoStart);
@@ -446,17 +453,22 @@ export async function initTail(options = {}) {
446
453
  rl.pause();
447
454
  try {
448
455
  const { runDaemonOwnerQrBindFlow } = await import('./init-channel.js');
449
- const result = await runDaemonOwnerQrBindFlow('append');
450
- if (result?.boundAid) {
456
+ const result = await runDaemonOwnerQrBindFlow();
457
+ if (result.action === 'bound') {
451
458
  console.log(` ✓ 已配置管理者: ${result.boundAid}`);
452
459
  }
453
- else {
460
+ else if (result.action === 'manual') {
454
461
  // QR 流程失败,恢复 rl 并提示手动输入
455
462
  rl.resume();
456
463
  await promptOwnersManually(rl);
457
464
  }
465
+ else {
466
+ ownerBindingInterrupted = true;
467
+ }
458
468
  }
459
469
  catch (e) {
470
+ if (isInitCancelledError(e))
471
+ throw e;
460
472
  console.log(` ⚠ 扫码绑定不可用: ${e?.message || e}`);
461
473
  rl.resume();
462
474
  await promptOwnersManually(rl);
@@ -561,7 +573,7 @@ export async function selectInstance(rl, channelType, instances, options = {}) {
561
573
  const validOptions = letters.slice(0, instances.length + 1).split('');
562
574
  let choice = '';
563
575
  while (!validOptions.includes(choice)) {
564
- choice = (await new Promise(r => rl.question('请选择: ', r))).trim().toLowerCase();
576
+ choice = (await ask(rl, '请选择: ')).trim().toLowerCase();
565
577
  if (!validOptions.includes(choice)) {
566
578
  console.log(`无效选择,请输入 ${validOptions.join('/')}`);
567
579
  }
@@ -570,7 +582,7 @@ export async function selectInstance(rl, channelType, instances, options = {}) {
570
582
  if (choiceIndex === instances.length) {
571
583
  let name = '';
572
584
  while (!name) {
573
- name = (await new Promise(r => rl.question('请输入新配置名称: ', r))).trim();
585
+ name = (await ask(rl, '请输入新配置名称: ')).trim();
574
586
  if (!name)
575
587
  console.log(' 名称不能为空');
576
588
  if (instances.some(i => i.name === name)) {
@@ -583,7 +595,7 @@ export async function selectInstance(rl, channelType, instances, options = {}) {
583
595
  const target = instances[choiceIndex];
584
596
  console.log(`\n已选择:${target.name}`);
585
597
  if (options.confirmOverwrite !== false) {
586
- const confirm = (await new Promise(r => rl.question(`⚠️ 即将覆盖该配置,确认?(y/N) `, r))).trim().toLowerCase();
598
+ const confirm = (await ask(rl, `⚠️ 即将覆盖该配置,确认?(y/N) `)).trim().toLowerCase();
587
599
  if (confirm !== 'y' && confirm !== 'yes') {
588
600
  console.log('已取消');
589
601
  return null;
@@ -0,0 +1,41 @@
1
+ import { wantsHelp } from './help.js';
2
+ const MANAGED_TASK_COMMANDS = new Set([
3
+ 'aid',
4
+ 'agent',
5
+ 'config',
6
+ 'contact',
7
+ 'ctl',
8
+ 'fs',
9
+ 'group',
10
+ 'handoff',
11
+ 'model',
12
+ 'msg',
13
+ 'queue',
14
+ 'response',
15
+ 'status',
16
+ 'storage',
17
+ 'trigger',
18
+ 'version',
19
+ '-v',
20
+ '-V',
21
+ '--version',
22
+ ]);
23
+ export class ManagedCommandNotAllowedError extends Error {
24
+ command;
25
+ code = 'NOT_ALLOWED';
26
+ constructor(command) {
27
+ super(`Command ${command} is not available in a managed Agent task`);
28
+ this.command = command;
29
+ this.name = 'ManagedCommandNotAllowedError';
30
+ }
31
+ }
32
+ /**
33
+ * Local maintenance commands do not have daemon authorization entrypoints.
34
+ * Keep them outside managed tasks so they cannot read or mutate host state.
35
+ */
36
+ export function assertManagedTopLevelCommandAllowed(command, args, env = process.env) {
37
+ if (!env.EVOLCORE_SESSION_ID || wantsHelp(args.slice(1)) || command === '--help' || command === '-h')
38
+ return;
39
+ if (!MANAGED_TASK_COMMANDS.has(command))
40
+ throw new ManagedCommandNotAllowedError(command);
41
+ }
package/dist/cli/model.js CHANGED
@@ -46,10 +46,8 @@ function fail(formatJson, code, message, data) {
46
46
  process.exit(1);
47
47
  }
48
48
  function isManagedSessionEnv(args) {
49
- return !!process.env.EVOLCORE_SESSION_ID
50
- && !getArgValue(args, '--self')
51
- && !getArgValue(args, '--peer')
52
- && !getArgValue(args, '--role');
49
+ void args;
50
+ return !!process.env.EVOLCORE_SESSION_ID;
53
51
  }
54
52
  function isManagedTargetedWriteEnv(args) {
55
53
  return !!process.env.EVOLCORE_SESSION_ID
@@ -368,6 +366,11 @@ async function cmdInfo(args, formatJson) {
368
366
  const modelId = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
369
367
  if (!modelId)
370
368
  fail(formatJson, 'MISSING_MODEL_ID', 'info 需要 <model-id>');
369
+ if (isManagedSessionEnv(args)) {
370
+ const out = await runCtlCommand(`/model info ${modelId}`, formatJson);
371
+ printCtlResult(out, formatJson);
372
+ return;
373
+ }
371
374
  const sel = parseSelector(args, formatJson);
372
375
  const self = getArgValue(args, '--self');
373
376
  const info = await getModelInfo(modelId, self);
@@ -587,5 +590,9 @@ export async function cmdModel(args) {
587
590
  console.log(HELP);
588
591
  return;
589
592
  }
593
+ if (process.env.EVOLCORE_SESSION_ID
594
+ && (getArgValue(args, '--self') || getArgValue(args, '--peer') || getArgValue(args, '--role'))) {
595
+ fail(formatJson, 'NOT_ALLOWED', 'Managed model commands cannot select --self, --peer, or --role; they always use the authenticated current relation');
596
+ }
590
597
  await dispatch(sub, args, formatJson);
591
598
  }
@@ -1,5 +1,6 @@
1
1
  import { resolvePaths } from '../paths.js';
2
2
  import { ipcQuery } from '../ipc.js';
3
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
3
4
  import { getArgValue, isHelpFlag, wantsHelp } from './help.js';
4
5
  export async function cmdQueue(args) {
5
6
  if (args.length === 0 || isHelpFlag(args[0]) || wantsHelp(args)) {
@@ -72,7 +73,16 @@ export async function cmdQueue(args) {
72
73
  : interrupt ? 'interrupt'
73
74
  : undefined;
74
75
  const socketPath = resolvePaths().socket;
75
- const result = await ipcQuery(socketPath, {
76
+ const managed = process.env.EVOLCORE_SESSION_ID;
77
+ const result = await ipcQuery(socketPath, managed ? {
78
+ type: 'queue.op',
79
+ agent,
80
+ action,
81
+ messageId: cancelMsgId,
82
+ sessionKey,
83
+ sessionId: managed,
84
+ delegationToken: process.env[AGENT_DELEGATION_TOKEN_ENV],
85
+ } : {
76
86
  type: 'queue-snapshot',
77
87
  agent,
78
88
  action,
@@ -15,6 +15,9 @@ import { readField, writeField, determineFieldScope, normalizePeer, ModelScopeEr
15
15
  import { readFieldWithSource, resolveAgentConfig, ConfigTarget } from '../config/config-manager.js';
16
16
  import { ResponseModeRegistry } from '../response-system/registry.js';
17
17
  import { registerBuiltinModes } from '../response-system/modes/index.js';
18
+ import { ipcQuery } from '../ipc.js';
19
+ import { resolvePaths } from '../paths.js';
20
+ import { AGENT_DELEGATION_TOKEN_ENV } from '../core/auth/agent-delegation.js';
18
21
  const RESPONSE_MODE_FIELD = 'responseMode';
19
22
  const RESPONSE_MODE_PARAMS_FIELD = 'responseModeParams';
20
23
  /**
@@ -54,6 +57,71 @@ function fail(formatJson, code, message) {
54
57
  }
55
58
  process.exit(1);
56
59
  }
60
+ async function managedConfig(fieldArgs, formatJson) {
61
+ const sessionId = process.env.EVOLCORE_SESSION_ID;
62
+ const delegationToken = process.env[AGENT_DELEGATION_TOKEN_ENV];
63
+ if (!sessionId)
64
+ fail(formatJson, 'NO_SESSION', 'EVOLCORE_SESSION_ID is not set');
65
+ if (!delegationToken)
66
+ fail(formatJson, 'DELEGATION_REQUIRED', `${AGENT_DELEGATION_TOKEN_ENV} is not set`);
67
+ const response = await ipcQuery(resolvePaths().socket, {
68
+ type: 'config.op',
69
+ argv: ['config', ...fieldArgs],
70
+ sessionId,
71
+ delegationToken,
72
+ }, 10_000);
73
+ if (!response)
74
+ fail(formatJson, 'DAEMON_UNAVAILABLE', 'Unable to connect to the evolcore daemon');
75
+ if (!response.ok || !response.result?.ok) {
76
+ fail(formatJson, response.code || 'CONFIG_AUTH_FAILED', response.error || 'response config operation failed');
77
+ }
78
+ return response.result;
79
+ }
80
+ async function runManagedResponse(args, formatJson) {
81
+ if (getArgValue(args, '--self') || getArgValue(args, '--peer')) {
82
+ fail(formatJson, 'NOT_ALLOWED', 'Managed response commands always use the authenticated current relation');
83
+ }
84
+ const sub = args[0];
85
+ if (sub === 'set') {
86
+ const id = args[1];
87
+ if (!id)
88
+ fail(formatJson, 'MISSING_ID', 'set requires a mode id');
89
+ if (!buildRegistry().has(id))
90
+ fail(formatJson, 'UNKNOWN_MODE', `Unknown mode: ${id}`);
91
+ await managedConfig(['set', RESPONSE_MODE_FIELD, id], formatJson);
92
+ return emit(formatJson, { ok: true, scope: 'relation', mode: id }, () => `✓ 已设置响应模式为 ${id}(作用域: relation)`);
93
+ }
94
+ if (sub === 'reset') {
95
+ await managedConfig(['unset', RESPONSE_MODE_FIELD], formatJson);
96
+ return emit(formatJson, { ok: true, scope: 'relation' }, () => '✓ 已清除当前关系的响应模式设置');
97
+ }
98
+ if (sub === 'current') {
99
+ const modeResult = await managedConfig(['get', RESPONSE_MODE_FIELD], formatJson);
100
+ const paramsResult = await managedConfig(['get', RESPONSE_MODE_PARAMS_FIELD], formatJson);
101
+ const configuredMode = typeof modeResult.value === 'string' ? modeResult.value : undefined;
102
+ const mode = configuredMode ?? buildRegistry().getPreferredId();
103
+ return emit(formatJson, {
104
+ ok: true,
105
+ scope: 'relation',
106
+ responseMode: mode ?? null,
107
+ source: configuredMode ? 'config' : 'preferred',
108
+ sourceTarget: modeResult.source?.target ?? null,
109
+ responseModeParams: paramsResult.value ?? null,
110
+ }, () => `当前响应模式: ${mode ?? '(无)'}`);
111
+ }
112
+ if (sub === 'config') {
113
+ if (args[1] === 'set') {
114
+ fail(formatJson, 'NOT_ALLOWED', 'responseModeParams cannot be modified as an opaque object from a managed task');
115
+ }
116
+ const result = await managedConfig(['get', RESPONSE_MODE_PARAMS_FIELD], formatJson);
117
+ const params = result.value ?? {};
118
+ const modeId = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
119
+ if (modeId)
120
+ return emit(formatJson, { ok: true, mode: modeId, config: params[modeId] ?? {} }, () => `${modeId} 配置: ${JSON.stringify(params[modeId] ?? {}, null, 2)}`);
121
+ return emit(formatJson, { ok: true, responseModeParams: params }, () => `所有模式配置: ${JSON.stringify(params, null, 2)}`);
122
+ }
123
+ fail(formatJson, 'NOT_ALLOWED', `response ${sub} is not available in a managed task`);
124
+ }
57
125
  /** 解析 --self / --peer 为作用域选择器 */
58
126
  function parseSelector(args, formatJson) {
59
127
  const self = getArgValue(args, '--self');
@@ -331,6 +399,9 @@ export async function cmdResponse(args) {
331
399
  console.log(HELP);
332
400
  return;
333
401
  }
402
+ if (process.env.EVOLCORE_SESSION_ID && sub !== 'list' && sub !== 'info') {
403
+ return runManagedResponse(args, formatJson);
404
+ }
334
405
  switch (sub) {
335
406
  case 'list': return cmdList(args, formatJson);
336
407
  case 'current': return cmdCurrent(args, formatJson);
@@ -6,8 +6,7 @@ import { resolvePaths, getPackageRoot, daemonControlDir } from '../paths.js';
6
6
  import { loadDaemonConfig } from '../config-store.js';
7
7
  import * as platform from '../utils/cross-platform.js';
8
8
  import { EventBus } from '../core/event-bus.js';
9
- import { tryUpgrade, tryUpgradeAunSdk, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
10
- import { resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG } from '../aun/aid/client.js';
9
+ import { tryUpgrade, tryUpgradeGlobalPkg, resolveGlobalPkg } from '../utils/npm-ops.js';
11
10
  import { isValidAid } from '../aun/aid/index.js';
12
11
  import { msgSend } from '../aun/msg/index.js';
13
12
  import { scanInstances, cleanupInstances, writeRestartMonitor, removeRestartMonitor, isRestartMonitorWinner, findOrphanProcesses, killOrphans } from '../utils/instance-registry.js';
@@ -181,21 +180,7 @@ export async function cmdRestartMonitor() {
181
180
  await notifyDaemonOwners(p, `⚠️ evolcore 升级失败,使用当前版本继续\n${upgrade.error ?? ''}`.trim(), log);
182
181
  break;
183
182
  }
184
- // AUN SDK 版本检查与升级
185
- const aunUpgrade = await tryUpgradeAunSdk(resolveAunCoreSdkPkg, AUN_CORE_SDK_PKG);
186
- switch (aunUpgrade.status) {
187
- case 'upgraded':
188
- log(`✅ AUN SDK upgraded: ${aunUpgrade.from} → ${aunUpgrade.to}`);
189
- await notifyDaemonOwners(p, `📦 AUN SDK 已升级 ${aunUpgrade.from} → ${aunUpgrade.to}`, log);
190
- break;
191
- case 'no-update':
192
- break;
193
- case 'failed':
194
- log(`⚠ AUN SDK upgrade failed (${aunUpgrade.from} → ${aunUpgrade.to}): ${aunUpgrade.error}`);
195
- await notifyDaemonOwners(p, `⚠️ AUN SDK 升级失败,使用当前版本继续\n${aunUpgrade.error ?? ''}`.trim(), log);
196
- break;
197
- }
198
- // EC Web 版本检查与升级(已安装才检查)
183
+ // EC Web 是独立全局包,已安装时单独检查升级。
199
184
  const ecwebUpgrade = await tryUpgradeGlobalPkg(() => resolveGlobalPkg(WEB_PACKAGE_NAME), WEB_PACKAGE_NAME);
200
185
  switch (ecwebUpgrade.status) {
201
186
  case 'upgraded':
@@ -392,7 +377,7 @@ async function spawnAndWaitReady(p, log, timeout) {
392
377
  const out = fs.openSync(stdoutLog, 'a');
393
378
  const err = fs.openSync(stdoutLog, 'a');
394
379
  const appMain = path.join(getPackageRoot(), 'dist', 'index.js');
395
- const child = spawn('node', ['--no-warnings=ExperimentalWarning', appMain], {
380
+ const child = spawn(process.execPath, ['--no-warnings=ExperimentalWarning', appMain], {
396
381
  detached: true,
397
382
  stdio: ['ignore', out, err],
398
383
  windowsHide: true,
@@ -489,6 +474,7 @@ async function invokeClaude(claudePath, p, attempt, maxAttempts, timeout, log) {
489
474
  timeout,
490
475
  // Windows npm CLIs are .cmd shims; execFile needs a shell to run them.
491
476
  shell: platform.isWindows,
477
+ windowsHide: platform.isWindows,
492
478
  env: { ...process.env, CLAUDE_CODE_ENTRYPOINT: 'cli' },
493
479
  maxBuffer: 10 * 1024 * 1024,
494
480
  });
@@ -31,6 +31,10 @@ export async function cmdTrigger(args) {
31
31
  }
32
32
  return;
33
33
  }
34
+ if (process.env.EVOLCORE_SESSION_ID
35
+ && (hasOption(rest, '--file') || hasOption(rest, '--prompt-file') || hasOption(rest, '--script-path'))) {
36
+ throw new Error('Managed tasks cannot read trigger definitions, prompts, or scripts from local files; use inline prompt content');
37
+ }
34
38
  try {
35
39
  switch (sub) {
36
40
  case 'list':
@@ -35,10 +35,15 @@ export function getManagementCommandPermissions(role) {
35
35
  'role.revoke': { allow: true, scopes: ['agent'] },
36
36
  'role.policy.read': { allow: true, scopes: ['agent'] },
37
37
  'role.relation.read': { allow: true, scopes: ['agent'] },
38
+ 'agent.baseagent.update': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
39
+ 'observable.current': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true } },
40
+ 'observable.update': { allow: true, scopes: ['agent'], constraints: { requireAgentOwner: true, targetCurrentAgentOnly: true } },
38
41
  'config.get': { allow: true, scopes: ['agent', 'relation'] },
39
42
  'config.set': { allow: true, scopes: ['agent', 'relation'] },
40
43
  'config.unset': { allow: true, scopes: ['agent', 'relation'] },
41
44
  'role.policy.write': { allow: true, dangerous: true, scopes: ['agent'], constraints: { requireAgentAdmin: true } },
45
+ 'ec.aid.show': { allow: true, dangerous: true, scopes: ['agent'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
46
+ 'ec.aid.agentmd.put': { allow: true, dangerous: true, scopes: ['agent'], constraints: { targetCurrentAgentOnly: true, requireAgentAdmin: true } },
42
47
  '*': { allow: true },
43
48
  // Reload is valid from an Agent's own channel and the daemon control plane.
44
49
  // The control-channel gate still requires a daemon owner for cross-Agent reloads.
@@ -184,17 +184,25 @@ function mutateContactBookPreparedSyncInternal(selfAid, prepare) {
184
184
  value: prepared.value,
185
185
  };
186
186
  }
187
- prepared.beforeCommit?.({
187
+ const preparedChanges = prepared.beforeCommit?.({
188
188
  contact: next,
189
189
  previousContactRevision: previousRevision,
190
190
  contactRevision: nextRevision,
191
191
  });
192
192
  const before = readTextOrNull(file);
193
193
  const after = `${JSON.stringify(next, null, 2)}\n`;
194
- const changes = [{ file, before, after }];
194
+ const additionalChanges = preparedChanges === undefined
195
+ ? []
196
+ : Array.isArray(preparedChanges) ? preparedChanges : [preparedChanges];
197
+ const changes = [
198
+ { file, before, after },
199
+ ...additionalChanges,
200
+ ];
201
+ validateTransactionChanges(selfAid, changes);
195
202
  writeJournal(selfAid, { schemaVersion: 1, state: 'prepared', selfAid, changes });
196
203
  try {
197
- applyTransactionChange(changes[0]);
204
+ for (const change of changes)
205
+ applyTransactionChange(change);
198
206
  writeJournal(selfAid, { schemaVersion: 1, state: 'committed', selfAid, changes });
199
207
  removeJournal(selfAid);
200
208
  }