evolcore 0.0.3 → 0.0.4

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 (143) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +45 -10
  3. package/bin/ec-safe-output.js +89 -24
  4. package/dist/agents/baseagent.js +46 -0
  5. package/dist/agents/claude-runner.js +1 -31
  6. package/dist/agents/codex-app-server-client.js +68 -0
  7. package/dist/agents/codex-runner.js +157 -5
  8. package/dist/agents/runner-types.js +2 -2
  9. package/dist/aun/aid/agentmd.js +79 -0
  10. package/dist/aun/aid/encryption-seed-policy.js +29 -0
  11. package/dist/aun/aid/index.js +1 -1
  12. package/dist/aun/aid/store.js +2 -5
  13. package/dist/channels/aun.js +220 -112
  14. package/dist/channels/daemon.js +18 -4
  15. package/dist/channels/dingtalk.js +52 -137
  16. package/dist/channels/feishu.js +56 -4
  17. package/dist/channels/qqbot.js +23 -1
  18. package/dist/channels/wechat.js +303 -155
  19. package/dist/channels/wecom.js +383 -7
  20. package/dist/cli/aun-commands.js +11 -11
  21. package/dist/cli/handoff-command.js +2 -1
  22. package/dist/cli/init-channel.js +185 -67
  23. package/dist/cli/init.js +7 -5
  24. package/dist/cli/trigger-command.js +92 -11
  25. package/dist/config/access-policy-domain.js +38 -0
  26. package/dist/config/access-policy.js +134 -0
  27. package/dist/config/builtin-role-templates.js +27 -14
  28. package/dist/config/builtin-roles.js +25 -6
  29. package/dist/config/config-field-policy.js +17 -5
  30. package/dist/config/config-manager.js +198 -22
  31. package/dist/config/config-operation-service.js +35 -38
  32. package/dist/config/contact-bind-code.js +274 -0
  33. package/dist/config/contact-book-store.js +173 -5
  34. package/dist/config/contact-book.js +32 -0
  35. package/dist/config/contact-operation-service.js +9 -3
  36. package/dist/config/contact-request-service.js +331 -0
  37. package/dist/config/peer-role-resolver.js +3 -1
  38. package/dist/config/schema-registry.js +49 -24
  39. package/dist/config-store.js +14 -2
  40. package/dist/core/auth/agent-delegation.js +105 -11
  41. package/dist/core/auth/authorization-audit.js +6 -0
  42. package/dist/core/auth/operation-authorizer.js +8 -0
  43. package/dist/core/auth/operation-catalog.js +51 -3
  44. package/dist/core/auth/trigger-authorization.js +15 -0
  45. package/dist/core/bootstrap-service.js +2 -9
  46. package/dist/core/channel-loader.js +6 -2
  47. package/dist/core/command/command-handler.js +10 -13
  48. package/dist/core/command/connect-menu.js +249 -24
  49. package/dist/core/command/evol-menu-version-gate.js +38 -0
  50. package/dist/core/command/group-menu.js +421 -0
  51. package/dist/core/command/menu-handler.js +269 -85
  52. package/dist/core/command/menu-protocol.js +8 -2
  53. package/dist/core/command/menu-token-store.js +102 -0
  54. package/dist/core/command/slash-gate.js +1 -1
  55. package/dist/core/command/slash-handler.js +158 -31
  56. package/dist/core/daemon-file-cache.js +28 -0
  57. package/dist/core/event-catalog.js +29 -0
  58. package/dist/core/evolagent-registry.js +4 -39
  59. package/dist/core/handoff/runtime.js +162 -37
  60. package/dist/core/handoff/store.js +46 -2
  61. package/dist/core/handoff/types.js +1 -0
  62. package/dist/core/inference/text-inference.js +16 -74
  63. package/dist/core/message/file-markers.js +7 -0
  64. package/dist/core/message/im-renderer.js +18 -14
  65. package/dist/core/message/inbound-admission.js +124 -0
  66. package/dist/core/message/message-bridge.js +616 -74
  67. package/dist/core/message/message-log.js +1 -0
  68. package/dist/core/message/message-queue.js +185 -10
  69. package/dist/core/message/peer-mode.js +7 -8
  70. package/dist/core/message/response-engine.js +381 -79
  71. package/dist/core/permission/approval-gateway.js +17 -10
  72. package/dist/core/permission/ec-command-parser.js +101 -46
  73. package/dist/core/permission/tool-policy.js +69 -24
  74. package/dist/core/protected-paths.js +36 -11
  75. package/dist/core/session/session-manager.js +25 -3
  76. package/dist/core/session/session-mapper.js +2 -0
  77. package/dist/core/session/session-renew.js +125 -69
  78. package/dist/core/session/session-turn-coordinator.js +5 -1
  79. package/dist/eck/kit-renderer.js +12 -1
  80. package/dist/eck/message-renderer.js +79 -1
  81. package/dist/index.js +224 -89
  82. package/dist/ipc.js +81 -4
  83. package/dist/paths.js +3 -0
  84. package/dist/response-system/config-resolver.js +29 -0
  85. package/dist/response-system/coordinator.js +8 -32
  86. package/dist/response-system/engines/v1/proactive-flow.js +1 -1
  87. package/dist/response-system/index.js +1 -0
  88. package/dist/response-system/modes/single-session/index.js +7 -4
  89. package/dist/trigger/parser.js +55 -15
  90. package/dist/trigger/patch.js +4 -1
  91. package/dist/trigger/scheduler.js +441 -39
  92. package/dist/utils/error-dict.json +7 -0
  93. package/dist/utils/evolcore-version.js +21 -0
  94. package/dist/utils/logger.js +2 -2
  95. package/dist/utils/stable-semver.js +21 -0
  96. package/dist/utils/stats.js +33 -9
  97. package/kits/docs/channels/aun.md +4 -13
  98. package/kits/docs/evolcore/INDEX.md +1 -1
  99. package/kits/docs/evolcore/config.md +47 -2
  100. package/kits/docs/evolcore/contact.md +7 -3
  101. package/kits/docs/evolcore/group-rules.md +46 -4
  102. package/kits/docs/evolcore/group.md +4 -4
  103. package/kits/docs/evolcore/msg.md +5 -5
  104. package/kits/docs/evolcore/trigger.md +25 -8
  105. package/kits/docs/path-registry.md +36 -17
  106. package/kits/eck_message_manifest.json +12 -1
  107. package/kits/migrations/migrate-contact-book-v2.mjs +7 -0
  108. package/kits/rules/01-overview.md +17 -7
  109. package/kits/rules/02-navigation.md +38 -18
  110. package/kits/rules/03-identity.md +28 -24
  111. package/kits/rules/04-relation.md +44 -28
  112. package/kits/rules/05-venue.md +31 -15
  113. package/kits/rules/06-channel.md +11 -7
  114. package/kits/schemas/_meta.json +18 -7
  115. package/kits/schemas/agent-config.schema.7.json +303 -0
  116. package/kits/schemas/agent-config.schema.8.json +304 -0
  117. package/kits/schemas/agent-config.schema.9.json +374 -0
  118. package/kits/schemas/contact-book.schema.3.json +67 -0
  119. package/kits/schemas/daemon.schema.1.json +3 -2
  120. package/kits/schemas/daemon.schema.2.json +101 -0
  121. package/kits/schemas/daemon.schema.3.json +123 -0
  122. package/kits/schemas/defaults.schema.2.json +85 -0
  123. package/kits/schemas/defaults.schema.3.json +73 -0
  124. package/kits/schemas/relation-config.schema.6.json +46 -0
  125. package/kits/schemas/relation-config.schema.7.json +59 -0
  126. package/kits/schemas/single-session.schema.2.json +57 -0
  127. package/kits/templates/message-fragments/handoff-context-to-target.md +9 -0
  128. package/kits/templates/message-fragments/handoff-request-to-target.md +14 -8
  129. package/kits/templates/message-fragments/handoff-response-to-origin.md +5 -6
  130. package/kits/templates/roles/admin.json +46 -0
  131. package/kits/templates/roles/member.json +4 -0
  132. package/kits/templates/roles/visitor.json +4 -0
  133. package/kits/templates/system-fragments/channel.md +12 -2
  134. package/kits/templates/system-fragments/identity.md +3 -1
  135. package/kits/templates/system-fragments/relation.md +1 -1
  136. package/kits/templates/system-fragments/session.md +6 -2
  137. package/package.json +4 -2
  138. package/MIGRATION-0.5.0.md +0 -378
  139. package/ROLE_ACCESS_CONTROL.md +0 -174
  140. package/dist/channels/contact-bind-code.js +0 -134
  141. package/dist/channels/wecom-card.js +0 -101
  142. package/dist/channels/wecom-onboarding.js +0 -82
  143. package/dist/channels/wecom-state.js +0 -191
