evolcore 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bin/codex-managed-hook.mjs +80 -0
  3. package/dist/agents/claude-runner.js +35 -2
  4. package/dist/agents/codex-app-server-client.js +120 -14
  5. package/dist/agents/codex-runner.js +273 -35
  6. package/dist/agents/ecagent-runner.js +36 -4
  7. package/dist/agents/gemini-runner.js +1 -0
  8. package/dist/aun/aid/client.js +11 -21
  9. package/dist/aun/aid/managed-operation.js +107 -0
  10. package/dist/aun/msg/group.js +81 -12
  11. package/dist/aun/msg/managed-operation.js +804 -0
  12. package/dist/aun/msg/mention-schema.js +20 -0
  13. package/dist/aun/msg/p2p.js +7 -0
  14. package/dist/channels/aun.js +288 -108
  15. package/dist/channels/daemon.js +13 -0
  16. package/dist/cli/agent-command.js +56 -8
  17. package/dist/cli/agent.js +170 -6
  18. package/dist/cli/aun-commands.js +270 -69
  19. package/dist/cli/bench.js +12 -3
  20. package/dist/cli/daemon-commands.js +31 -31
  21. package/dist/cli/fs-command.js +60 -0
  22. package/dist/cli/handoff-command.js +3 -0
  23. package/dist/cli/index.js +30 -2
  24. package/dist/cli/managed-command-guard.js +41 -0
  25. package/dist/cli/model.js +11 -4
  26. package/dist/cli/queue-command.js +11 -1
  27. package/dist/cli/response.js +71 -0
  28. package/dist/cli/restart-monitor.js +4 -18
  29. package/dist/cli/trigger-command.js +4 -0
  30. package/dist/config/builtin-roles.js +4 -0
  31. package/dist/config/contact-book-store.js +11 -3
  32. package/dist/config/contact-request-service.js +161 -15
  33. package/dist/config/mention-mode.js +8 -24
  34. package/dist/core/auth/agent-delegation.js +0 -1
  35. package/dist/core/auth/operation-authorizer.js +30 -7
  36. package/dist/core/auth/operation-catalog.js +187 -25
  37. package/dist/core/bootstrap-messages.js +18 -0
  38. package/dist/core/bootstrap-service.js +63 -4
  39. package/dist/core/capability/providers/claude-capability-provider.js +9 -31
  40. package/dist/core/capability/providers/codex-capability-provider.js +4 -15
  41. package/dist/core/capability/skill-discovery.js +55 -0
  42. package/dist/core/channel-loader.js +1 -1
  43. package/dist/core/command/cli-intent-parser.js +9 -0
  44. package/dist/core/command/command-handler.js +467 -6
  45. package/dist/core/command/connect-menu.js +15 -0
  46. package/dist/core/command/group-menu.js +4 -4
  47. package/dist/core/command/menu-catalog.js +366 -0
  48. package/dist/core/command/menu-handler.js +147 -35
  49. package/dist/core/command/menu-protocol.js +71 -0
  50. package/dist/core/command/slash-gate.js +5 -2
  51. package/dist/core/command/slash-handler.js +41 -21
  52. package/dist/core/daemon-file-cache.js +2 -1
  53. package/dist/core/data-migration.js +9 -2
  54. package/dist/core/evolagent.js +4 -2
  55. package/dist/core/handoff/dispatcher.js +5 -2
  56. package/dist/core/handoff/runtime.js +145 -21
  57. package/dist/core/handoff/store.js +24 -0
  58. package/dist/core/handoff/types.js +1 -0
  59. package/dist/core/message/logical-queue-bridge.js +1 -0
  60. package/dist/core/message/mention-schema.js +126 -0
  61. package/dist/core/message/message-bridge.js +236 -78
  62. package/dist/core/message/message-log.js +1 -0
  63. package/dist/core/message/message-queue.js +1 -0
  64. package/dist/core/message/response-engine.js +54 -36
  65. package/dist/core/permission/ec-command-parser.js +156 -10
  66. package/dist/core/permission/sandbox-runtime.js +22 -1
  67. package/dist/core/permission/tool-policy.js +73 -30
  68. package/dist/core/protected-paths.js +7 -2
  69. package/dist/core/session/session-manager.js +21 -2
  70. package/dist/eck/manifest-engine.js +39 -13
  71. package/dist/index.js +384 -98
  72. package/dist/ipc.js +218 -9
  73. package/dist/response-system/coordinator.js +6 -4
  74. package/dist/response-system/engines/v1/proactive-flow.js +26 -8
  75. package/dist/response-system/modes/single-session/index.js +14 -1
  76. package/dist/response-system/selector.js +6 -5
  77. package/dist/trigger/anomaly-store.js +4 -0
  78. package/dist/trigger/script-executor.js +1 -0
  79. package/dist/utils/codex-app-server-registry.js +90 -0
  80. package/dist/utils/codex-cli.js +5 -1
  81. package/dist/utils/cross-platform.js +15 -0
  82. package/dist/utils/npm-ops.js +5 -12
  83. package/dist/utils/tool-summary.js +11 -0
  84. package/kits/docs/channels/aun.md +1 -1
  85. package/kits/docs/context-assembly.md +2 -2
  86. package/kits/docs/evolcore/agent.md +11 -6
  87. package/kits/docs/evolcore/aid.md +14 -0
  88. package/kits/docs/prompt-loading-architecture.md +1 -2
  89. package/kits/docs/venues/group.md +1 -1
  90. package/kits/eck_manifest.json +0 -12
  91. package/kits/rules/04-relation.md +1 -1
  92. package/kits/rules/05-venue.md +2 -2
  93. package/kits/schemas/single-session.schema.1.json +3 -3
  94. package/kits/schemas/single-session.schema.2.json +3 -3
  95. package/kits/templates/roles/admin.json +22 -0
  96. package/kits/templates/roles/member.json +27 -0
  97. package/kits/templates/roles/visitor.json +33 -3
  98. package/kits/templates/system-fragments/bootstrap.md +1 -1
  99. package/kits/templates/system-fragments/channel.md +1 -1
  100. package/kits/templates/system-fragments/session.md +1 -1
  101. package/package.json +2 -2
  102. package/dist/core/command/evol-menu-version-gate.js +0 -39
