evolcore 0.0.9 → 0.0.11
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 +29 -0
- package/README.md +3 -3
- package/dist/agents/baseagent.js +4 -0
- package/dist/agents/claude-runner.js +123 -42
- package/dist/agents/codex-app-server-client.js +33 -9
- package/dist/agents/codex-runner.js +58 -8
- package/dist/agents/ecagent-runner.js +17 -2
- package/dist/agents/request-identity.js +55 -0
- package/dist/aun/outbox.js +28 -31
- package/dist/channels/aun.js +131 -128
- package/dist/cli/agent-command.js +16 -9
- package/dist/cli/agent.js +82 -19
- package/dist/cli/daemon-commands.js +21 -2
- package/dist/cli/index.js +76 -61
- package/dist/cli/init-cancel.js +208 -0
- package/dist/cli/init-channel.js +343 -195
- package/dist/cli/init.js +21 -9
- package/dist/config/builtin-roles.js +1 -0
- package/dist/config/contact-book-store.js +1 -1
- package/dist/config/gateway-config.js +26 -10
- package/dist/core/agent-reload-coordinator.js +53 -0
- package/dist/core/auth/operation-authorizer.js +32 -147
- package/dist/core/auth/operation-catalog.js +80 -0
- package/dist/core/bootstrap-messages.js +50 -0
- package/dist/core/bootstrap-service.js +85 -10
- package/dist/core/channel-loader.js +23 -6
- package/dist/core/command/agent-control.js +14 -11
- package/dist/core/command/menu-handler.js +67 -76
- package/dist/core/command/slash-handler.js +4 -4
- package/dist/core/data-migration.js +79 -27
- package/dist/core/evolagent-registry.js +125 -35
- package/dist/core/evolagent.js +8 -3
- package/dist/core/inference/text-inference.js +38 -4
- package/dist/core/message/message-bridge.js +1 -1
- package/dist/core/message/message-log.js +22 -0
- package/dist/core/message/message-queue.js +19 -4
- package/dist/core/model/model-catalog.js +143 -24
- package/dist/core/model/model-diagnostics.js +28 -10
- package/dist/core/permission/index.js +1 -0
- package/dist/core/permission/readonly-shell-query.js +532 -0
- package/dist/core/permission/shell-environment.js +46 -0
- package/dist/core/permission/tool-policy.js +231 -93
- package/dist/core/protected-paths.js +10 -7
- package/dist/core/runner-reload-transaction.js +57 -0
- package/dist/index.js +262 -84
- package/dist/ipc.js +29 -11
- package/dist/utils/aid-bind.js +3 -8
- package/dist/utils/log-writer.js +6 -10
- package/dist/utils/logger.js +5 -5
- package/kits/docs/evolcore/msg.md +13 -0
- package/kits/rules/01-overview.md +9 -0
- package/kits/schemas/agent-config.schema.3.json +1 -1
- package/kits/schemas/agent-config.schema.4.json +1 -1
- package/kits/schemas/relation-config.schema.2.json +1 -1
- package/kits/schemas/role-config.schema.1.json +1 -1
- package/kits/templates/roles/admin.json +5 -0
- package/kits/templates/roles/member.json +17 -0
- package/kits/templates/roles/visitor.json +8 -0
- package/kits/templates/system-fragments/bootstrap.md +12 -6
- package/kits/templates/system-fragments/channel.md +6 -0
- package/kits/templates/system-fragments/session.md +2 -0
- package/package.json +2 -1
- package/skills/eclink/SKILL.md +15 -3
- package/skills/eclink/agents/openai.yaml +3 -3
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { setupRawKeyListener } from './raw-key-input.js';
|
|
2
|
+
const ESC = '\u001b';
|
|
3
|
+
const ANSI_SEQUENCE_TIMEOUT_MS = 40;
|
|
4
|
+
export const INIT_DOUBLE_ESCAPE_WINDOW_MS = 500;
|
|
5
|
+
export class InitCancelledError extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('EvolCore init cancelled');
|
|
8
|
+
this.name = 'InitCancelledError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function isInitCancelledError(error) {
|
|
12
|
+
return error instanceof InitCancelledError || (error instanceof Error && error.name === 'InitCancelledError');
|
|
13
|
+
}
|
|
14
|
+
export function printInitCancelHint() {
|
|
15
|
+
if (process.stdin.isTTY) {
|
|
16
|
+
console.log('提示:任意步骤连续按两次 Esc 退出(Ctrl+C 也可退出)\n');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function isAnsiFinalByte(char) {
|
|
20
|
+
const code = char.charCodeAt(0);
|
|
21
|
+
return code >= 0x40 && code <= 0x7e;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect two standalone Escape presses without treating arrow/function-key
|
|
25
|
+
* escape sequences as Escape presses.
|
|
26
|
+
*/
|
|
27
|
+
export function createDoubleEscapeDetector(onDoubleEscape, windowMs = INIT_DOUBLE_ESCAPE_WINDOW_MS) {
|
|
28
|
+
let pendingBareEscape = false;
|
|
29
|
+
let pendingTimer;
|
|
30
|
+
let lastBareEscapeAt = 0;
|
|
31
|
+
let ansiSequence = '';
|
|
32
|
+
let disposed = false;
|
|
33
|
+
let triggered = false;
|
|
34
|
+
const clearPending = () => {
|
|
35
|
+
if (pendingTimer)
|
|
36
|
+
clearTimeout(pendingTimer);
|
|
37
|
+
pendingTimer = undefined;
|
|
38
|
+
pendingBareEscape = false;
|
|
39
|
+
};
|
|
40
|
+
const registerBareEscape = () => {
|
|
41
|
+
if (disposed || triggered)
|
|
42
|
+
return;
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
if (lastBareEscapeAt > 0 && now - lastBareEscapeAt <= windowMs) {
|
|
45
|
+
lastBareEscapeAt = 0;
|
|
46
|
+
triggered = true;
|
|
47
|
+
onDoubleEscape();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
lastBareEscapeAt = now;
|
|
51
|
+
};
|
|
52
|
+
const scheduleBareEscape = () => {
|
|
53
|
+
clearPending();
|
|
54
|
+
pendingBareEscape = true;
|
|
55
|
+
pendingTimer = setTimeout(() => {
|
|
56
|
+
pendingTimer = undefined;
|
|
57
|
+
pendingBareEscape = false;
|
|
58
|
+
registerBareEscape();
|
|
59
|
+
}, ANSI_SEQUENCE_TIMEOUT_MS);
|
|
60
|
+
};
|
|
61
|
+
const handle = (chunk) => {
|
|
62
|
+
if (disposed)
|
|
63
|
+
return;
|
|
64
|
+
const text = String(chunk);
|
|
65
|
+
for (let index = 0; index < text.length; index++) {
|
|
66
|
+
const char = text[index];
|
|
67
|
+
if (ansiSequence) {
|
|
68
|
+
lastBareEscapeAt = 0;
|
|
69
|
+
ansiSequence += char;
|
|
70
|
+
if (ansiSequence.length === 2 && ansiSequence[1] !== '[' && ansiSequence[1] !== 'O') {
|
|
71
|
+
ansiSequence = '';
|
|
72
|
+
}
|
|
73
|
+
else if (ansiSequence.length >= 2 && isAnsiFinalByte(char)) {
|
|
74
|
+
ansiSequence = '';
|
|
75
|
+
}
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (pendingBareEscape) {
|
|
79
|
+
clearPending();
|
|
80
|
+
if (char === ESC) {
|
|
81
|
+
registerBareEscape();
|
|
82
|
+
registerBareEscape();
|
|
83
|
+
}
|
|
84
|
+
else if (char === '[' || char === 'O') {
|
|
85
|
+
lastBareEscapeAt = 0;
|
|
86
|
+
ansiSequence = `${ESC}${char}`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
lastBareEscapeAt = 0;
|
|
90
|
+
}
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (char !== ESC) {
|
|
94
|
+
lastBareEscapeAt = 0;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const next = text[index + 1];
|
|
98
|
+
if (next === ESC) {
|
|
99
|
+
registerBareEscape();
|
|
100
|
+
registerBareEscape();
|
|
101
|
+
index++;
|
|
102
|
+
}
|
|
103
|
+
else if (next === '[' || next === 'O') {
|
|
104
|
+
lastBareEscapeAt = 0;
|
|
105
|
+
ansiSequence = `${ESC}${next}`;
|
|
106
|
+
index++;
|
|
107
|
+
}
|
|
108
|
+
else if (next !== undefined) {
|
|
109
|
+
lastBareEscapeAt = 0;
|
|
110
|
+
index++;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
scheduleBareEscape();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
handle,
|
|
119
|
+
dispose: () => {
|
|
120
|
+
disposed = true;
|
|
121
|
+
clearPending();
|
|
122
|
+
ansiSequence = '';
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export function setupDoubleEscapeListener(onDoubleEscape, input = process.stdin) {
|
|
127
|
+
if (!input || typeof input.on !== 'function' || typeof input.removeListener !== 'function')
|
|
128
|
+
return () => { };
|
|
129
|
+
const detector = createDoubleEscapeDetector(onDoubleEscape);
|
|
130
|
+
const handler = (chunk) => detector.handle(chunk);
|
|
131
|
+
input.on('data', handler);
|
|
132
|
+
return () => {
|
|
133
|
+
input.removeListener('data', handler);
|
|
134
|
+
detector.dispose();
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export function setupInitRawKeyListener(onKey, onDoubleEscape, input = process.stdin) {
|
|
138
|
+
const detector = createDoubleEscapeDetector(onDoubleEscape);
|
|
139
|
+
const cleanupRaw = setupRawKeyListener(key => {
|
|
140
|
+
detector.handle(key);
|
|
141
|
+
onKey(key);
|
|
142
|
+
}, input);
|
|
143
|
+
return () => {
|
|
144
|
+
cleanupRaw();
|
|
145
|
+
detector.dispose();
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** readline.question with the shared double-Escape cancellation behavior. */
|
|
149
|
+
export function askInit(rl, question) {
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
let settled = false;
|
|
152
|
+
const input = rl.input;
|
|
153
|
+
let cleanupInput = () => { };
|
|
154
|
+
const cleanup = () => {
|
|
155
|
+
cleanupInput();
|
|
156
|
+
rl.removeListener('SIGINT', cancel);
|
|
157
|
+
};
|
|
158
|
+
const cancel = () => {
|
|
159
|
+
if (settled)
|
|
160
|
+
return;
|
|
161
|
+
settled = true;
|
|
162
|
+
cleanup();
|
|
163
|
+
try {
|
|
164
|
+
rl.close();
|
|
165
|
+
}
|
|
166
|
+
catch { /* ignore */ }
|
|
167
|
+
try {
|
|
168
|
+
input?.pause?.();
|
|
169
|
+
}
|
|
170
|
+
catch { /* ignore */ }
|
|
171
|
+
reject(new InitCancelledError());
|
|
172
|
+
};
|
|
173
|
+
cleanupInput = setupDoubleEscapeListener(cancel, input);
|
|
174
|
+
rl.once('SIGINT', cancel);
|
|
175
|
+
try {
|
|
176
|
+
rl.question(question, answer => {
|
|
177
|
+
if (settled)
|
|
178
|
+
return;
|
|
179
|
+
settled = true;
|
|
180
|
+
cleanup();
|
|
181
|
+
resolve(answer);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
if (!settled) {
|
|
186
|
+
settled = true;
|
|
187
|
+
cleanup();
|
|
188
|
+
reject(error);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
export function waitForInitDelay(ms, signal) {
|
|
194
|
+
if (signal?.aborted)
|
|
195
|
+
return Promise.reject(new InitCancelledError());
|
|
196
|
+
return new Promise((resolve, reject) => {
|
|
197
|
+
const onAbort = () => {
|
|
198
|
+
clearTimeout(timer);
|
|
199
|
+
signal?.removeEventListener('abort', onAbort);
|
|
200
|
+
reject(new InitCancelledError());
|
|
201
|
+
};
|
|
202
|
+
const timer = setTimeout(() => {
|
|
203
|
+
signal?.removeEventListener('abort', onAbort);
|
|
204
|
+
resolve();
|
|
205
|
+
}, ms);
|
|
206
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
207
|
+
});
|
|
208
|
+
}
|