@@ -18,6 +18,8 @@ export const USER_PLANE_CAPABILITY_CEILING = {
18
18
  'chatmode.update',
19
19
  'mentionmode.current',
20
20
  'mentionmode.update',
21
+ 'group.mentionmode.current',
22
+ 'group.rulespolicy.current',
21
23
  'session.list',
22
24
  'session.create',
23
25
  'session.rename',
@@ -415,6 +417,12 @@ function checkConfigFieldPolicy(ctx, policy, resolvedConfigOp) {
415
417
  if (!resolvedConfigOp.route || (resolvedConfigOp.fieldRule.class !== 'safe-scalar' && resolvedConfigOp.fieldRule.class !== 'safe-readonly-object')) {
416
418
  return { ok: false, reason: `Config field ${field} is not available to user roles` };
417
419
  }
420
+ if (policy === 'role-overridable-write'
421
+ && resolvedConfigOp.fieldRule.access === 'owner-only'
422
+ && ctx.role !== 'owner'
423
+ && !ctx.isDaemonOwner) {
424
+ return { ok: false, reason: `Config field ${field} can only be changed by an owner` };
425
+ }
418
426
  const roleDef = getRoleDefinition(ctx.role, ctx.selfAid);
419
427
  const fieldPermission = roleDef
420
428
  ? resolveRoleFieldPermission(roleDef.permissions || {}, field)
@@ -133,6 +133,46 @@ const OPERATIONS = [
133
133
  description: 'Update group mention mode',
134
134
  sources: ['slash', 'menu'],
135
135
  },
136
+ {
137
+ id: 'group.list',
138
+ category: 'read',
139
+ dangerous: false,
140
+ defaultScopes: ['agent'],
141
+ description: 'List joined AUN groups',
142
+ sources: ['menu'],
143
+ },
144
+ {
145
+ id: 'group.mentionmode.current',
146
+ category: 'read',
147
+ dangerous: false,
148
+ defaultScopes: ['relation', 'agent'],
149
+ description: 'Read a group mention mode',
150
+ sources: ['menu'],
151
+ },
152
+ {
153
+ id: 'group.mentionmode.update',
154
+ category: 'write-own',
155
+ dangerous: false,
156
+ defaultScopes: ['relation', 'agent'],
157
+ description: 'Update a group mention mode',
158
+ sources: ['menu'],
159
+ },
160
+ {
161
+ id: 'group.rulespolicy.current',
162
+ category: 'read',
163
+ dangerous: false,
164
+ defaultScopes: ['relation', 'agent'],
165
+ description: 'Read a group rules loading policy',
166
+ sources: ['menu'],
167
+ },
168
+ {
169
+ id: 'group.rulespolicy.update',
170
+ category: 'write-own',
171
+ dangerous: false,
172
+ defaultScopes: ['relation', 'agent'],
173
+ description: 'Update a group rules loading policy',
174
+ sources: ['menu'],
175
+ },
136
176
  {
137
177
  id: 'session.list',
138
178
  category: 'read',
@@ -180,7 +220,7 @@ const OPERATIONS = [
180
220
  dangerous: false,
181
221
  defaultScopes: ['filesystem'],
182
222
  description: '获取文件内容(需路径沙箱检查)',
183
- sources: ['menu'],
223
+ sources: ['slash', 'menu'],
184
224
  },
185
225
  // ── Trigger Operations ──
186
226
  {
@@ -317,7 +357,7 @@ const OPERATIONS = [
317
357
  category: 'write-agent',
318
358
  dangerous: false,
319
359
  defaultScopes: ['agent'],
320
- description: 'Block or unblock an AUN contact',
360
+ description: 'Block or unblock a canonical contact across bound private channels',
321
361
  sources: ['agent-tool'],
322
362
  },
323
363
  {
@@ -357,7 +397,15 @@ const OPERATIONS = [
357
397
  category: 'write-agent',
358
398
  dangerous: false,
359
399
  defaultScopes: ['agent'],
360
- description: 'Add contacts or modify contact status (block/unblock)',
400
+ description: 'Manage contacts, contact requests, and allowed group channels',
401
+ sources: ['menu', 'ecweb', 'control'],
402
+ },
403
+ {
404
+ id: 'connect.access.write',
405
+ category: 'write-agent',
406
+ dangerous: false,
407
+ defaultScopes: ['agent'],
408
+ description: 'Manage owner-only Agent access policy and request limit settings',
361
409
  sources: ['menu', 'ecweb', 'control'],
362
410
  },
363
411
  // Agent Operations
@@ -0,0 +1,15 @@
1
+ const CROSS_AGENT_READ_OPERATIONS = new Set([
2
+ 'trigger.list',
3
+ 'trigger.show',
4
+ 'trigger.history',
5
+ ]);
6
+ export function isCrossAgentTriggerOperationAllowed(input) {
7
+ if (input.control || input.taskAgentAid === input.targetAgentAid)
8
+ return true;
9
+ if (!input.taskAgentAid || !input.targetManagement)
10
+ return false;
11
+ return CROSS_AGENT_READ_OPERATIONS.has(input.operation);
12
+ }
13
+ export function isCrossAgentTriggerReadOperation(operation) {
14
+ return CROSS_AGENT_READ_OPERATIONS.has(operation);
15
+ }
@@ -2,6 +2,7 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { randomBytes } from 'crypto';
4
4
  import { kitsTemplatesDir, agentMdPath } from '../paths.js';
5
+ import { resolveAgentDisplayName } from '../aun/aid/agentmd.js';
5
6
  import { logger } from '../utils/logger.js';
6
7
  import { loadAgent, saveAgent } from '../config-store.js';
7
8
  import { normalizeAgentLifecycle, withLifecycleForWrite } from '../config/lifecycle.js';
@@ -130,15 +131,7 @@ export class BootstrapService {
130
131
  return renderTemplate(template, vars).trim();
131
132
  }
132
133
  resolveAgentDisplayName(aid) {
133
- try {
134
- const content = fs.readFileSync(agentMdPath(aid), 'utf-8');
135
- const fm = content.match(/^---\n([\s\S]*?)\n---/)?.[1] || '';
136
- const name = fm.match(/^name:\s*["']?(.+?)["']?\s*$/m)?.[1]?.trim();
137
- if (name)
138
- return name;
139
- }
140
- catch { }
141
- return aid.split('.')[0];
134
+ return resolveAgentDisplayName(aid) || aid.split('.')[0];
142
135
  }
143
136
  resolveBaseagent(agent, aid) {
144
137
  try {
@@ -26,7 +26,11 @@ export function showActivitiesPolicy(mode, chatType, _identity) {
26
26
  }
27
27
  // ── ChannelLoader ──────────────────────────────────────────────────────────
28
28
  export class ChannelLoader {
29
+ processDebug;
29
30
  plugins = new Map();
31
+ constructor(processDebug) {
32
+ this.processDebug = processDebug;
33
+ }
30
34
  register(plugin) {
31
35
  if (this.plugins.has(plugin.name)) {
32
36
  throw new Error(`Channel plugin '${plugin.name}' already registered`);
@@ -46,7 +50,7 @@ export class ChannelLoader {
46
50
  const ctx = {
47
51
  agentName: agent.aid,
48
52
  defaultProjectPath: agent.config.projects?.defaultPath ?? process.cwd(),
49
- debug: agent.config.debug,
53
+ debug: this.processDebug,
50
54
  };
51
55
  // Build the full list of config instances to create.
52
56
  // AUN is synthesised from agent.aid; any explicit aun entry in channels[] is skipped.
@@ -252,7 +256,7 @@ export function buildReloadHooks(deps) {
252
256
  const ctx = {
253
257
  agentName: agent.aid ?? agent.config?.aid,
254
258
  defaultProjectPath: agent.config?.projects?.defaultPath ?? process.cwd(),
255
- debug: agent.config?.debug,
259
+ debug: channelLoader.processDebug,
256
260
  };
257
261
  const plugin = channelLoader.getPlugin(cfgInst.type);
258
262
  if (!plugin)
@@ -814,12 +814,9 @@ export class CommandHandler {
814
814
  item.lastActive = s.updatedAt;
815
815
  return item;
816
816
  }
817
- /**
818
- * 返回结构化命令菜单(供 menu.query 使用)
819
- * owner 看到全部命令,admin 看到管理级命令(不含 owner-only),visitor/member 仅看到用户级命令
820
- */
821
- getMenuItems(role, chatType = 'private', scope = 'agent') {
822
- return menuGetMenuItems.call(this, role, chatType, scope);
817
+ /** 返回结构化命令菜单,已迁移的命令按当前授权主体过滤。 */
818
+ getMenuItems(role, chatType = 'private', scope = 'agent', authSubject) {
819
+ return menuGetMenuItems.call(this, role, chatType, scope, authSubject);
823
820
  }
824
821
  /** 动态子菜单:根据 cmd 路径返回选项列表(供 menu.query + cmd 使用) */
825
822
  async getSubMenuItems(cmd, channel, channelId, userId, args, overrideIdentity, explicitChatType, fromControlChannel = false, authSubject, source = 'menu') {
@@ -843,8 +840,8 @@ export class CommandHandler {
843
840
  return await menuExecMenuUpdate.call(this, cmd, value, channel, channelId, userId, overrideIdentity, fromControlChannel, args, authSubject, source);
844
841
  }
845
842
  /** menu.action — 触发动词。 */
846
- async execMenuAction(cmd, action, args, channel, channelId, userId, overrideIdentity, explicitChatType, requestId, fromControlChannel = false, authSubject, source = 'menu') {
847
- return await menuExecMenuAction.call(this, cmd, action, args, channel, channelId, userId, overrideIdentity, explicitChatType, requestId, fromControlChannel, authSubject, source);
843
+ async execMenuAction(cmd, action, args, channel, channelId, userId, overrideIdentity, explicitChatType, requestId, fromControlChannel = false, authSubject, source = 'menu', transportReplyContext, deferSideEffect) {
844
+ return await menuExecMenuAction.call(this, cmd, action, args, channel, channelId, userId, overrideIdentity, explicitChatType, requestId, fromControlChannel, authSubject, source, transportReplyContext, deferSideEffect);
848
845
  }
849
846
  /** ECWeb 专用入口:身份只取可信 IPC 信封。 */
850
847
  async execMenuForEcweb(payload, auth) {
@@ -1168,7 +1165,7 @@ export class CommandHandler {
1168
1165
  /trigger list [--all] — 查看所有触发器
1169
1166
  /trigger create <参数> — 创建触发器(set 为兼容别名)
1170
1167
  /trigger update <名称|ID> <参数> — 修改触发器
1171
- 常用参数:--delay/--at/--cron/--every、--prompt、--model、--effort、--permission(省略则继承;update 可用 inherit 清除覆盖)
1168
+ 常用参数:--exec script|trigger-session|target-session(create 必填)、--delay/--at/--cron/--every、--prompt、--model、--effort、--permission(省略则继承;update 可用 inherit 清除覆盖)
1172
1169
  /trigger enable <名称|ID> — 启用触发器
1173
1170
  /trigger disable <名称|ID> — 暂停触发器
1174
1171
  /trigger show <名称|ID> — 查看触发器详情
@@ -1451,11 +1448,11 @@ export class CommandHandler {
1451
1448
  * Agent managed CLI config entrypoint. Identity and relation are resolved
1452
1449
  * from the daemon-owned session rather than caller-provided flags.
1453
1450
  */
1454
- async handleConfigOperation(argv, sessionId, delegationToken) {
1451
+ async handleConfigOperation(argv, sessionId, delegationToken, delegationCommandHash) {
1455
1452
  if (!this.agentDelegationRegistry) {
1456
1453
  return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Task delegation is not configured' };
1457
1454
  }
1458
- const delegation = this.agentDelegationRegistry.validate(delegationToken, sessionId);
1455
+ const delegation = this.agentDelegationRegistry.validate(delegationToken, sessionId, delegationCommandHash);
1459
1456
  if (!delegation.ok)
1460
1457
  return { ok: false, code: delegation.code, error: delegation.reason };
1461
1458
  const session = await this.sessionManager.getSessionById(sessionId);
@@ -1513,11 +1510,11 @@ export class CommandHandler {
1513
1510
  : { ok: false, code: result.code, error: result.error, ...(result.data !== undefined ? { data: result.data } : {}) };
1514
1511
  }
1515
1512
  /** Agent-managed contact CLI entrypoint. The daemon owns actor resolution and authorization. */
1516
- async handleContactOperation(argv, sessionId, delegationToken) {
1513
+ async handleContactOperation(argv, sessionId, delegationToken, delegationCommandHash) {
1517
1514
  if (!this.agentDelegationRegistry) {
1518
1515
  return { ok: false, code: 'DELEGATION_REQUIRED', error: 'Task delegation is not configured' };
1519
1516
  }
1520
- const delegation = this.agentDelegationRegistry.validate(delegationToken, sessionId);
1517
+ const delegation = this.agentDelegationRegistry.validate(delegationToken, sessionId, delegationCommandHash);
1521
1518
  if (!delegation.ok)
1522
1519
  return { ok: false, code: delegation.code, error: delegation.reason };
1523
1520
  const session = await this.sessionManager.getSessionById(sessionId);