@@ -0,0 +1,107 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { resolveRoot } from '../../paths.js';
4
+ import { agentmdGet, agentmdPut } from './agentmd.js';
5
+ import { aidLookup, aidShow } from './identity.js';
6
+ import { isValidAid } from './validation.js';
7
+ export class ManagedAidOperationError extends Error {
8
+ code;
9
+ constructor(code, message) {
10
+ super(message);
11
+ this.code = code;
12
+ this.name = 'ManagedAidOperationError';
13
+ }
14
+ }
15
+ function normalizeAid(value) {
16
+ const aid = String(value || '').trim();
17
+ return aid.startsWith('@') ? aid.slice(1) : aid;
18
+ }
19
+ function hasOnlyOptionalJsonFormat(args, aidIndex) {
20
+ const suffix = args.slice(aidIndex + 1);
21
+ return suffix.length === 0 || (suffix.length === 2 && suffix[0] === '--format' && suffix[1] === 'json');
22
+ }
23
+ function parseAid(value) {
24
+ const aid = normalizeAid(value);
25
+ if (!aid)
26
+ return { ok: false, code: 'INVALID_ARGUMENT', reason: 'missing AID' };
27
+ if (!isValidAid(aid))
28
+ return { ok: false, code: 'INVALID_AID', reason: `invalid AID: ${aid}` };
29
+ return { ok: true, aid };
30
+ }
31
+ /**
32
+ * The daemon accepts only the self-scoped AID commands exposed to managed
33
+ * tasks. Parsing here is deliberately narrower than the standalone CLI.
34
+ */
35
+ export function resolveManagedAidOperation(argv) {
36
+ const args = argv[0] === 'aid' ? argv.slice(1) : argv;
37
+ const subcommand = args[0];
38
+ if ((subcommand === 'show' || subcommand === 'lookup') && hasOnlyOptionalJsonFormat(args, 1)) {
39
+ const parsedAid = parseAid(args[1]);
40
+ if (!parsedAid.ok)
41
+ return parsedAid;
42
+ return {
43
+ ok: true,
44
+ command: {
45
+ kind: subcommand,
46
+ aid: parsedAid.aid,
47
+ operationId: `ec.aid.${subcommand}`,
48
+ canonicalArgv: ['aid', subcommand, parsedAid.aid],
49
+ },
50
+ };
51
+ }
52
+ if (subcommand === 'agentmd' && (args[1] === 'get' || args[1] === 'put') && hasOnlyOptionalJsonFormat(args, 2)) {
53
+ const parsedAid = parseAid(args[2]);
54
+ if (!parsedAid.ok)
55
+ return parsedAid;
56
+ const kind = `agentmd.${args[1]}`;
57
+ return {
58
+ ok: true,
59
+ command: {
60
+ kind,
61
+ aid: parsedAid.aid,
62
+ operationId: `ec.aid.${kind}`,
63
+ canonicalArgv: ['aid', 'agentmd', args[1], parsedAid.aid],
64
+ },
65
+ };
66
+ }
67
+ return {
68
+ ok: false,
69
+ code: 'NOT_ALLOWED',
70
+ reason: 'Managed AID operations only allow exact self-scoped show, lookup, agentmd get, or agentmd put commands with an optional --format json suffix',
71
+ };
72
+ }
73
+ const defaultDependencies = () => ({
74
+ root: resolveRoot(),
75
+ aidShow,
76
+ aidLookup,
77
+ agentmdGet,
78
+ agentmdPut,
79
+ existsSync: fs.existsSync,
80
+ readFileSync: fs.readFileSync,
81
+ });
82
+ /** Execute a validated AID operation from the daemon-owned host filesystem. */
83
+ export async function executeManagedAidOperation(command, overrides = {}) {
84
+ const deps = { ...defaultDependencies(), ...overrides };
85
+ const aunPath = deps.root;
86
+ switch (command.kind) {
87
+ case 'show':
88
+ return { kind: command.kind, aid: command.aid, value: await deps.aidShow(command.aid, { aunPath }) };
89
+ case 'lookup':
90
+ return { kind: command.kind, aid: command.aid, value: await deps.aidLookup(command.aid) };
91
+ case 'agentmd.get':
92
+ return {
93
+ kind: command.kind,
94
+ aid: command.aid,
95
+ value: await deps.agentmdGet(command.aid, { aunPath, withVerification: true }),
96
+ };
97
+ case 'agentmd.put': {
98
+ const localPath = path.join(aunPath, 'AIDs', command.aid, 'agent.md');
99
+ if (!deps.existsSync(localPath)) {
100
+ throw new ManagedAidOperationError('LOCAL_AGENTMD_MISSING', `local agent.md not found: ${command.aid}`);
101
+ }
102
+ const content = deps.readFileSync(localPath, 'utf-8');
103
+ await deps.agentmdPut(content, { aid: command.aid, aunPath });
104
+ return { kind: command.kind, aid: command.aid, path: localPath };
105
+ }
106
+ }
107
+ }
@@ -13,6 +13,7 @@ import { readBestTaskRuntimeContext } from '../../cli/task-context.js';
13
13
  import { ipcQuery } from '../../ipc.js';
