sema-core 2.0.11 → 2.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.
- package/dist/core/RunTools.d.ts.map +1 -1
- package/dist/core/RunTools.js +48 -2
- package/dist/core/RunTools.js.map +1 -1
- package/dist/core/SemaCore.d.ts +2 -0
- package/dist/core/SemaCore.d.ts.map +1 -1
- package/dist/core/SemaCore.js +7 -1
- package/dist/core/SemaCore.js.map +1 -1
- package/dist/core/SemaEngine.d.ts +2 -0
- package/dist/core/SemaEngine.d.ts.map +1 -1
- package/dist/core/SemaEngine.js +81 -5
- package/dist/core/SemaEngine.js.map +1 -1
- package/dist/events/types.d.ts +13 -0
- package/dist/events/types.d.ts.map +1 -1
- package/dist/manager/PermissionManager.d.ts.map +1 -1
- package/dist/manager/PermissionManager.js +19 -0
- package/dist/manager/PermissionManager.js.map +1 -1
- package/dist/prompt/toolAliases.d.ts +4 -0
- package/dist/prompt/toolAliases.d.ts.map +1 -1
- package/dist/prompt/toolAliases.js +14 -0
- package/dist/prompt/toolAliases.js.map +1 -1
- package/dist/services/api/adapt/anthropic.js +1 -1
- package/dist/services/api/adapt/anthropic.js.map +1 -1
- package/dist/services/api/adapt/openai.js +1 -1
- package/dist/services/api/adapt/openai.js.map +1 -1
- package/dist/services/api/adapt/util.js +4 -4
- package/dist/services/api/adapt/util.js.map +1 -1
- package/dist/services/hooks/hookRunner.d.ts +21 -0
- package/dist/services/hooks/hookRunner.d.ts.map +1 -0
- package/dist/services/hooks/hookRunner.js +252 -0
- package/dist/services/hooks/hookRunner.js.map +1 -0
- package/dist/services/hooks/hookTriggers.d.ts +65 -0
- package/dist/services/hooks/hookTriggers.d.ts.map +1 -0
- package/dist/services/hooks/hookTriggers.js +295 -0
- package/dist/services/hooks/hookTriggers.js.map +1 -0
- package/dist/services/hooks/hooksManager.d.ts +64 -0
- package/dist/services/hooks/hooksManager.d.ts.map +1 -0
- package/dist/services/hooks/hooksManager.js +346 -0
- package/dist/services/hooks/hooksManager.js.map +1 -0
- package/dist/types/hook.d.ts +76 -0
- package/dist/types/hook.d.ts.map +1 -0
- package/dist/types/hook.js +28 -0
- package/dist/types/hook.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/util/file.d.ts +8 -0
- package/dist/util/file.d.ts.map +1 -1
- package/dist/util/file.js +39 -0
- package/dist/util/file.js.map +1 -1
- package/dist/util/history.d.ts +1 -1
- package/dist/util/history.d.ts.map +1 -1
- package/dist/util/history.js +23 -2
- package/dist/util/history.js.map +1 -1
- package/dist/util/logLLM.js +2 -2
- package/dist/util/logLLM.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook 命令执行器与输出解析
|
|
4
|
+
*
|
|
5
|
+
* 一次性子进程执行(不复用 PersistentShell:其为单例长驻共享 shell,有状态且命令排队),
|
|
6
|
+
* stdin 写入 JSON payload,输出走通用 hooks 协议(exit code + stdout JSON 两条通道)。
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MAX_ADDITIONAL_CONTEXT_CHARS = void 0;
|
|
10
|
+
exports.executeHookCommand = executeHookCommand;
|
|
11
|
+
exports.parseHookOutput = parseHookOutput;
|
|
12
|
+
exports.truncateContext = truncateContext;
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const cwd_1 = require("../../util/cwd");
|
|
15
|
+
const log_1 = require("../../util/log");
|
|
16
|
+
const process_1 = require("../../util/process");
|
|
17
|
+
const platform_1 = require("../../util/platform");
|
|
18
|
+
// 单流输出上限 1MB
|
|
19
|
+
const MAX_STREAM_BYTES = 1024 * 1024;
|
|
20
|
+
// additionalContext 长度上限(超出截断并记 warning)
|
|
21
|
+
exports.MAX_ADDITIONAL_CONTEXT_CHARS = 10_000;
|
|
22
|
+
// SIGTERM 后升级 SIGKILL 的宽限期
|
|
23
|
+
const KILL_GRACE_MS = 2000;
|
|
24
|
+
// SIGKILL 后强制 settle 的期限(不依赖 close/exit 事件到达,保证 Promise 有界结束)
|
|
25
|
+
const SETTLE_GRACE_MS = 2000;
|
|
26
|
+
// 不可阻断的事件(exit 2 / decision block 降级为 pass 并打 blockIgnored 标)。
|
|
27
|
+
// Stop 暂不支持续驱(block stop 强迫模型继续),只作观察型埋点
|
|
28
|
+
const NON_BLOCKABLE_EVENTS = new Set(['SessionStart', 'SessionEnd', 'Stop']);
|
|
29
|
+
/**
|
|
30
|
+
* 终止 hook 进程。POSIX 下 hook 以独立进程组运行(spawn detached),
|
|
31
|
+
* 负 pid 整组终止(含孙进程);Windows 复用 taskkill /f /t(已是整树强杀)
|
|
32
|
+
*/
|
|
33
|
+
function terminateHookProcess(proc, force) {
|
|
34
|
+
if (!proc.pid)
|
|
35
|
+
return;
|
|
36
|
+
try {
|
|
37
|
+
if (platform_1.IS_WIN) {
|
|
38
|
+
(0, process_1.killProcess)(proc);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
try {
|
|
42
|
+
process.kill(-proc.pid, force ? 'SIGKILL' : 'SIGTERM');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// 进程组终止失败(如进程已退出)回落单进程 kill
|
|
46
|
+
try {
|
|
47
|
+
proc.kill(force ? 'SIGKILL' : 'SIGTERM');
|
|
48
|
+
}
|
|
49
|
+
catch { /* 已退出 */ }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
(0, log_1.logWarn)(`[Hook] 终止 hook 进程失败: ${error}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 以一次性子进程执行 hook 命令,payload 经 stdin 写入
|
|
59
|
+
*/
|
|
60
|
+
function executeHookCommand(command, payloadJson, timeoutMs, signal) {
|
|
61
|
+
return new Promise(resolve => {
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
let stdout = '';
|
|
64
|
+
let stderr = '';
|
|
65
|
+
let timedOut = false;
|
|
66
|
+
let settled = false;
|
|
67
|
+
let terminating = false;
|
|
68
|
+
let timeoutTimer = null;
|
|
69
|
+
let escalationTimer = null;
|
|
70
|
+
let deadlineTimer = null;
|
|
71
|
+
let proc;
|
|
72
|
+
const finish = (result) => {
|
|
73
|
+
if (settled)
|
|
74
|
+
return;
|
|
75
|
+
settled = true;
|
|
76
|
+
if (timeoutTimer)
|
|
77
|
+
clearTimeout(timeoutTimer);
|
|
78
|
+
if (escalationTimer)
|
|
79
|
+
clearTimeout(escalationTimer);
|
|
80
|
+
if (deadlineTimer)
|
|
81
|
+
clearTimeout(deadlineTimer);
|
|
82
|
+
if (signal)
|
|
83
|
+
signal.removeEventListener('abort', onAbort);
|
|
84
|
+
resolve({ ...result, durationMs: Date.now() - startTime });
|
|
85
|
+
};
|
|
86
|
+
// 终止升级链(配置超时与 AbortSignal 中断共用同一入口):
|
|
87
|
+
// SIGTERM → KILL_GRACE → SIGKILL → SETTLE_GRACE 到期直接 settle。
|
|
88
|
+
// 最后一级不依赖任何进程事件,是 Promise 有界结束的确定性保证
|
|
89
|
+
const beginTermination = () => {
|
|
90
|
+
if (terminating || settled)
|
|
91
|
+
return;
|
|
92
|
+
terminating = true;
|
|
93
|
+
terminateHookProcess(proc, false);
|
|
94
|
+
escalationTimer = setTimeout(() => {
|
|
95
|
+
if (settled)
|
|
96
|
+
return;
|
|
97
|
+
terminateHookProcess(proc, true);
|
|
98
|
+
deadlineTimer = setTimeout(() => {
|
|
99
|
+
(0, log_1.logWarn)(`[Hook] 进程未在期限内退出,强制结束等待(可能残留进程): ${command}`);
|
|
100
|
+
finish({ exitCode: null, stdout, stderr, timedOut, failedToSpawn: !timedOut });
|
|
101
|
+
}, SETTLE_GRACE_MS);
|
|
102
|
+
}, KILL_GRACE_MS);
|
|
103
|
+
};
|
|
104
|
+
const onAbort = () => beginTermination();
|
|
105
|
+
const { bin, args } = (0, process_1.getShellForSpawn)();
|
|
106
|
+
try {
|
|
107
|
+
proc = (0, child_process_1.spawn)(bin, [...args, command], {
|
|
108
|
+
cwd: (0, cwd_1.readInitialCwd)(),
|
|
109
|
+
env: process.env,
|
|
110
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
111
|
+
// POSIX 下 detached 使 hook 独占进程组,便于整组终止;
|
|
112
|
+
// 子进程不会随宿主退出自动回收,与非 detached 行为一致(SessionEnd 本为尽力而为)
|
|
113
|
+
...(platform_1.IS_WIN ? { windowsHide: true } : { detached: true }),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
(0, log_1.logWarn)(`[Hook] spawn 失败: ${error}`);
|
|
118
|
+
finish({ exitCode: null, stdout: '', stderr: '', timedOut: false, failedToSpawn: true });
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
timeoutTimer = setTimeout(() => {
|
|
122
|
+
timedOut = true;
|
|
123
|
+
beginTermination();
|
|
124
|
+
}, timeoutMs);
|
|
125
|
+
if (signal) {
|
|
126
|
+
if (signal.aborted)
|
|
127
|
+
beginTermination();
|
|
128
|
+
else
|
|
129
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
130
|
+
}
|
|
131
|
+
proc.on('error', error => {
|
|
132
|
+
(0, log_1.logWarn)(`[Hook] 子进程执行失败: ${error}`);
|
|
133
|
+
finish({ exitCode: null, stdout, stderr, timedOut, failedToSpawn: true });
|
|
134
|
+
});
|
|
135
|
+
proc.stdout?.on('data', (chunk) => {
|
|
136
|
+
if (stdout.length < MAX_STREAM_BYTES)
|
|
137
|
+
stdout += chunk.toString('utf-8');
|
|
138
|
+
});
|
|
139
|
+
proc.stderr?.on('data', (chunk) => {
|
|
140
|
+
if (stderr.length < MAX_STREAM_BYTES)
|
|
141
|
+
stderr += chunk.toString('utf-8');
|
|
142
|
+
});
|
|
143
|
+
// EPIPE 防护:脚本不读 stdin 直接退出时 write 会触发 error
|
|
144
|
+
proc.stdin?.on('error', () => { });
|
|
145
|
+
proc.stdin?.write(payloadJson);
|
|
146
|
+
proc.stdin?.end();
|
|
147
|
+
proc.on('close', code => {
|
|
148
|
+
// abort 场景按执行失败处理(外层 fail-open)
|
|
149
|
+
const abortedExternally = signal?.aborted === true && !timedOut;
|
|
150
|
+
finish({
|
|
151
|
+
exitCode: code,
|
|
152
|
+
stdout,
|
|
153
|
+
stderr,
|
|
154
|
+
timedOut,
|
|
155
|
+
failedToSpawn: abortedExternally,
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 解析单条 hook 的执行输出(exit code + stdout JSON 双通道)
|
|
162
|
+
*/
|
|
163
|
+
function parseHookOutput(event, exec) {
|
|
164
|
+
if (exec.timedOut || exec.failedToSpawn) {
|
|
165
|
+
return { kind: 'error' };
|
|
166
|
+
}
|
|
167
|
+
// exit 2:阻断,stderr 作为原因;SessionStart/SessionEnd 不可阻断,降级 pass
|
|
168
|
+
if (exec.exitCode === 2) {
|
|
169
|
+
if (NON_BLOCKABLE_EVENTS.has(event)) {
|
|
170
|
+
(0, log_1.logWarn)(`[Hook] ${event} 不可阻断,忽略 exit 2(stderr: ${exec.stderr.trim().slice(0, 200)})`);
|
|
171
|
+
return { kind: 'pass', blockIgnored: true };
|
|
172
|
+
}
|
|
173
|
+
return { kind: 'block', reason: exec.stderr.trim() || `Blocked by ${event} hook` };
|
|
174
|
+
}
|
|
175
|
+
// 其他非 0 exit code(含 null):hook 执行失败,fail-open(exit 1 明确不阻断)
|
|
176
|
+
if (exec.exitCode !== 0) {
|
|
177
|
+
return { kind: 'error' };
|
|
178
|
+
}
|
|
179
|
+
// exit 0:stdout 若为单个合法 JSON 对象则结构化解析,否则按纯文本处理
|
|
180
|
+
const rawStdout = exec.stdout.trim();
|
|
181
|
+
let parsed = null;
|
|
182
|
+
if (rawStdout.startsWith('{')) {
|
|
183
|
+
try {
|
|
184
|
+
const obj = JSON.parse(rawStdout);
|
|
185
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
186
|
+
parsed = obj;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// 非法 JSON 按纯文本处理
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!parsed) {
|
|
194
|
+
// 纯文本:SessionStart / UserPromptSubmit 作为附加上下文注入,其他事件忽略
|
|
195
|
+
if (rawStdout && (event === 'SessionStart' || event === 'UserPromptSubmit')) {
|
|
196
|
+
return { kind: 'pass', additionalContext: truncateContext(rawStdout) };
|
|
197
|
+
}
|
|
198
|
+
return { kind: 'pass' };
|
|
199
|
+
}
|
|
200
|
+
const outcome = { kind: 'pass' };
|
|
201
|
+
// 通用字段(顶层);未识别字段(continue/stopReason/updatedInput 等)一律静默忽略
|
|
202
|
+
if (typeof parsed.systemMessage === 'string')
|
|
203
|
+
outcome.systemMessage = parsed.systemMessage;
|
|
204
|
+
if (typeof parsed.suppressOutput === 'boolean')
|
|
205
|
+
outcome.suppressOutput = parsed.suppressOutput;
|
|
206
|
+
if (parsed.decision === 'block') {
|
|
207
|
+
if (NON_BLOCKABLE_EVENTS.has(event)) {
|
|
208
|
+
(0, log_1.logWarn)(`[Hook] ${event} 不可阻断,忽略 decision: block`);
|
|
209
|
+
outcome.blockIgnored = true;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
outcome.kind = 'block';
|
|
213
|
+
outcome.reason = typeof parsed.reason === 'string' ? parsed.reason : `Blocked by ${event} hook`;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// 事件专属字段(hookSpecificOutput 壳,hookEventName 为判别字段)
|
|
217
|
+
const hso = parsed.hookSpecificOutput;
|
|
218
|
+
if (hso && typeof hso === 'object' && !Array.isArray(hso)) {
|
|
219
|
+
const shell = hso;
|
|
220
|
+
if (shell.hookEventName !== undefined && shell.hookEventName !== event) {
|
|
221
|
+
(0, log_1.logWarn)(`[Hook] hookSpecificOutput.hookEventName (${shell.hookEventName}) 与事件 ${event} 不匹配,忽略`);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const pd = shell.permissionDecision;
|
|
225
|
+
if (pd !== undefined) {
|
|
226
|
+
if (pd === 'allow' || pd === 'deny' || pd === 'ask') {
|
|
227
|
+
outcome.decision = pd;
|
|
228
|
+
if (typeof shell.permissionDecisionReason === 'string') {
|
|
229
|
+
outcome.reason = shell.permissionDecisionReason;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
(0, log_1.logWarn)(`[Hook] 未识别的 permissionDecision: ${pd},忽略`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (typeof shell.additionalContext === 'string' && shell.additionalContext) {
|
|
237
|
+
outcome.additionalContext = truncateContext(shell.additionalContext);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return outcome;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* additionalContext 截断(上限 10k 字符)
|
|
245
|
+
*/
|
|
246
|
+
function truncateContext(text) {
|
|
247
|
+
if (text.length <= exports.MAX_ADDITIONAL_CONTEXT_CHARS)
|
|
248
|
+
return text;
|
|
249
|
+
(0, log_1.logWarn)(`[Hook] additionalContext 超出 ${exports.MAX_ADDITIONAL_CONTEXT_CHARS} 字符上限,已截断`);
|
|
250
|
+
return text.slice(0, exports.MAX_ADDITIONAL_CONTEXT_CHARS);
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=hookRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookRunner.js","sourceRoot":"","sources":["../../../src/services/hooks/hookRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook 埋点入口
|
|
3
|
+
*
|
|
4
|
+
* 核心链路仅 import 本模块。埋点稳定性硬约束:
|
|
5
|
+
* ① 无匹配条目零开销早退;② 整体 try/catch fail-open,
|
|
6
|
+
* 内部任何错误只记日志不上抛——未配置 hooks 的现有用户零影响。
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* SessionStart:engine session 初始化成功后触发;不可阻断
|
|
10
|
+
* @returns 注入模型上下文的 additionalContext,无则 null
|
|
11
|
+
*/
|
|
12
|
+
export declare function fireSessionStart(sessionId: string): Promise<string | null>;
|
|
13
|
+
/**
|
|
14
|
+
* UserPromptSubmit:用户输入进入命令处理或模型处理前触发
|
|
15
|
+
* block → 丢弃本次输入(原因经 hook:notice 展示给用户,由调用方发出)
|
|
16
|
+
*/
|
|
17
|
+
export declare function fireUserPromptSubmit(sessionId: string, prompt: string, signal?: AbortSignal): Promise<{
|
|
18
|
+
blocked: boolean;
|
|
19
|
+
reason?: string;
|
|
20
|
+
additionalContext?: string;
|
|
21
|
+
ran: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* PreToolUse:工具执行前触发
|
|
25
|
+
* deny → 工具不执行,原因以 is_error tool_result 回给模型(exit 2 等价 deny)
|
|
26
|
+
* allow → 跳过权限询问直接执行;ask/无输出 → 走原权限流程
|
|
27
|
+
*/
|
|
28
|
+
export declare function firePreToolUse(sessionId: string, agentId: string, semaToolName: string, input: unknown, signal?: AbortSignal): Promise<{
|
|
29
|
+
decision: 'allow' | 'deny' | 'none';
|
|
30
|
+
reason?: string;
|
|
31
|
+
ran: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* PostToolUse:工具执行成功后触发
|
|
35
|
+
* @returns contextBlocks 注入模型上下文的文本块(exit 2 的 stderr 与 additionalContext)
|
|
36
|
+
*/
|
|
37
|
+
export declare function firePostToolUse(sessionId: string, agentId: string, semaToolName: string, input: unknown, response: unknown, signal?: AbortSignal): Promise<{
|
|
38
|
+
contextBlocks: string[];
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* PostToolUseFailure:工具执行抛错后触发(可注入纠错提示)
|
|
42
|
+
*/
|
|
43
|
+
export declare function firePostToolUseFailure(sessionId: string, agentId: string, semaToolName: string, input: unknown, error: string, signal?: AbortSignal): Promise<{
|
|
44
|
+
contextBlocks: string[];
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* PermissionRequest:权限系统即将向用户发起询问前触发
|
|
48
|
+
* allow → 批准(等价用户 agree,不产生永久授权);deny → 拒绝(exit 2 等价 deny);
|
|
49
|
+
* ask/无输出 → 保持正常询问流程
|
|
50
|
+
*/
|
|
51
|
+
export declare function firePermissionRequest(sessionId: string, agentId: string, semaToolName: string, input: unknown, signal?: AbortSignal): Promise<{
|
|
52
|
+
decision: 'allow' | 'deny' | 'none';
|
|
53
|
+
reason?: string;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Stop:主链路一轮处理自然完成并转入 idle 时触发,fire-and-forget(观察型埋点)。
|
|
57
|
+
* 不可阻断(暂不支持续驱,block 输出忽略并告警)、不注入上下文;
|
|
58
|
+
* systemMessage 照常经 hook:notice 展示。中断的轮次与排队输入接续的轮次不触发。
|
|
59
|
+
*/
|
|
60
|
+
export declare function fireStop(sessionId: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* SessionEnd:会话关闭时触发,fire-and-forget(不可阻断,输出忽略)
|
|
63
|
+
*/
|
|
64
|
+
export declare function fireSessionEnd(sessionId: string): void;
|
|
65
|
+
//# sourceMappingURL=hookTriggers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookTriggers.d.ts","sourceRoot":"","sources":["../../../src/services/hooks/hookTriggers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmMH;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWhF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC,CAoB1F;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC,CAWjF;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,OAAO,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAUtC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAStC;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAWnE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAYhD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAiBtD"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook 埋点入口
|
|
4
|
+
*
|
|
5
|
+
* 核心链路仅 import 本模块。埋点稳定性硬约束:
|
|
6
|
+
* ① 无匹配条目零开销早退;② 整体 try/catch fail-open,
|
|
7
|
+
* 内部任何错误只记日志不上抛——未配置 hooks 的现有用户零影响。
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.fireSessionStart = fireSessionStart;
|
|
11
|
+
exports.fireUserPromptSubmit = fireUserPromptSubmit;
|
|
12
|
+
exports.firePreToolUse = firePreToolUse;
|
|
13
|
+
exports.firePostToolUse = firePostToolUse;
|
|
14
|
+
exports.firePostToolUseFailure = firePostToolUseFailure;
|
|
15
|
+
exports.firePermissionRequest = firePermissionRequest;
|
|
16
|
+
exports.fireStop = fireStop;
|
|
17
|
+
exports.fireSessionEnd = fireSessionEnd;
|
|
18
|
+
const EventSystem_1 = require("../../events/EventSystem");
|
|
19
|
+
const toolAliases_1 = require("../../prompt/toolAliases");
|
|
20
|
+
const cwd_1 = require("../../util/cwd");
|
|
21
|
+
const log_1 = require("../../util/log");
|
|
22
|
+
const hooksManager_1 = require("./hooksManager");
|
|
23
|
+
const hookRunner_1 = require("./hookRunner");
|
|
24
|
+
const MAIN_AGENT = 'main';
|
|
25
|
+
function neutralAggregate() {
|
|
26
|
+
return { ran: false, blocked: false, decision: 'none', additionalContext: [] };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* fail-open 总兜底:入口全部逻辑(含单例获取、开关读取)都在其中执行,
|
|
30
|
+
* 任何异常只记日志并返回中性结果,绝不上抛到核心链路
|
|
31
|
+
*/
|
|
32
|
+
async function safeRun(neutral, fn) {
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
(0, log_1.logWarn)(`[Hook] 内部错误(fail-open): ${error}`);
|
|
38
|
+
return neutral;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function emitNotice(sessionId, data) {
|
|
42
|
+
(0, EventSystem_1.getEventBus)().emit('hook:notice', data, sessionId);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 顺序执行单个事件下的全部命中条目并聚合结果
|
|
46
|
+
* - 第一个阻断(block / deny)立即停止后续条目
|
|
47
|
+
* - 聚合优先级:deny > ask > allow > none(ask 保守优先于 allow)
|
|
48
|
+
*/
|
|
49
|
+
async function runEventHooks(event, sessionId, payload, entries, signal) {
|
|
50
|
+
const aggregate = { ran: true, blocked: false, decision: 'none', additionalContext: [] };
|
|
51
|
+
const payloadJson = JSON.stringify(payload);
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
// 中断后短路剩余条目,避免逐个 spawn 出立即被 kill 的进程
|
|
54
|
+
if (signal?.aborted)
|
|
55
|
+
break;
|
|
56
|
+
const exec = await (0, hookRunner_1.executeHookCommand)(entry.command, payloadJson, entry.timeoutMs, signal);
|
|
57
|
+
const outcome = (0, hookRunner_1.parseHookOutput)(event, exec);
|
|
58
|
+
// 审计日志(PreToolUse / PermissionRequest 的 allow 等于把权限决策交给 hook 脚本,日志不可省)
|
|
59
|
+
(0, log_1.logInfo)(`[Hook][audit] event=${event} agent=${String(payload.agent_id ?? MAIN_AGENT)} ` +
|
|
60
|
+
`source=${entry.source} command="${entry.command}" timeoutMs=${entry.timeoutMs} ` +
|
|
61
|
+
`exit=${exec.exitCode} timedOut=${exec.timedOut} kind=${outcome.kind} ` +
|
|
62
|
+
`decision=${outcome.decision ?? '-'} duration=${exec.durationMs}ms`);
|
|
63
|
+
if (exec.timedOut) {
|
|
64
|
+
emitNotice(sessionId, {
|
|
65
|
+
kind: 'warning',
|
|
66
|
+
hookEvent: event,
|
|
67
|
+
message: `hook 执行超时(${entry.timeoutMs / 1000}s)已终止: ${entry.command}`,
|
|
68
|
+
command: entry.command,
|
|
69
|
+
source: entry.source,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// 不可阻断事件上的 block 输出被忽略:告警而非静默,
|
|
73
|
+
// 避免用户从其他工具迁移来的续驱配置(Stop + exit 2)看似生效实则无效
|
|
74
|
+
if (outcome.blockIgnored) {
|
|
75
|
+
emitNotice(sessionId, {
|
|
76
|
+
kind: 'warning',
|
|
77
|
+
hookEvent: event,
|
|
78
|
+
message: `${event} 事件不支持阻断,hook 的 block 输出已忽略: ${entry.command}`,
|
|
79
|
+
command: entry.command,
|
|
80
|
+
source: entry.source,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (outcome.systemMessage) {
|
|
84
|
+
emitNotice(sessionId, {
|
|
85
|
+
kind: 'systemMessage',
|
|
86
|
+
hookEvent: event,
|
|
87
|
+
message: outcome.systemMessage,
|
|
88
|
+
command: entry.command,
|
|
89
|
+
source: entry.source,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (outcome.additionalContext) {
|
|
93
|
+
aggregate.additionalContext.push(outcome.additionalContext);
|
|
94
|
+
}
|
|
95
|
+
// fail-closed 条目:hook 执行失败按阻断处理
|
|
96
|
+
const effectiveKind = outcome.kind === 'error' && entry.failClosed ? 'block' : outcome.kind;
|
|
97
|
+
if (effectiveKind === 'block') {
|
|
98
|
+
aggregate.blocked = true;
|
|
99
|
+
aggregate.blockReason =
|
|
100
|
+
outcome.kind === 'error'
|
|
101
|
+
? `hook failed (fail-closed): ${entry.command}`
|
|
102
|
+
: outcome.reason;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
if (outcome.decision === 'deny') {
|
|
106
|
+
aggregate.decision = 'deny';
|
|
107
|
+
aggregate.decisionReason = outcome.reason;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
if (outcome.decision === 'ask') {
|
|
111
|
+
aggregate.decision = 'ask';
|
|
112
|
+
if (outcome.reason)
|
|
113
|
+
aggregate.decisionReason = outcome.reason;
|
|
114
|
+
}
|
|
115
|
+
else if (outcome.decision === 'allow' && aggregate.decision === 'none') {
|
|
116
|
+
aggregate.decision = 'allow';
|
|
117
|
+
if (outcome.reason)
|
|
118
|
+
aggregate.decisionReason = outcome.reason;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 聚合后总量再做一次截断
|
|
122
|
+
const total = aggregate.additionalContext.join('\n\n');
|
|
123
|
+
if (total.length > hookRunner_1.MAX_ADDITIONAL_CONTEXT_CHARS) {
|
|
124
|
+
aggregate.additionalContext = [(0, hookRunner_1.truncateContext)(total)];
|
|
125
|
+
}
|
|
126
|
+
return aggregate;
|
|
127
|
+
}
|
|
128
|
+
function buildCommonPayload(event, sessionId, agentId) {
|
|
129
|
+
return {
|
|
130
|
+
session_id: sessionId,
|
|
131
|
+
cwd: (0, cwd_1.readInitialCwd)(),
|
|
132
|
+
hook_event_name: event,
|
|
133
|
+
agent_id: agentId,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 工具类事件的统一触发(PreToolUse / PostToolUse / PostToolUseFailure / PermissionRequest)
|
|
138
|
+
*/
|
|
139
|
+
async function runToolEventHooks(event, sessionId, agentId, semaToolName, extraPayload, signal) {
|
|
140
|
+
// ran 在 safeRun 外持有:条目进入执行链路后即置位,
|
|
141
|
+
// 后续执行失败/被中断(fail-open 返回中性结果)时 ran 仍为 true
|
|
142
|
+
let ran = false;
|
|
143
|
+
const result = await safeRun(neutralAggregate(), async () => {
|
|
144
|
+
const manager = (0, hooksManager_1.getHooksManager)();
|
|
145
|
+
await manager.ready();
|
|
146
|
+
const genericToolName = (0, toolAliases_1.toGenericToolName)(semaToolName);
|
|
147
|
+
const entries = manager.getMatchedEntries(event, genericToolName, semaToolName);
|
|
148
|
+
if (entries.length === 0)
|
|
149
|
+
return neutralAggregate();
|
|
150
|
+
ran = true;
|
|
151
|
+
const payload = {
|
|
152
|
+
...buildCommonPayload(event, sessionId, agentId),
|
|
153
|
+
tool_name: genericToolName,
|
|
154
|
+
sema_tool_name: semaToolName,
|
|
155
|
+
...extraPayload,
|
|
156
|
+
};
|
|
157
|
+
return runEventHooks(event, sessionId, payload, entries, signal);
|
|
158
|
+
});
|
|
159
|
+
return { ...result, ran };
|
|
160
|
+
}
|
|
161
|
+
// ==================== 8 个事件入口 ====================
|
|
162
|
+
/**
|
|
163
|
+
* SessionStart:engine session 初始化成功后触发;不可阻断
|
|
164
|
+
* @returns 注入模型上下文的 additionalContext,无则 null
|
|
165
|
+
*/
|
|
166
|
+
async function fireSessionStart(sessionId) {
|
|
167
|
+
return safeRun(null, async () => {
|
|
168
|
+
const manager = (0, hooksManager_1.getHooksManager)();
|
|
169
|
+
await manager.ready();
|
|
170
|
+
const entries = manager.getMatchedEntries('SessionStart');
|
|
171
|
+
if (entries.length === 0)
|
|
172
|
+
return null;
|
|
173
|
+
const payload = { ...buildCommonPayload('SessionStart', sessionId, MAIN_AGENT), source: 'startup' };
|
|
174
|
+
const aggregate = await runEventHooks('SessionStart', sessionId, payload, entries);
|
|
175
|
+
return aggregate.additionalContext.length > 0 ? aggregate.additionalContext.join('\n\n') : null;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* UserPromptSubmit:用户输入进入命令处理或模型处理前触发
|
|
180
|
+
* block → 丢弃本次输入(原因经 hook:notice 展示给用户,由调用方发出)
|
|
181
|
+
*/
|
|
182
|
+
async function fireUserPromptSubmit(sessionId, prompt, signal) {
|
|
183
|
+
const neutral = { blocked: false };
|
|
184
|
+
let ran = false;
|
|
185
|
+
const result = await safeRun(neutral, async () => {
|
|
186
|
+
const manager = (0, hooksManager_1.getHooksManager)();
|
|
187
|
+
await manager.ready();
|
|
188
|
+
const entries = manager.getMatchedEntries('UserPromptSubmit');
|
|
189
|
+
if (entries.length === 0)
|
|
190
|
+
return neutral;
|
|
191
|
+
ran = true;
|
|
192
|
+
const payload = { ...buildCommonPayload('UserPromptSubmit', sessionId, MAIN_AGENT), prompt };
|
|
193
|
+
const aggregate = await runEventHooks('UserPromptSubmit', sessionId, payload, entries, signal);
|
|
194
|
+
return {
|
|
195
|
+
blocked: aggregate.blocked,
|
|
196
|
+
reason: aggregate.blockReason,
|
|
197
|
+
additionalContext: aggregate.additionalContext.length > 0 ? aggregate.additionalContext.join('\n\n') : undefined,
|
|
198
|
+
};
|
|
199
|
+
});
|
|
200
|
+
return { ...result, ran };
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* PreToolUse:工具执行前触发
|
|
204
|
+
* deny → 工具不执行,原因以 is_error tool_result 回给模型(exit 2 等价 deny)
|
|
205
|
+
* allow → 跳过权限询问直接执行;ask/无输出 → 走原权限流程
|
|
206
|
+
*/
|
|
207
|
+
async function firePreToolUse(sessionId, agentId, semaToolName, input, signal) {
|
|
208
|
+
const aggregate = await runToolEventHooks('PreToolUse', sessionId, agentId, semaToolName, { tool_input: input }, signal);
|
|
209
|
+
if (aggregate.blocked) {
|
|
210
|
+
return { decision: 'deny', reason: aggregate.blockReason, ran: aggregate.ran };
|
|
211
|
+
}
|
|
212
|
+
if (aggregate.decision === 'allow' || aggregate.decision === 'deny') {
|
|
213
|
+
return { decision: aggregate.decision, reason: aggregate.decisionReason, ran: aggregate.ran };
|
|
214
|
+
}
|
|
215
|
+
return { decision: 'none', ran: aggregate.ran };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* PostToolUse:工具执行成功后触发
|
|
219
|
+
* @returns contextBlocks 注入模型上下文的文本块(exit 2 的 stderr 与 additionalContext)
|
|
220
|
+
*/
|
|
221
|
+
async function firePostToolUse(sessionId, agentId, semaToolName, input, response, signal) {
|
|
222
|
+
const aggregate = await runToolEventHooks('PostToolUse', sessionId, agentId, semaToolName, { tool_input: input, tool_response: response }, signal);
|
|
223
|
+
const contextBlocks = [...aggregate.additionalContext];
|
|
224
|
+
if (aggregate.blocked && aggregate.blockReason) {
|
|
225
|
+
// 工具已执行完,无法撤销,stderr 仅回灌模型
|
|
226
|
+
contextBlocks.push(`[PostToolUse hook] ${aggregate.blockReason}`);
|
|
227
|
+
}
|
|
228
|
+
return { contextBlocks };
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* PostToolUseFailure:工具执行抛错后触发(可注入纠错提示)
|
|
232
|
+
*/
|
|
233
|
+
async function firePostToolUseFailure(sessionId, agentId, semaToolName, input, error, signal) {
|
|
234
|
+
const aggregate = await runToolEventHooks('PostToolUseFailure', sessionId, agentId, semaToolName, { tool_input: input, error }, signal);
|
|
235
|
+
const contextBlocks = [...aggregate.additionalContext];
|
|
236
|
+
if (aggregate.blocked && aggregate.blockReason) {
|
|
237
|
+
contextBlocks.push(`[PostToolUseFailure hook] ${aggregate.blockReason}`);
|
|
238
|
+
}
|
|
239
|
+
return { contextBlocks };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* PermissionRequest:权限系统即将向用户发起询问前触发
|
|
243
|
+
* allow → 批准(等价用户 agree,不产生永久授权);deny → 拒绝(exit 2 等价 deny);
|
|
244
|
+
* ask/无输出 → 保持正常询问流程
|
|
245
|
+
*/
|
|
246
|
+
async function firePermissionRequest(sessionId, agentId, semaToolName, input, signal) {
|
|
247
|
+
const aggregate = await runToolEventHooks('PermissionRequest', sessionId, agentId, semaToolName, { tool_input: input }, signal);
|
|
248
|
+
if (aggregate.blocked) {
|
|
249
|
+
return { decision: 'deny', reason: aggregate.blockReason };
|
|
250
|
+
}
|
|
251
|
+
if (aggregate.decision === 'allow' || aggregate.decision === 'deny') {
|
|
252
|
+
return { decision: aggregate.decision, reason: aggregate.decisionReason };
|
|
253
|
+
}
|
|
254
|
+
return { decision: 'none' };
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Stop:主链路一轮处理自然完成并转入 idle 时触发,fire-and-forget(观察型埋点)。
|
|
258
|
+
* 不可阻断(暂不支持续驱,block 输出忽略并告警)、不注入上下文;
|
|
259
|
+
* systemMessage 照常经 hook:notice 展示。中断的轮次与排队输入接续的轮次不触发。
|
|
260
|
+
*/
|
|
261
|
+
function fireStop(sessionId) {
|
|
262
|
+
void safeRun(null, async () => {
|
|
263
|
+
const manager = (0, hooksManager_1.getHooksManager)();
|
|
264
|
+
await manager.ready();
|
|
265
|
+
const entries = manager.getMatchedEntries('Stop');
|
|
266
|
+
if (entries.length === 0)
|
|
267
|
+
return null;
|
|
268
|
+
// stop_hook_active 对齐通用 hooks 字段形状(无续驱恒为 false),方便脚本跨端复用
|
|
269
|
+
const payload = { ...buildCommonPayload('Stop', sessionId, MAIN_AGENT), stop_hook_active: false };
|
|
270
|
+
await runEventHooks('Stop', sessionId, payload, entries);
|
|
271
|
+
return null;
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* SessionEnd:会话关闭时触发,fire-and-forget(不可阻断,输出忽略)
|
|
276
|
+
*/
|
|
277
|
+
function fireSessionEnd(sessionId) {
|
|
278
|
+
void safeRun(null, async () => {
|
|
279
|
+
// async 函数体在首个 await 前同步执行:缓存就绪时条目在本调用返回前即被同步捕获,
|
|
280
|
+
// 不受 SemaCore.dispose 同步链路随后清空 hooksManager 缓存的影响(捕获的是过滤后的新数组)。
|
|
281
|
+
// 缓存未就绪(会话刚创建即销毁的窄窗口)走异步加载兜底,此时仍可能因 dispose 竞态跳过——
|
|
282
|
+
// SessionEnd 本为 best-effort(宿主进程随即退出也可能截断 hook 执行),该残余可接受
|
|
283
|
+
const manager = (0, hooksManager_1.getHooksManager)();
|
|
284
|
+
if (!manager.isReady()) {
|
|
285
|
+
await manager.ready();
|
|
286
|
+
}
|
|
287
|
+
const entries = manager.getMatchedEntries('SessionEnd');
|
|
288
|
+
if (entries.length === 0)
|
|
289
|
+
return null;
|
|
290
|
+
const payload = { ...buildCommonPayload('SessionEnd', sessionId, MAIN_AGENT), reason: 'dispose' };
|
|
291
|
+
await runEventHooks('SessionEnd', sessionId, payload, entries);
|
|
292
|
+
return null;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=hookTriggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookTriggers.js","sourceRoot":"","sources":["../../../src/services/hooks/hookTriggers.ts"],"names":[],"mappings":"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"}
|