evolcore 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/bin/codex-managed-hook.mjs +80 -0
- package/bin/ec-safe-output.js +26 -7
- package/dist/agents/claude-runner.js +86 -7
- package/dist/agents/codex-app-server-client.js +174 -20
- package/dist/agents/codex-runner.js +375 -92
- package/dist/agents/ecagent-runner.js +39 -4
- package/dist/agents/gemini-runner.js +1 -0
- package/dist/aun/aid/client.js +11 -21
- package/dist/aun/aid/control-aid.js +36 -13
- package/dist/aun/aid/managed-operation.js +107 -0
- package/dist/aun/aid/store.js +13 -7
- package/dist/aun/group-fs-download.js +56 -0
- package/dist/aun/group-identity.js +1 -2
- package/dist/aun/msg/group.js +91 -44
- package/dist/aun/msg/index.js +1 -2
- package/dist/aun/msg/managed-operation.js +865 -0
- package/dist/aun/msg/mention-schema.js +20 -0
- package/dist/aun/msg/p2p.js +7 -0
- package/dist/aun/msg/upload.js +16 -1
- package/dist/aun/outbox.js +31 -2
- package/dist/aun/rpc/client.js +66 -0
- package/dist/aun/rpc/index.js +1 -2
- package/dist/aun/storage/{upload.js → client.js} +11 -2
- package/dist/aun/storage/index.js +1 -2
- package/dist/channels/aun.js +655 -240
- package/dist/channels/daemon.js +13 -0
- package/dist/cli/agent-command.js +56 -8
- package/dist/cli/agent.js +108 -31
- package/dist/cli/aun-commands.js +270 -69
- package/dist/cli/bench.js +12 -3
- package/dist/cli/cli-argv.js +10 -0
- package/dist/cli/config.js +9 -17
- package/dist/cli/ctl-command.js +1 -1
- package/dist/cli/daemon-commands.js +70 -55
- package/dist/cli/fs-command.js +79 -10
- package/dist/cli/handoff-command.js +3 -0
- package/dist/cli/index.js +30 -2
- package/dist/cli/init.js +77 -8
- package/dist/cli/managed-command-guard.js +41 -0
- package/dist/cli/model.js +11 -4
- package/dist/cli/queue-command.js +53 -1
- package/dist/cli/response.js +71 -0
- package/dist/cli/restart-monitor.js +7 -32
- package/dist/cli/trigger-command.js +11 -0
- package/dist/config/access-policy.js +1 -2
- package/dist/config/builtin-roles.js +9 -0
- package/dist/config/config-manager.js +21 -1
- package/dist/config/contact-book-store.js +11 -3
- package/dist/config/contact-request-service.js +161 -15
- package/dist/config/mention-mode.js +8 -24
- package/dist/config/peer-role-resolver.js +6 -2
- package/dist/config/role-migration-startup.js +53 -0
- package/dist/config/role-store.js +1 -1
- package/dist/core/auth/agent-delegation.js +1 -2
- package/dist/core/auth/auth-gateway.js +29 -1
- package/dist/core/auth/authorization-audit.js +15 -0
- package/dist/core/auth/operation-authorizer.js +31 -7
- package/dist/core/auth/operation-catalog.js +196 -25
- package/dist/core/bootstrap-messages.js +25 -0
- package/dist/core/bootstrap-service.js +64 -4
- package/dist/core/capability/providers/claude-capability-provider.js +9 -31
- package/dist/core/capability/providers/codex-capability-provider.js +4 -15
- package/dist/core/capability/skill-discovery.js +55 -0
- package/dist/core/channel-loader.js +1 -1
- package/dist/core/command/cli-intent-parser.js +9 -0
- package/dist/core/command/command-handler.js +650 -42
- package/dist/core/command/connect-menu.js +15 -0
- package/dist/core/command/group-menu.js +4 -4
- package/dist/core/command/menu-catalog.js +370 -0
- package/dist/core/command/menu-handler.js +230 -51
- package/dist/core/command/menu-protocol.js +94 -2
- package/dist/core/command/slash-gate.js +5 -2
- package/dist/core/command/slash-handler.js +99 -31
- package/dist/core/daemon-file-cache.js +2 -1
- package/dist/core/data-migration.js +9 -2
- package/dist/core/event-catalog.js +6 -0
- package/dist/core/evolagent.js +4 -2
- package/dist/core/handoff/dispatcher.js +5 -2
- package/dist/core/handoff/runtime.js +157 -22
- package/dist/core/handoff/store.js +29 -1
- package/dist/core/handoff/types.js +1 -0
- package/dist/core/interaction-router.js +10 -0
- package/dist/core/message/im-renderer.js +19 -0
- package/dist/core/message/logical-queue-bridge.js +1 -0
- package/dist/core/message/mention-schema.js +126 -0
- package/dist/core/message/message-bridge.js +298 -88
- package/dist/core/message/message-log.js +3 -0
- package/dist/core/message/message-queue.js +268 -39
- package/dist/core/message/message-utils.js +81 -4
- package/dist/core/message/response-engine.js +161 -77
- package/dist/core/message/stream-debouncer.js +10 -2
- package/dist/core/permission/approval-gateway.js +1 -0
- package/dist/core/permission/ec-command-parser.js +243 -18
- package/dist/core/permission/index.js +1 -1
- package/dist/core/permission/mode.js +15 -0
- package/dist/core/permission/readonly-shell-query.js +148 -8
- package/dist/core/permission/sandbox-runtime.js +43 -1
- package/dist/core/permission/tool-policy.js +322 -57
- package/dist/core/protected-paths.js +114 -4
- package/dist/core/session/session-manager.js +42 -4
- package/dist/core/session/session-mapper.js +20 -1
- package/dist/eck/detect.js +18 -1
- package/dist/eck/group-rules-sync.js +15 -44
- package/dist/eck/manifest-engine.js +39 -13
- package/dist/index.js +541 -180
- package/dist/ipc.js +232 -10
- package/dist/paths.js +3 -0
- package/dist/response-system/coordinator.js +6 -4
- package/dist/response-system/engines/v1/proactive-flow.js +26 -8
- package/dist/response-system/modes/single-session/index.js +14 -1
- package/dist/response-system/selector.js +6 -5
- package/dist/trigger/anomaly-store.js +4 -0
- package/dist/trigger/feedback.js +64 -11
- package/dist/trigger/manager.js +21 -1
- package/dist/trigger/parser.js +14 -2
- package/dist/trigger/scheduler.js +1 -0
- package/dist/trigger/script-executor.js +1 -0
- package/dist/trigger/validation.js +67 -6
- package/dist/utils/codex-app-server-registry.js +90 -0
- package/dist/utils/codex-cli.js +5 -1
- package/dist/utils/cross-platform.js +15 -0
- package/dist/utils/ecweb-supervisor.js +332 -0
- package/dist/utils/error-utils.js +10 -0
- package/dist/utils/npm-ops.js +5 -12
- package/dist/utils/tool-summary.js +11 -0
- package/kits/docs/channels/aun.md +1 -1
- package/kits/docs/context-assembly.md +2 -2
- package/kits/docs/evolcore/agent.md +11 -6
- package/kits/docs/evolcore/aid.md +14 -0
- package/kits/docs/evolcore/trigger.md +17 -1
- package/kits/docs/prompt-loading-architecture.md +1 -2
- package/kits/docs/venues/group.md +1 -1
- package/kits/eck_manifest.json +0 -12
- package/kits/migrations/migrate-contact-book-v2.mjs +1 -2
- package/kits/rules/04-relation.md +1 -1
- package/kits/rules/05-venue.md +2 -2
- package/kits/schemas/role-config.schema.1.json +1 -0
- package/kits/schemas/single-session.schema.1.json +3 -3
- package/kits/schemas/single-session.schema.2.json +3 -3
- package/kits/templates/roles/admin.json +27 -0
- package/kits/templates/roles/member.json +34 -1
- package/kits/templates/roles/visitor.json +35 -3
- package/kits/templates/system-fragments/bootstrap.md +1 -1
- package/kits/templates/system-fragments/channel.md +1 -1
- package/kits/templates/system-fragments/session.md +1 -1
- package/package.json +2 -2
- package/dist/aun/msg/payload-type.js +0 -27
- package/dist/aun/rpc/caller.js +0 -42
- package/dist/aun/rpc/connection.js +0 -25
- package/dist/aun/storage/manage.js +0 -10
- package/dist/config/access-policy-domain.js +0 -18
- package/dist/config/config-batch-get.js +0 -11
- package/dist/config/owner-policy.js +0 -4
- package/dist/config/role-config-v4-startup.js +0 -32
- package/dist/config/role-config-v5-startup.js +0 -27
- package/dist/core/auth/trigger-authorization.js +0 -15
- package/dist/core/command/evol-menu-version-gate.js +0 -39
- package/dist/core/interaction-registration.js +0 -10
- package/dist/core/permission/execution-sandbox.js +0 -16
- package/dist/core/relation/peer-key.js +0 -1
- package/dist/core/session/session-key.js +0 -24
- package/dist/eck/baseagent-caps.js +0 -18
- package/dist/eck/rules-loader.js +0 -28
|
@@ -21,6 +21,90 @@ const CONFIG_MANAGEMENT_OPERATIONS = [
|
|
|
21
21
|
description,
|
|
22
22
|
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
23
23
|
}));
|
|
24
|
+
const GROUP_MANAGEMENT_OPERATIONS = [
|
|
25
|
+
['ec.group.list', 'read', ['agent'], 'List groups joined by the current Agent'],
|
|
26
|
+
['ec.group.info', 'read', ['relation', 'agent'], 'Read group information'],
|
|
27
|
+
['ec.group.pull', 'read', ['relation', 'agent'], 'Pull group messages'],
|
|
28
|
+
['ec.group.members', 'read', ['relation', 'agent'], 'List group members'],
|
|
29
|
+
['ec.group.online', 'read', ['relation', 'agent'], 'List online group members'],
|
|
30
|
+
['ec.group.rules.get', 'read', ['relation', 'agent'], 'Read the published group rules file'],
|
|
31
|
+
['ec.group.rules.read', 'read', ['relation', 'agent'], 'Read legacy group join rules'],
|
|
32
|
+
['ec.group.create', 'write-agent', ['agent'], 'Create a group as the current Agent'],
|
|
33
|
+
['ec.group.ack', 'write-agent', ['agent'], 'Advance the current Agent group cursor'],
|
|
34
|
+
['ec.group.update', 'write-agent', ['agent'], 'Update group metadata'],
|
|
35
|
+
['ec.group.dissolve', 'write-agent', ['agent'], 'Dissolve a group'],
|
|
36
|
+
['ec.group.suspend', 'write-agent', ['agent'], 'Suspend a group'],
|
|
37
|
+
['ec.group.resume', 'write-agent', ['agent'], 'Resume a group'],
|
|
38
|
+
['ec.group.join', 'write-agent', ['agent'], 'Request to join a group'],
|
|
39
|
+
['ec.group.leave', 'write-agent', ['agent'], 'Leave a group'],
|
|
40
|
+
['ec.group.invite', 'write-agent', ['agent'], 'Invite group members'],
|
|
41
|
+
['ec.group.kick', 'write-agent', ['agent'], 'Remove a group member'],
|
|
42
|
+
['ec.group.role', 'write-agent', ['agent'], 'Change a group member role'],
|
|
43
|
+
['ec.group.owner', 'write-agent', ['agent'], 'Transfer group ownership'],
|
|
44
|
+
['ec.group.ban', 'write-agent', ['agent'], 'Read or update the group ban list'],
|
|
45
|
+
['ec.group.unban', 'write-agent', ['agent'], 'Remove a group ban'],
|
|
46
|
+
['ec.group.rules.set', 'write-agent', ['agent'], 'Upload and publish group rules content'],
|
|
47
|
+
['ec.group.rules.publish', 'write-agent', ['agent'], 'Publish the current group rules file'],
|
|
48
|
+
['ec.group.rules.update', 'write-agent', ['agent'], 'Update group join rules'],
|
|
49
|
+
].map(([id, category, defaultScopes, description]) => ({
|
|
50
|
+
id,
|
|
51
|
+
category,
|
|
52
|
+
dangerous: false,
|
|
53
|
+
defaultScopes,
|
|
54
|
+
description,
|
|
55
|
+
sources: ['agent-tool'],
|
|
56
|
+
}));
|
|
57
|
+
const MSG_READ_OPERATIONS = [
|
|
58
|
+
['ec.msg.history', 'Read message history for an AUN private relation'],
|
|
59
|
+
['ec.msg.online', 'Read online status for an AUN private relation'],
|
|
60
|
+
].map(([id, description]) => ({
|
|
61
|
+
id,
|
|
62
|
+
category: 'read',
|
|
63
|
+
dangerous: false,
|
|
64
|
+
defaultScopes: ['relation', 'agent'],
|
|
65
|
+
description,
|
|
66
|
+
sources: ['agent-tool'],
|
|
67
|
+
}));
|
|
68
|
+
const GROUP_FS_READ_OPERATIONS = ['ls', 'stat', 'lstat', 'cat', 'find', 'df'].map(kind => ({
|
|
69
|
+
id: `ec.fs.${kind}`,
|
|
70
|
+
category: 'read',
|
|
71
|
+
dangerous: false,
|
|
72
|
+
defaultScopes: ['relation', 'agent'],
|
|
73
|
+
description: `Read current group filesystem (${kind})`,
|
|
74
|
+
sources: ['agent-tool'],
|
|
75
|
+
}));
|
|
76
|
+
const GROUP_FS_WRITE_OPERATIONS = ['mkdir', 'upload', 'copy', 'move', 'remove'].map(kind => ({
|
|
77
|
+
id: `ec.fs.${kind}`,
|
|
78
|
+
category: 'write-own',
|
|
79
|
+
dangerous: false,
|
|
80
|
+
defaultScopes: ['relation'],
|
|
81
|
+
description: `Write current group filesystem (${kind})`,
|
|
82
|
+
sources: ['agent-tool'],
|
|
83
|
+
}));
|
|
84
|
+
const HANDOFF_READ_OPERATIONS = ['status', 'list', 'trace'].map(kind => ({
|
|
85
|
+
id: `ec.handoff.${kind}`,
|
|
86
|
+
category: 'read',
|
|
87
|
+
dangerous: false,
|
|
88
|
+
defaultScopes: ['relation', 'agent'],
|
|
89
|
+
description: `Read handoff ${kind}`,
|
|
90
|
+
sources: ['agent-tool'],
|
|
91
|
+
}));
|
|
92
|
+
const HANDOFF_WRITE_OPERATIONS = [{
|
|
93
|
+
id: 'ec.handoff.return',
|
|
94
|
+
category: 'write-own',
|
|
95
|
+
dangerous: false,
|
|
96
|
+
defaultScopes: ['relation', 'agent'],
|
|
97
|
+
description: 'Return the current handoff result',
|
|
98
|
+
sources: ['agent-tool'],
|
|
99
|
+
}];
|
|
100
|
+
const QUEUE_OPERATIONS = [['read', 'Read the current Agent message queue'], ['clear', 'Clear the current Agent message queue'], ['cancel', 'Cancel a current Agent queued message'], ['interrupt', 'Interrupt a current Agent session']].map(([kind, description]) => ({
|
|
101
|
+
id: `ec.queue.${kind}`,
|
|
102
|
+
category: kind === 'read' ? 'read' : 'write-agent',
|
|
103
|
+
dangerous: false,
|
|
104
|
+
defaultScopes: ['agent'],
|
|
105
|
+
description,
|
|
106
|
+
sources: ['agent-tool'],
|
|
107
|
+
}));
|
|
24
108
|
/**
|
|
25
109
|
* Operation Catalog - 所有命令操作的元数据定义
|
|
26
110
|
*
|
|
@@ -34,7 +118,7 @@ const OPERATIONS = [
|
|
|
34
118
|
dangerous: false,
|
|
35
119
|
defaultScopes: ['relation', 'role', 'agent'],
|
|
36
120
|
description: '列出可用模型',
|
|
37
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
121
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
38
122
|
},
|
|
39
123
|
{
|
|
40
124
|
id: 'model.current',
|
|
@@ -42,7 +126,7 @@ const OPERATIONS = [
|
|
|
42
126
|
dangerous: false,
|
|
43
127
|
defaultScopes: ['relation', 'role', 'agent'],
|
|
44
128
|
description: '查询当前使用的模型',
|
|
45
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
129
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
46
130
|
},
|
|
47
131
|
{
|
|
48
132
|
id: 'model.effort.current',
|
|
@@ -50,7 +134,7 @@ const OPERATIONS = [
|
|
|
50
134
|
dangerous: false,
|
|
51
135
|
defaultScopes: ['relation', 'role', 'agent'],
|
|
52
136
|
description: '查询当前推理努力度',
|
|
53
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
137
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
54
138
|
},
|
|
55
139
|
{
|
|
56
140
|
id: 'model.info',
|
|
@@ -74,7 +158,7 @@ const OPERATIONS = [
|
|
|
74
158
|
dangerous: false,
|
|
75
159
|
defaultScopes: ['relation', 'role', 'agent'],
|
|
76
160
|
description: '切换使用的模型',
|
|
77
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
161
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
78
162
|
},
|
|
79
163
|
{
|
|
80
164
|
id: 'model.effort',
|
|
@@ -82,7 +166,7 @@ const OPERATIONS = [
|
|
|
82
166
|
dangerous: false,
|
|
83
167
|
defaultScopes: ['relation', 'role', 'agent'],
|
|
84
168
|
description: '设置推理努力度',
|
|
85
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
169
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
86
170
|
},
|
|
87
171
|
{
|
|
88
172
|
id: 'model.reset',
|
|
@@ -195,7 +279,7 @@ const OPERATIONS = [
|
|
|
195
279
|
dangerous: false,
|
|
196
280
|
defaultScopes: ['relation'],
|
|
197
281
|
description: '查看当前会话状态',
|
|
198
|
-
sources: ['slash', 'menu'],
|
|
282
|
+
sources: ['slash', 'menu', 'agent-tool'],
|
|
199
283
|
},
|
|
200
284
|
{
|
|
201
285
|
id: 'session.topic.current',
|
|
@@ -227,7 +311,7 @@ const OPERATIONS = [
|
|
|
227
311
|
dangerous: false,
|
|
228
312
|
defaultScopes: ['relation'],
|
|
229
313
|
description: '重命名会话',
|
|
230
|
-
sources: ['slash', 'menu'],
|
|
314
|
+
sources: ['slash', 'menu', 'agent-tool'],
|
|
231
315
|
},
|
|
232
316
|
{
|
|
233
317
|
id: 'session.delete',
|
|
@@ -244,7 +328,7 @@ const OPERATIONS = [
|
|
|
244
328
|
dangerous: false,
|
|
245
329
|
defaultScopes: ['relation', 'agent'],
|
|
246
330
|
description: '查看当前项目摘要',
|
|
247
|
-
sources: ['menu'],
|
|
331
|
+
sources: ['menu', 'agent-tool'],
|
|
248
332
|
},
|
|
249
333
|
{
|
|
250
334
|
id: 'file.list',
|
|
@@ -481,6 +565,14 @@ const OPERATIONS = [
|
|
|
481
565
|
description: '列出当前 Agent 可用的 BaseAgent',
|
|
482
566
|
sources: ['menu', 'control'],
|
|
483
567
|
},
|
|
568
|
+
{
|
|
569
|
+
id: 'agent.baseagent.update',
|
|
570
|
+
category: 'write-agent',
|
|
571
|
+
dangerous: false,
|
|
572
|
+
defaultScopes: ['agent'],
|
|
573
|
+
description: '切换当前 Agent 使用的 BaseAgent',
|
|
574
|
+
sources: ['menu'],
|
|
575
|
+
},
|
|
484
576
|
{
|
|
485
577
|
id: 'agent.getConfig',
|
|
486
578
|
category: 'read',
|
|
@@ -505,6 +597,14 @@ const OPERATIONS = [
|
|
|
505
597
|
description: '重载 agent 配置',
|
|
506
598
|
sources: ['slash', 'menu', 'control'],
|
|
507
599
|
},
|
|
600
|
+
{
|
|
601
|
+
id: 'agent.bootstrapComplete',
|
|
602
|
+
category: 'write-agent',
|
|
603
|
+
dangerous: false,
|
|
604
|
+
defaultScopes: ['agent'],
|
|
605
|
+
description: 'Complete bootstrap for the current Agent',
|
|
606
|
+
sources: ['agent-tool'],
|
|
607
|
+
},
|
|
508
608
|
{
|
|
509
609
|
id: 'agent.delete',
|
|
510
610
|
category: 'dangerous',
|
|
@@ -520,7 +620,7 @@ const OPERATIONS = [
|
|
|
520
620
|
dangerous: false,
|
|
521
621
|
defaultScopes: ['process'],
|
|
522
622
|
description: '查看系统状态(敏感信息)',
|
|
523
|
-
sources: ['slash', 'menu', 'menu.cli'],
|
|
623
|
+
sources: ['slash', 'menu', 'menu.cli', 'agent-tool'],
|
|
524
624
|
},
|
|
525
625
|
{
|
|
526
626
|
id: 'activity.current',
|
|
@@ -530,6 +630,14 @@ const OPERATIONS = [
|
|
|
530
630
|
description: '查看当前中间活动显示策略',
|
|
531
631
|
sources: ['menu'],
|
|
532
632
|
},
|
|
633
|
+
{
|
|
634
|
+
id: 'activity.update',
|
|
635
|
+
category: 'write-agent',
|
|
636
|
+
dangerous: false,
|
|
637
|
+
defaultScopes: ['relation', 'agent'],
|
|
638
|
+
description: '更新中间活动显示策略',
|
|
639
|
+
sources: ['menu'],
|
|
640
|
+
},
|
|
533
641
|
{
|
|
534
642
|
id: 'observable.current',
|
|
535
643
|
category: 'read',
|
|
@@ -538,6 +646,14 @@ const OPERATIONS = [
|
|
|
538
646
|
description: '查看当前 Agent 观察者模式',
|
|
539
647
|
sources: ['menu', 'control'],
|
|
540
648
|
},
|
|
649
|
+
{
|
|
650
|
+
id: 'observable.update',
|
|
651
|
+
category: 'write-agent',
|
|
652
|
+
dangerous: false,
|
|
653
|
+
defaultScopes: ['agent'],
|
|
654
|
+
description: '更新当前 Agent 观察者模式',
|
|
655
|
+
sources: ['menu'],
|
|
656
|
+
},
|
|
541
657
|
{
|
|
542
658
|
id: 'capability.read',
|
|
543
659
|
category: 'read',
|
|
@@ -649,41 +765,41 @@ const OPERATIONS = [
|
|
|
649
765
|
id: 'storage.list',
|
|
650
766
|
category: 'read',
|
|
651
767
|
dangerous: false,
|
|
652
|
-
defaultScopes: ['control'],
|
|
768
|
+
defaultScopes: ['agent', 'control'],
|
|
653
769
|
description: '列出存储对象(敏感信息)',
|
|
654
|
-
sources: ['menu.cli', 'control'],
|
|
770
|
+
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
655
771
|
},
|
|
656
772
|
{
|
|
657
773
|
id: 'storage.quota',
|
|
658
774
|
category: 'read',
|
|
659
775
|
dangerous: false,
|
|
660
|
-
defaultScopes: ['control'],
|
|
776
|
+
defaultScopes: ['agent', 'control'],
|
|
661
777
|
description: '查看存储配额(敏感信息)',
|
|
662
|
-
sources: ['menu.cli', 'control'],
|
|
778
|
+
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
663
779
|
},
|
|
664
780
|
{
|
|
665
781
|
id: 'storage.upload',
|
|
666
782
|
category: 'write-agent',
|
|
667
783
|
dangerous: true,
|
|
668
|
-
defaultScopes: ['control'],
|
|
784
|
+
defaultScopes: ['agent', 'control'],
|
|
669
785
|
description: '上传文件到云存储',
|
|
670
|
-
sources: ['menu.cli', 'control'],
|
|
786
|
+
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
671
787
|
},
|
|
672
788
|
{
|
|
673
789
|
id: 'storage.download',
|
|
674
790
|
category: 'write-agent',
|
|
675
791
|
dangerous: true,
|
|
676
|
-
defaultScopes: ['control'],
|
|
792
|
+
defaultScopes: ['agent', 'control'],
|
|
677
793
|
description: '从云存储下载文件',
|
|
678
|
-
sources: ['menu.cli', 'control'],
|
|
794
|
+
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
679
795
|
},
|
|
680
796
|
{
|
|
681
797
|
id: 'storage.delete',
|
|
682
798
|
category: 'dangerous',
|
|
683
799
|
dangerous: true,
|
|
684
|
-
defaultScopes: ['control'],
|
|
800
|
+
defaultScopes: ['agent', 'control'],
|
|
685
801
|
description: '删除云存储对象',
|
|
686
|
-
sources: ['menu.cli', 'control'],
|
|
802
|
+
sources: ['menu.cli', 'agent-tool', 'control'],
|
|
687
803
|
},
|
|
688
804
|
// ── Gateway & Config Operations ──
|
|
689
805
|
{
|
|
@@ -745,6 +861,53 @@ const OPERATIONS = [
|
|
|
745
861
|
// ── EC Command Operations ──
|
|
746
862
|
// EC daemon 入口根据结构化 IPC 请求构造 operation;Runner 不解析 EC 子命令。
|
|
747
863
|
...CONFIG_MANAGEMENT_OPERATIONS,
|
|
864
|
+
...GROUP_MANAGEMENT_OPERATIONS,
|
|
865
|
+
...MSG_READ_OPERATIONS,
|
|
866
|
+
...GROUP_FS_READ_OPERATIONS,
|
|
867
|
+
...GROUP_FS_WRITE_OPERATIONS,
|
|
868
|
+
...HANDOFF_READ_OPERATIONS,
|
|
869
|
+
...HANDOFF_WRITE_OPERATIONS,
|
|
870
|
+
...QUEUE_OPERATIONS,
|
|
871
|
+
{
|
|
872
|
+
id: 'ec.version',
|
|
873
|
+
category: 'read',
|
|
874
|
+
dangerous: false,
|
|
875
|
+
defaultScopes: ['relation', 'agent', 'process'],
|
|
876
|
+
description: 'Read local EvolCore component versions',
|
|
877
|
+
sources: ['menu.cli', 'agent-tool'],
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
id: 'ec.aid.show',
|
|
881
|
+
category: 'read',
|
|
882
|
+
dangerous: true,
|
|
883
|
+
defaultScopes: ['relation', 'agent'],
|
|
884
|
+
description: 'Inspect the current Agent local AID identity and signing state',
|
|
885
|
+
sources: ['agent-tool'],
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
id: 'ec.aid.lookup',
|
|
889
|
+
category: 'read',
|
|
890
|
+
dangerous: false,
|
|
891
|
+
defaultScopes: ['relation', 'agent'],
|
|
892
|
+
description: 'Look up the current Agent public AID record',
|
|
893
|
+
sources: ['agent-tool'],
|
|
894
|
+
},
|
|
895
|
+
{
|
|
896
|
+
id: 'ec.aid.agentmd.get',
|
|
897
|
+
category: 'read',
|
|
898
|
+
dangerous: false,
|
|
899
|
+
defaultScopes: ['relation', 'agent'],
|
|
900
|
+
description: 'Read and verify the current Agent public agent.md',
|
|
901
|
+
sources: ['agent-tool'],
|
|
902
|
+
},
|
|
903
|
+
{
|
|
904
|
+
id: 'ec.aid.agentmd.put',
|
|
905
|
+
category: 'write-agent',
|
|
906
|
+
dangerous: true,
|
|
907
|
+
defaultScopes: ['agent'],
|
|
908
|
+
description: 'Sign and publish the current Agent local agent.md',
|
|
909
|
+
sources: ['agent-tool'],
|
|
910
|
+
},
|
|
748
911
|
{
|
|
749
912
|
id: 'ec.msg.send',
|
|
750
913
|
category: 'write-own',
|
|
@@ -779,20 +942,28 @@ const OPERATIONS = [
|
|
|
779
942
|
},
|
|
780
943
|
{
|
|
781
944
|
id: 'ec.ctl.send',
|
|
782
|
-
category: 'write-
|
|
945
|
+
category: 'write-own',
|
|
783
946
|
dangerous: false,
|
|
784
|
-
defaultScopes: ['
|
|
785
|
-
description: '通过 ec ctl send
|
|
947
|
+
defaultScopes: ['relation'],
|
|
948
|
+
description: '通过 ec ctl send 向当前会话发送消息',
|
|
786
949
|
sources: ['agent-tool'],
|
|
787
950
|
},
|
|
788
951
|
{
|
|
789
952
|
id: 'ec.ctl.file',
|
|
790
|
-
category: 'write-
|
|
953
|
+
category: 'write-own',
|
|
791
954
|
dangerous: false,
|
|
792
|
-
defaultScopes: ['
|
|
793
|
-
description: '通过 ec ctl file
|
|
955
|
+
defaultScopes: ['relation'],
|
|
956
|
+
description: '通过 ec ctl file 向当前会话发送项目文件',
|
|
794
957
|
sources: ['agent-tool'],
|
|
795
958
|
},
|
|
959
|
+
...['read', 'clear', 'cancel', 'interrupt'].map(action => ({
|
|
960
|
+
id: `ec.ctl.queue.${action}`,
|
|
961
|
+
category: action === 'read' ? 'read' : 'write-own',
|
|
962
|
+
dangerous: false,
|
|
963
|
+
defaultScopes: ['relation'],
|
|
964
|
+
description: `${action} the current managed session queue`,
|
|
965
|
+
sources: ['agent-tool'],
|
|
966
|
+
})),
|
|
796
967
|
// ── Raw CLI & Shell Execution ──
|
|
797
968
|
{
|
|
798
969
|
id: 'cli.exec.raw',
|
|
@@ -31,14 +31,21 @@ export function preparePostBootstrapWelcomeOutbox(aid, owner, ownerName) {
|
|
|
31
31
|
const chatDir = chatDirPath(resolvePaths().sessionsDir, 'aun', owner, aid);
|
|
32
32
|
if (hasMessageLogOperation(chatDir, operationId))
|
|
33
33
|
return;
|
|
34
|
+
const existing = outbox.findByDedupeKey(aid, operationId);
|
|
35
|
+
if (existing?.delivery?.chatType === 'private' && existing.channelId === owner)
|
|
36
|
+
return;
|
|
37
|
+
if (existing)
|
|
38
|
+
outbox.remove(aid, existing.id);
|
|
34
39
|
outbox.enqueue(aid, {
|
|
35
40
|
channelId: owner,
|
|
41
|
+
delivery: { chatType: 'private' },
|
|
36
42
|
dedupeKey: operationId,
|
|
37
43
|
critical: true,
|
|
38
44
|
type: 'text',
|
|
39
45
|
text: renderPostBootstrapWelcome(aid, owner, ownerName),
|
|
40
46
|
ttl: BOOTSTRAP_MESSAGE_TTL_MS,
|
|
41
47
|
context: {
|
|
48
|
+
delivery: { chatType: 'private' },
|
|
42
49
|
metadata: {
|
|
43
50
|
source: 'daemon',
|
|
44
51
|
chatmode: 'interactive',
|
|
@@ -48,3 +55,21 @@ export function preparePostBootstrapWelcomeOutbox(aid, owner, ownerName) {
|
|
|
48
55
|
},
|
|
49
56
|
});
|
|
50
57
|
}
|
|
58
|
+
export function hasPendingPostBootstrapWelcomeOutbox(aid) {
|
|
59
|
+
return outbox.findByDedupeKey(aid, postBootstrapWelcomeOperationId(aid))?.delivery?.chatType === 'private';
|
|
60
|
+
}
|
|
61
|
+
/** Bind the durable completion welcome to the fresh post-bootstrap session. */
|
|
62
|
+
export function bindPostBootstrapWelcomeOutboxSession(aid, sessionId) {
|
|
63
|
+
const entry = outbox.findByDedupeKey(aid, postBootstrapWelcomeOperationId(aid));
|
|
64
|
+
if (!entry || entry.delivery?.chatType !== 'private')
|
|
65
|
+
return false;
|
|
66
|
+
if (entry.context?.sessionId === sessionId)
|
|
67
|
+
return true;
|
|
68
|
+
return outbox.replace(aid, {
|
|
69
|
+
...entry,
|
|
70
|
+
context: {
|
|
71
|
+
...(entry.context ?? {}),
|
|
72
|
+
sessionId,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -11,8 +11,12 @@ import { activeBaseagent } from './model/config-scope.js';
|
|
|
11
11
|
import { buildEnvelope } from './message/message-utils.js';
|
|
12
12
|
import { BOOTSTRAP_MESSAGE_TTL_MS, bootstrapInitialMessageOperationId } from './bootstrap-messages.js';
|
|
13
13
|
/** Coordinate the write-ahead completion welcome with the lifecycle commit. */
|
|
14
|
-
export async function completeBootstrapWithWelcome(service, aid, welcome) {
|
|
14
|
+
export async function completeBootstrapWithWelcome(service, aid, welcome, sessions) {
|
|
15
15
|
const lifecycle = service.lifecycleOf(aid);
|
|
16
|
+
if (lifecycle !== 'bootstrapping' && lifecycle !== 'active') {
|
|
17
|
+
const result = service.completeBootstrap(aid);
|
|
18
|
+
return { ...result, reloaded: false };
|
|
19
|
+
}
|
|
16
20
|
if (lifecycle === 'bootstrapping') {
|
|
17
21
|
if (!welcome) {
|
|
18
22
|
return {
|
|
@@ -31,13 +35,68 @@ export async function completeBootstrapWithWelcome(service, aid, welcome) {
|
|
|
31
35
|
};
|
|
32
36
|
}
|
|
33
37
|
}
|
|
38
|
+
const welcomePending = welcome
|
|
39
|
+
? await welcome.hasPendingPostBootstrapWelcome()
|
|
40
|
+
: false;
|
|
41
|
+
const needsMainSessionBoundary = lifecycle === 'bootstrapping' || welcomePending;
|
|
42
|
+
let mainSession;
|
|
43
|
+
if (needsMainSessionBoundary) {
|
|
44
|
+
if (!sessions) {
|
|
45
|
+
return {
|
|
46
|
+
ok: false,
|
|
47
|
+
code: 'MAIN_SESSION_UNAVAILABLE',
|
|
48
|
+
error: `No session coordinator available to create the post-bootstrap main session for ${aid}`,
|
|
49
|
+
reloaded: false,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
mainSession = await sessions.ensurePostBootstrapMainSession();
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
code: 'MAIN_SESSION_CREATE_FAILED',
|
|
59
|
+
error: e instanceof Error ? e.message : `Failed to create the post-bootstrap main session for ${aid}`,
|
|
60
|
+
reloaded: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (!mainSession.sessionId) {
|
|
64
|
+
return {
|
|
65
|
+
ok: false,
|
|
66
|
+
code: 'MAIN_SESSION_CREATE_FAILED',
|
|
67
|
+
error: `Failed to create the post-bootstrap main session for ${aid}`,
|
|
68
|
+
reloaded: false,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (welcomePending && welcome && !await welcome.bindPostBootstrapWelcomeToSession(mainSession.sessionId)) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
code: 'WELCOME_SESSION_BIND_FAILED',
|
|
75
|
+
error: `Failed to bind the post-bootstrap welcome to session ${mainSession.sessionId}`,
|
|
76
|
+
reloaded: false,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
34
80
|
const result = service.completeBootstrap(aid);
|
|
35
81
|
if (!result.ok)
|
|
36
82
|
return { ...result, reloaded: false };
|
|
37
|
-
if (!welcome)
|
|
38
|
-
return {
|
|
83
|
+
if (!welcome) {
|
|
84
|
+
return {
|
|
85
|
+
...result,
|
|
86
|
+
reloaded: true,
|
|
87
|
+
welcomeQueued: false,
|
|
88
|
+
mainSessionId: mainSession?.sessionId,
|
|
89
|
+
mainSessionCreated: mainSession?.created,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
39
92
|
const welcomeQueued = await welcome.reconcilePostBootstrapWelcome();
|
|
40
|
-
return {
|
|
93
|
+
return {
|
|
94
|
+
...result,
|
|
95
|
+
reloaded: true,
|
|
96
|
+
welcomeQueued,
|
|
97
|
+
mainSessionId: mainSession?.sessionId,
|
|
98
|
+
mainSessionCreated: mainSession?.created,
|
|
99
|
+
};
|
|
41
100
|
}
|
|
42
101
|
export class BootstrapService {
|
|
43
102
|
agentRegistry;
|
|
@@ -107,6 +166,7 @@ export class BootstrapService {
|
|
|
107
166
|
channelId,
|
|
108
167
|
agentName: aid,
|
|
109
168
|
replyContext: {
|
|
169
|
+
delivery: { chatType: 'private' },
|
|
110
170
|
metadata: {
|
|
111
171
|
source: 'daemon',
|
|
112
172
|
persistRequired: true,
|
|
@@ -2,6 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { execFileSync } from 'child_process';
|
|
5
|
+
import { discoverSkillDirectories } from '../skill-discovery.js';
|
|
5
6
|
function readJson(file) {
|
|
6
7
|
try {
|
|
7
8
|
if (!fs.existsSync(file))
|
|
@@ -12,31 +13,6 @@ function readJson(file) {
|
|
|
12
13
|
return null;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
function listDirectories(dir) {
|
|
16
|
-
try {
|
|
17
|
-
if (!fs.existsSync(dir))
|
|
18
|
-
return [];
|
|
19
|
-
return fs.readdirSync(dir, { withFileTypes: true })
|
|
20
|
-
.filter(entry => entry.isDirectory())
|
|
21
|
-
.map(entry => entry.name);
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return [];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function readSkillDescription(skillDir) {
|
|
28
|
-
const file = path.join(skillDir, 'SKILL.md');
|
|
29
|
-
try {
|
|
30
|
-
const text = fs.readFileSync(file, 'utf-8');
|
|
31
|
-
const firstBodyLine = text.split(/\r?\n/)
|
|
32
|
-
.map(line => line.trim())
|
|
33
|
-
.find(line => line && !line.startsWith('#') && !line.startsWith('---') && !line.includes(':'));
|
|
34
|
-
return firstBodyLine ? firstBodyLine.slice(0, 180) : undefined;
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
16
|
function describeMcpSpec(spec) {
|
|
41
17
|
const command = typeof spec?.command === 'string' ? spec.command : undefined;
|
|
42
18
|
if (command)
|
|
@@ -60,14 +36,15 @@ function discoverSkills(projectPath) {
|
|
|
60
36
|
const seen = new Set();
|
|
61
37
|
const items = [];
|
|
62
38
|
for (const root of roots) {
|
|
63
|
-
for (const
|
|
64
|
-
|
|
39
|
+
for (const skill of discoverSkillDirectories(root.dir)) {
|
|
40
|
+
const { id } = skill;
|
|
41
|
+
if (seen.has(id))
|
|
65
42
|
continue;
|
|
66
|
-
seen.add(
|
|
43
|
+
seen.add(id);
|
|
67
44
|
items.push({
|
|
68
|
-
id
|
|
69
|
-
label:
|
|
70
|
-
desc:
|
|
45
|
+
id,
|
|
46
|
+
label: id,
|
|
47
|
+
desc: skill.description,
|
|
71
48
|
source: root.source,
|
|
72
49
|
});
|
|
73
50
|
}
|
|
@@ -138,6 +115,7 @@ async function discoverPluginsFromCli() {
|
|
|
138
115
|
encoding: 'utf-8',
|
|
139
116
|
timeout: 3000,
|
|
140
117
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
118
|
+
windowsHide: process.platform === 'win32',
|
|
141
119
|
});
|
|
142
120
|
const parsed = JSON.parse(output);
|
|
143
121
|
const list = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.installed) ? parsed.installed : [];
|
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
1
|
import os from 'os';
|
|
3
2
|
import path from 'path';
|
|
4
3
|
import { execCodexCliSync } from '../../../utils/codex-cli.js';
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
if (!fs.existsSync(dir))
|
|
8
|
-
return [];
|
|
9
|
-
return fs.readdirSync(dir, { withFileTypes: true })
|
|
10
|
-
.filter(entry => entry.isDirectory())
|
|
11
|
-
.map(entry => entry.name);
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
}
|
|
4
|
+
import { discoverSkillDirectories } from '../skill-discovery.js';
|
|
17
5
|
function discoverSkills(ctx) {
|
|
18
6
|
const roots = [
|
|
19
7
|
{ dir: path.join(ctx.projectPath, '.codex', 'skills'), source: 'project' },
|
|
@@ -23,11 +11,12 @@ function discoverSkills(ctx) {
|
|
|
23
11
|
const seen = new Set();
|
|
24
12
|
const out = [];
|
|
25
13
|
for (const root of roots) {
|
|
26
|
-
for (const
|
|
14
|
+
for (const skill of discoverSkillDirectories(root.dir)) {
|
|
15
|
+
const { id } = skill;
|
|
27
16
|
if (seen.has(id))
|
|
28
17
|
continue;
|
|
29
18
|
seen.add(id);
|
|
30
|
-
out.push({ id, label: id, source: root.source });
|
|
19
|
+
out.push({ id, label: id, desc: skill.description, source: root.source });
|
|
31
20
|
}
|
|
32
21
|
}
|
|
33
22
|
return out;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { parseDocument } from 'yaml';
|
|
4
|
+
function readSkillMetadata(skillDir) {
|
|
5
|
+
const skillFile = path.join(skillDir, 'SKILL.md');
|
|
6
|
+
try {
|
|
7
|
+
if (!fs.statSync(skillFile).isFile())
|
|
8
|
+
return undefined;
|
|
9
|
+
const text = fs.readFileSync(skillFile, 'utf-8');
|
|
10
|
+
const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
11
|
+
if (!match)
|
|
12
|
+
return undefined;
|
|
13
|
+
const document = parseDocument(match[1]);
|
|
14
|
+
if (document.errors.length > 0)
|
|
15
|
+
return undefined;
|
|
16
|
+
const metadata = document.toJS();
|
|
17
|
+
if (typeof metadata?.name !== 'string' || !metadata.name.trim())
|
|
18
|
+
return undefined;
|
|
19
|
+
if (typeof metadata.description !== 'string' || !metadata.description.trim())
|
|
20
|
+
return undefined;
|
|
21
|
+
return {
|
|
22
|
+
id: metadata.name.trim(),
|
|
23
|
+
description: metadata.description.trim(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Return only directories that satisfy the Codex/Claude skill file contract. */
|
|
31
|
+
export function discoverSkillDirectories(root) {
|
|
32
|
+
try {
|
|
33
|
+
if (!fs.existsSync(root))
|
|
34
|
+
return [];
|
|
35
|
+
return fs.readdirSync(root, { withFileTypes: true })
|
|
36
|
+
.filter(entry => !entry.name.startsWith('.'))
|
|
37
|
+
.filter(entry => entry.isDirectory() || entry.isSymbolicLink())
|
|
38
|
+
.map(entry => {
|
|
39
|
+
const dir = path.join(root, entry.name);
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.statSync(dir).isDirectory())
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const metadata = readSkillMetadata(dir);
|
|
48
|
+
return metadata;
|
|
49
|
+
})
|
|
50
|
+
.filter((entry) => Boolean(entry));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -196,7 +196,7 @@ export function buildReloadHooks(deps) {
|
|
|
196
196
|
if (!handoffRuntime)
|
|
197
197
|
return;
|
|
198
198
|
try {
|
|
199
|
-
await handoffRuntime.recover([aid]);
|
|
199
|
+
await handoffRuntime.recover([aid], { discardExpired: false });
|
|
200
200
|
}
|
|
201
201
|
finally {
|
|
202
202
|
handoffRuntime.resumeAgent(aid);
|