14
14
  import { resolvePaths } from '../../paths.js';
15
15
  import { AGENT_DELEGATION_TOKEN_ENV } from '../../core/auth/agent-delegation.js';
16
+ import { normalizeAunMentionEntries } from './mention-schema.js';
16
17
  function buildGroupPayload(body) {
17
18
  return body.mode === 'text' ? { type: 'text', text: body.text } : { ...body.payload };
18
19
  }
@@ -189,8 +190,18 @@ export async function groupSend(args) {
189
190
  break;
190
191
  }
191
192
  }
192
- if (args.mentions && args.mentions.length > 0) {
193
- payload.mentions = args.mentions;
193
+ const payloadMentions = Object.prototype.hasOwnProperty.call(payload, 'mentions')
194
+ ? normalizeAunMentionEntries(payload.mentions)
195
+ : undefined;
196
+ if (args.mentions !== undefined) {
197
+ const normalizedMentions = normalizeAunMentionEntries(args.mentions);
198
+ if (normalizedMentions.length > 0)
199
+ payload.mentions = normalizedMentions;
200
+ else if (payloadMentions !== undefined)
201
+ payload.mentions = payloadMentions;
202
+ }
203
+ else if (payloadMentions !== undefined) {
204
+ payload.mentions = payloadMentions;
194
205
  }
195
206
  applyGroupRoutingPayloadFields(payload, args, runtimeContext);
196
207
  const encrypt = resolveAunMessageEncrypt(args.encrypt);
@@ -305,8 +316,9 @@ export async function groupInfo(args) {
305
316
  }
306
317
  }
307
318
  export async function groupList(args) {
308
- const conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
319
+ let conn;
309
320
  try {
321
+ conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
310
322
  const params = {};
311
323
  if (args.size !== undefined)
312
324
  params.size = args.size;
@@ -329,7 +341,8 @@ export async function groupList(args) {
329
341
  return formatRpcError(e);
330
342
  }
331
343
  finally {
332
- await conn.close();
344
+ if (conn)
345
+ await conn.close();
333
346
  }
334
347
  }
335
348
  export async function groupUpdate(args) {
@@ -675,7 +688,7 @@ export async function groupUpdateRules(args) {
675
688
  }
676
689
  }
677
690
  const GROUP_RULES_FILE_PATH = '/rules.md';
678
- const MAX_GROUP_RULES_BYTES = 4 * 1024;
691
+ export const MAX_GROUP_RULES_BYTES = 4 * 1024;
679
692
  const MTIME_TOLERANCE_MS = 1;
680
693
  export async function groupRulesFileGet(args) {
681
694
  return withAunClient(args.from, args, async (client) => {
@@ -742,13 +755,26 @@ export async function groupRulesFileGet(args) {
742
755
  }
743
756
  export async function groupRulesFileSet(args) {
744
757
  return withAunClient(args.from, args, async (client) => {
745
- assertLocalRulesFile(args.filePath);
746
- const upload = await client.group.fs.cp(args.filePath, `${args.groupId}:${GROUP_RULES_FILE_PATH}`, {
747
- force: true,
748
- overwrite: true,
749
- parents: true,
750
- contentType: 'text/markdown; charset=utf-8',
751
- });
758
+ if ((args.filePath === undefined) === (args.content === undefined)) {
759
+ throw new Error('规则文件必须且只能提供 filePath content');
760
+ }
761
+ let upload;
762
+ if (args.content !== undefined) {
763
+ const bytes = Buffer.from(args.content, 'utf8');
764
+ if (!args.content || bytes.byteLength > MAX_GROUP_RULES_BYTES || bytes.toString('utf8') !== args.content) {
765
+ throw new Error(`规则内容必须是非空 UTF-8,且不超过 ${MAX_GROUP_RULES_BYTES} bytes`);
766
+ }
767
+ upload = await uploadGroupRulesBytes(client, args.groupId, bytes);
768
+ }
769
+ else {
770
+ assertLocalRulesFile(args.filePath);
771
+ upload = await client.group.fs.cp(args.filePath, `${args.groupId}:${GROUP_RULES_FILE_PATH}`, {
772
+ force: true,
773
+ overwrite: true,
774
+ parents: true,
775
+ contentType: 'text/markdown; charset=utf-8',
776
+ });
777
+ }
752
778
  const published = await publishCurrentRulesFile(client, args.groupId, args.from);
753
779
  return { ...published, upload };
754
780
  });
@@ -984,6 +1010,49 @@ function assertLocalRulesFile(filePath) {
984
1010
  throw new Error(`规则文件不是有效 UTF-8: ${errorMessage(e)}`);
985
1011
  }
986
1012
  }
1013
+ async function uploadGroupRulesBytes(client, groupId, bytes) {
1014
+ const remotePath = `${groupId}:${GROUP_RULES_FILE_PATH}`;
1015
+ const base = {
1016
+ path: remotePath,
1017
+ size_bytes: bytes.byteLength,
1018
+ sha256: sha256Hex(bytes),
1019
+ content_type: 'text/markdown; charset=utf-8',
1020
+ force: true,
1021
+ parents: true,
1022
+ };
1023
+ const check = await client.call('group.fs.check_upload', base);
1024
+ if (isRecord(check) && check.within_limit === false) {
1025
+ throw new Error('规则文件超过 group.fs 上传限制');
1026
+ }
1027
+ if (isRecord(check) && (check.instant === true || check.dedup_hit === true || check.skip_upload === true)) {
1028
+ return client.call('group.fs.complete_upload', {
1029
+ ...base,
1030
+ skip_blob: true,
1031
+ ...(check.session_id !== undefined ? { session_id: check.session_id } : {}),
1032
+ });
1033
+ }
1034
+ const session = await client.call('group.fs.create_upload_session', base);
1035
+ if (!isRecord(session))
1036
+ throw new Error('group.fs.create_upload_session returned invalid response');
1037
+ const uploadUrl = stringField(session, ['upload_url', 'url']);
1038
+ if (!uploadUrl)
1039
+ throw new Error('group.fs.create_upload_session did not return upload_url');
1040
+ const headers = {};
1041
+ if (isRecord(session.headers)) {
1042
+ for (const [key, value] of Object.entries(session.headers)) {
1043
+ if (value !== undefined && value !== null)
1044
+ headers[key] = String(value);
1045
+ }
1046
+ }
1047
+ if (!Object.keys(headers).some(key => key.toLowerCase() === 'content-type')) {
1048
+ headers['Content-Type'] = base.content_type;
1049
+ }
1050
+ await client.group.fs.lowlevel.httpPut(uploadUrl, bytes, headers);
1051
+ return client.call('group.fs.complete_upload', {
1052
+ ...base,
1053
+ ...((session.session_id ?? session.id) !== undefined ? { session_id: session.session_id ?? session.id } : {}),
1054
+ });
1055
+ }
987
1056
  async function readGroupRulesBytes(client, groupId) {
988
1057
  const remoteRef = `${groupId}:${GROUP_RULES_FILE_PATH}`;
989
1058
  const ticket = await client.call('group.fs.create_download_ticket', { path: remoteRef });