@x-otto/hook-contracts 0.0.1-alpha.0
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/README.md +74 -0
- package/dist/index.d.ts +407 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @x-otto/hook-contracts
|
|
2
|
+
|
|
3
|
+
> Engine↔hooks pure type contracts. Zero runtime — `export type` only, compiled output is empty.
|
|
4
|
+
|
|
5
|
+
`@x-otto/hook-contracts` defines the type-level contract between the engine (`@x-otto/agent`) and the hook system (`@x-otto/hooks`). It provides 25 hook timings with typed input/output payloads, the unified `AgentMessage` type, permission config shapes, and re-exports session event types from `@x-otto/interchange`. Both sides `import type`, avoiding a circular runtime dependency.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @x-otto/hook-contracts
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import type {
|
|
17
|
+
HookTiming,
|
|
18
|
+
HookPayloadMap,
|
|
19
|
+
HookHandle,
|
|
20
|
+
ObserverTiming,
|
|
21
|
+
InterceptorTiming,
|
|
22
|
+
} from '@x-otto/hook-contracts'
|
|
23
|
+
|
|
24
|
+
// Define an observer (output is void)
|
|
25
|
+
function logToolExecution(
|
|
26
|
+
input: HookPayloadMap['tool.execute.before']['input'],
|
|
27
|
+
) {
|
|
28
|
+
console.log(`Tool ${input.toolName} starting`)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Hook payload types are derived automatically
|
|
32
|
+
type ToolBeforeOutput = HookPayloadMap['tool.execute.before']['output']
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### Hook Timing Types
|
|
38
|
+
- `HookTiming` — 25 timing string literals
|
|
39
|
+
- `HookPayloadMap` — timing → `{ input, output }` type map
|
|
40
|
+
- `HookInput<T extends HookTiming>` / `HookOutput<T extends HookTiming>` — extract payload by timing
|
|
41
|
+
- `ObserverTiming` — compile-time subset: timings where output is `void` (read-only observation)
|
|
42
|
+
- `InterceptorTiming` — compile-time subset: timings where output can modify behavior
|
|
43
|
+
- `HookHandle<T extends HookTiming>` — derives correct handler signature
|
|
44
|
+
|
|
45
|
+
### Hook Payload Types
|
|
46
|
+
- `ChatMessageInput` / `ChatMessageOutput` — message interception
|
|
47
|
+
- `ToolExecuteBeforeInput` / `ToolExecuteBeforeOutput` — tool pre-execution (with `PermissionDecision`)
|
|
48
|
+
- `ToolExecuteAfterInput` / `ToolExecuteAfterOutput` — tool post-execution
|
|
49
|
+
- `MessagesTransformInput` / `MessagesTransformOutput` — message array transformation
|
|
50
|
+
- `ChatParamsInput` / `ChatParamsOutput` — LLM call parameter override
|
|
51
|
+
- `SystemPromptTransformInput` / `SystemPromptTransformOutput` — system prompt injection
|
|
52
|
+
- `SessionEventInput` — session lifecycle event observation
|
|
53
|
+
|
|
54
|
+
### Permission & Agent Types
|
|
55
|
+
- `PermissionMode`, `PermissionRuleConfig`, `PermissionPolicySetting` — permission config shapes
|
|
56
|
+
- `PERMISSION_MODES` — `bypass` / `auto` / `confirm` / `strict` / `readonly`
|
|
57
|
+
- `AgentMessage` — unified message type (user/assistant/tool/system/custom)
|
|
58
|
+
- `SystemAgentMessage` — engine/host UI notifications (not sent to provider)
|
|
59
|
+
- `CustomAgentMessages` — application-level declaration merging extension point
|
|
60
|
+
- `ToolCallContext<Params>` — typed tool execution context
|
|
61
|
+
|
|
62
|
+
### Session Event Re-exports (from `@x-otto/interchange`)
|
|
63
|
+
- `AgentSessionEvent` / `AgentSessionEventType` — full session event discriminant union
|
|
64
|
+
- `AskUserQuestion`, `GrillQuestion`, `GrillOption`, `GrillAnswer`, `GrillRequest` — HITL types
|
|
65
|
+
- `AgentSessionSubscriber`, `AgentSessionEventMap`
|
|
66
|
+
|
|
67
|
+
## Dependencies
|
|
68
|
+
|
|
69
|
+
- Internal: `@x-otto/interchange` (type-only)
|
|
70
|
+
- External: none
|
|
71
|
+
|
|
72
|
+
## Related
|
|
73
|
+
|
|
74
|
+
- [Architecture](./ARCHITECTURE.md)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { AgentSessionEvent, AgentSessionEventMap, AgentSessionEventType, AgentSessionSubscriber, AgentTool, AskUserQuestion, GrillAnswer, GrillOption, GrillQuestion, GrillRequest, Message, ToolCallContext, ToolCallEvent, ToolErrorKind, ToolResult } from "@x-otto/interchange";
|
|
2
|
+
|
|
3
|
+
//#region src/messages.d.ts
|
|
4
|
+
interface CustomAgentMessages {}
|
|
5
|
+
type SystemMessageLevel = 'info' | 'warning' | 'error';
|
|
6
|
+
/**
|
|
7
|
+
* 系统通知消息(M40-B0-04,对齐 CC SystemMessage 的本地子集)。
|
|
8
|
+
*
|
|
9
|
+
* 引擎/宿主产生的 UI 通知(回合耗时、记忆保存、压缩边界、API 错误等),
|
|
10
|
+
* 属于 AgentMessage(hooks/UI 域)但**不是协议消息**——agent 的
|
|
11
|
+
* convertToLLM 在类型边界过滤,绝不进 provider 请求(providers 按 role
|
|
12
|
+
* if/else 分支,未知角色会被静默丢弃或破坏请求构建)。
|
|
13
|
+
*
|
|
14
|
+
* subtype 驱动渲染分派(SystemTextMessage 的 subtype switch);
|
|
15
|
+
* `(string & {})` 允许宿主扩展自定义子类型同时保留内建集的自动补全。
|
|
16
|
+
* level 驱动严重性门控(info 默认不渲染除非 verbose)与着色。
|
|
17
|
+
*/
|
|
18
|
+
interface SystemAgentMessage {
|
|
19
|
+
role: 'system';
|
|
20
|
+
subtype?: 'turn_duration' | 'memory_saved' | 'compact_boundary' | 'api_error' | 'local_command' | (string & {});
|
|
21
|
+
level?: SystemMessageLevel;
|
|
22
|
+
content: string;
|
|
23
|
+
/** Unix 时间戳(毫秒),与 @x-otto/interchange Timestamp 同语义。 */
|
|
24
|
+
timestamp: number;
|
|
25
|
+
/** 稳定消息身份(可选,同 @x-otto/interchange 消息的 uuid 语义)。 */
|
|
26
|
+
uuid?: string;
|
|
27
|
+
}
|
|
28
|
+
type AgentMessage = Message | SystemAgentMessage | CustomAgentMessages[keyof CustomAgentMessages];
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/timings.d.ts
|
|
31
|
+
type HookTiming = 'chat.message.before' | 'chat.message.after' | 'tool.execute.before' | 'tool.execute.after' | 'messages.transform' | 'chat.params' | 'session.created' | 'session.restored' | 'session.deleted' | 'session.idle' | 'session.error' | 'stream.start' | 'stream.end' | 'compaction.before' | 'compaction.after' | 'memory.prune.before' | 'process.spawned' | 'process.exited' | 'task.created' | 'task.started' | 'task.completed' | 'task.failed' | 'task.cancelled' | 'system.prompt.transform' | 'notification';
|
|
32
|
+
interface ChatMessageInput {
|
|
33
|
+
message: AgentMessage;
|
|
34
|
+
sessionId: string;
|
|
35
|
+
isFirstMessage: boolean;
|
|
36
|
+
metadata: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
interface ChatMessageOutput {
|
|
39
|
+
message: AgentMessage;
|
|
40
|
+
cancelled: boolean;
|
|
41
|
+
metadata: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
interface ToolExecuteBeforeInput {
|
|
44
|
+
toolName: string;
|
|
45
|
+
toolCallId: string;
|
|
46
|
+
args: Record<string, unknown>;
|
|
47
|
+
agentName: string;
|
|
48
|
+
sessionId: string;
|
|
49
|
+
/**
|
|
50
|
+
* 执行器据工具声明的 AgentTool.pathParams 从 args 解析出的文件系统路径。
|
|
51
|
+
* PEP(permission/file guard)只读此字段做路径规则匹配,不再从 args 硬编码猜参数名。
|
|
52
|
+
*/
|
|
53
|
+
paths?: readonly string[];
|
|
54
|
+
/**
|
|
55
|
+
* 工具是否为只读(AgentTool.readonly)。sandbox-guard 据此跳过写评估——
|
|
56
|
+
* read/grep/find/lsp 等只读工具的 paths 是读目标而非写目标,不应被当作越界写而误升 ask/deny。
|
|
57
|
+
*/
|
|
58
|
+
readonly?: boolean;
|
|
59
|
+
}
|
|
60
|
+
type PermissionDecision = 'allow' | 'deny' | 'ask';
|
|
61
|
+
/** 审批显示等级(仅驱动 UI 文案/排序,不参与 allow/deny/ask 裁决)。 */
|
|
62
|
+
type ApprovalRisk = 'low' | 'medium' | 'high';
|
|
63
|
+
interface ToolExecuteBeforeOutput {
|
|
64
|
+
args: Record<string, unknown>;
|
|
65
|
+
cancelled: boolean;
|
|
66
|
+
cancelReason?: string;
|
|
67
|
+
decision?: PermissionDecision;
|
|
68
|
+
decisionReason?: string;
|
|
69
|
+
/**
|
|
70
|
+
* decision==='ask' 时由权限层从 rich PermissionDecision(safety+policyName)派生的风险等级,
|
|
71
|
+
* 透传给 HITL UI 作显示提示。缺省时下游回退 'medium'。
|
|
72
|
+
*/
|
|
73
|
+
risk?: ApprovalRisk;
|
|
74
|
+
}
|
|
75
|
+
interface ToolExecuteAfterInput {
|
|
76
|
+
toolName: string;
|
|
77
|
+
toolCallId: string;
|
|
78
|
+
args: Record<string, unknown>;
|
|
79
|
+
result: ToolResult;
|
|
80
|
+
agentName: string;
|
|
81
|
+
sessionId: string;
|
|
82
|
+
durationMs: number;
|
|
83
|
+
/**
|
|
84
|
+
* 工具是否为只读(AgentTool.readonly),由执行器从工具声明派生。
|
|
85
|
+
* after-hook(comment-checker / edit-files-panel)据此识别「会改文件的工具」,
|
|
86
|
+
* 取代各自硬编码的 write/edit 工具名集合——工具身份单源自注册表声明。
|
|
87
|
+
*/
|
|
88
|
+
readonly?: boolean;
|
|
89
|
+
}
|
|
90
|
+
interface ToolExecuteAfterOutput {
|
|
91
|
+
result: ToolResult;
|
|
92
|
+
metadata: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
interface MessagesTransformInput {
|
|
95
|
+
messages: AgentMessage[];
|
|
96
|
+
tools: AgentTool[];
|
|
97
|
+
agentName: string;
|
|
98
|
+
sessionId: string;
|
|
99
|
+
}
|
|
100
|
+
interface MessagesTransformOutput {
|
|
101
|
+
messages: AgentMessage[];
|
|
102
|
+
}
|
|
103
|
+
interface ChatParamsInput {
|
|
104
|
+
sessionId?: string;
|
|
105
|
+
model: string;
|
|
106
|
+
provider: string;
|
|
107
|
+
temperature?: number;
|
|
108
|
+
maxTokens?: number;
|
|
109
|
+
thinkingLevel?: string;
|
|
110
|
+
}
|
|
111
|
+
interface ChatParamsOutput {
|
|
112
|
+
temperature?: number;
|
|
113
|
+
maxTokens?: number;
|
|
114
|
+
thinkingLevel?: string;
|
|
115
|
+
metadata: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
interface SystemPromptTransformInput {
|
|
118
|
+
systemPrompt: string;
|
|
119
|
+
sessionId: string;
|
|
120
|
+
tools: AgentTool[];
|
|
121
|
+
/** RFC-284 T3a:当前 prompt 的显式 user query,用于 volatile Relevant Hints。 */
|
|
122
|
+
userText?: string;
|
|
123
|
+
}
|
|
124
|
+
interface SystemPromptTransformOutput {
|
|
125
|
+
/** 会话内稳定的 system 前缀(进入 prompt cache)。稳定注入累加到这里。 */
|
|
126
|
+
systemPrompt: string;
|
|
127
|
+
/**
|
|
128
|
+
* 每轮可变(volatile)的 system 尾段:附在 stable 前缀的 cache 断点**之后**,
|
|
129
|
+
* 不破坏 prompt cache。逐轮变化的注入(如 phase context)写这里而非 systemPrompt。
|
|
130
|
+
*/
|
|
131
|
+
systemTail?: string[];
|
|
132
|
+
}
|
|
133
|
+
interface SessionEventInput {
|
|
134
|
+
sessionId: string;
|
|
135
|
+
metadata: Record<string, unknown>;
|
|
136
|
+
}
|
|
137
|
+
interface MemoryPruneBeforeInput {
|
|
138
|
+
sessionId: string;
|
|
139
|
+
/** 即将参与裁剪判定的上下文消息条数。 */
|
|
140
|
+
messageCount: number;
|
|
141
|
+
}
|
|
142
|
+
interface MemoryPruneBeforeOutput {
|
|
143
|
+
/** true → 否决本轮裁剪(引擎据此对 process 传 skipPrune)。 */
|
|
144
|
+
cancelled: boolean;
|
|
145
|
+
}
|
|
146
|
+
interface HookPayloadMap {
|
|
147
|
+
'chat.message.before': {
|
|
148
|
+
input: ChatMessageInput;
|
|
149
|
+
output: ChatMessageOutput;
|
|
150
|
+
};
|
|
151
|
+
'chat.message.after': {
|
|
152
|
+
input: ChatMessageInput;
|
|
153
|
+
output: ChatMessageOutput;
|
|
154
|
+
};
|
|
155
|
+
'tool.execute.before': {
|
|
156
|
+
input: ToolExecuteBeforeInput;
|
|
157
|
+
output: ToolExecuteBeforeOutput;
|
|
158
|
+
};
|
|
159
|
+
'tool.execute.after': {
|
|
160
|
+
input: ToolExecuteAfterInput;
|
|
161
|
+
output: ToolExecuteAfterOutput;
|
|
162
|
+
};
|
|
163
|
+
'messages.transform': {
|
|
164
|
+
input: MessagesTransformInput;
|
|
165
|
+
output: MessagesTransformOutput;
|
|
166
|
+
};
|
|
167
|
+
'chat.params': {
|
|
168
|
+
input: ChatParamsInput;
|
|
169
|
+
output: ChatParamsOutput;
|
|
170
|
+
};
|
|
171
|
+
'session.created': {
|
|
172
|
+
input: SessionEventInput;
|
|
173
|
+
output: void;
|
|
174
|
+
};
|
|
175
|
+
'session.restored': {
|
|
176
|
+
input: SessionEventInput;
|
|
177
|
+
output: void;
|
|
178
|
+
};
|
|
179
|
+
'session.deleted': {
|
|
180
|
+
input: SessionEventInput;
|
|
181
|
+
output: void;
|
|
182
|
+
};
|
|
183
|
+
'session.idle': {
|
|
184
|
+
input: SessionEventInput;
|
|
185
|
+
output: void;
|
|
186
|
+
};
|
|
187
|
+
'session.error': {
|
|
188
|
+
input: SessionEventInput & {
|
|
189
|
+
error: Error;
|
|
190
|
+
};
|
|
191
|
+
output: void;
|
|
192
|
+
};
|
|
193
|
+
'stream.start': {
|
|
194
|
+
input: {
|
|
195
|
+
sessionId: string;
|
|
196
|
+
model: string;
|
|
197
|
+
};
|
|
198
|
+
output: void;
|
|
199
|
+
};
|
|
200
|
+
'stream.end': {
|
|
201
|
+
input: {
|
|
202
|
+
sessionId: string;
|
|
203
|
+
model: string;
|
|
204
|
+
stopReason: string;
|
|
205
|
+
/**
|
|
206
|
+
* RFC-129 D6:本次 done 事件的 token 用量(可选——向后兼容,既有消费方不读取新字段则
|
|
207
|
+
* 行为不变)。来源 `event.message.usage`(即时数据),非会话级累积状态。
|
|
208
|
+
*/
|
|
209
|
+
tokenUsage?: {
|
|
210
|
+
input: number;
|
|
211
|
+
output: number;
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
output: void;
|
|
215
|
+
};
|
|
216
|
+
'compaction.before': {
|
|
217
|
+
input: {
|
|
218
|
+
sessionId: string;
|
|
219
|
+
messageCount: number;
|
|
220
|
+
};
|
|
221
|
+
output: void;
|
|
222
|
+
};
|
|
223
|
+
'compaction.after': {
|
|
224
|
+
input: {
|
|
225
|
+
sessionId: string;
|
|
226
|
+
retainedCount: number;
|
|
227
|
+
};
|
|
228
|
+
output: void;
|
|
229
|
+
};
|
|
230
|
+
'memory.prune.before': {
|
|
231
|
+
input: MemoryPruneBeforeInput;
|
|
232
|
+
output: MemoryPruneBeforeOutput;
|
|
233
|
+
};
|
|
234
|
+
'process.spawned': {
|
|
235
|
+
input: {
|
|
236
|
+
sessionId: string;
|
|
237
|
+
processId: string;
|
|
238
|
+
pid: number;
|
|
239
|
+
command: string;
|
|
240
|
+
port?: number;
|
|
241
|
+
};
|
|
242
|
+
output: void;
|
|
243
|
+
};
|
|
244
|
+
'process.exited': {
|
|
245
|
+
input: {
|
|
246
|
+
sessionId: string;
|
|
247
|
+
processId: string;
|
|
248
|
+
pid: number;
|
|
249
|
+
command: string;
|
|
250
|
+
status: string;
|
|
251
|
+
exitCode?: number;
|
|
252
|
+
};
|
|
253
|
+
output: void;
|
|
254
|
+
};
|
|
255
|
+
'task.created': {
|
|
256
|
+
input: {
|
|
257
|
+
task: TaskHookInfo;
|
|
258
|
+
};
|
|
259
|
+
output: void;
|
|
260
|
+
};
|
|
261
|
+
'task.started': {
|
|
262
|
+
input: {
|
|
263
|
+
task: TaskHookInfo;
|
|
264
|
+
agent: string;
|
|
265
|
+
};
|
|
266
|
+
output: void;
|
|
267
|
+
};
|
|
268
|
+
'task.completed': {
|
|
269
|
+
input: {
|
|
270
|
+
task: TaskHookInfo;
|
|
271
|
+
result: TaskHookOutput;
|
|
272
|
+
subagentResult?: TaskHookOutput;
|
|
273
|
+
};
|
|
274
|
+
output: void;
|
|
275
|
+
};
|
|
276
|
+
'task.failed': {
|
|
277
|
+
input: {
|
|
278
|
+
task: TaskHookInfo;
|
|
279
|
+
error: TaskHookError;
|
|
280
|
+
};
|
|
281
|
+
output: void;
|
|
282
|
+
};
|
|
283
|
+
'task.cancelled': {
|
|
284
|
+
input: {
|
|
285
|
+
taskId: string;
|
|
286
|
+
};
|
|
287
|
+
output: void;
|
|
288
|
+
};
|
|
289
|
+
'system.prompt.transform': {
|
|
290
|
+
input: SystemPromptTransformInput;
|
|
291
|
+
output: SystemPromptTransformOutput;
|
|
292
|
+
};
|
|
293
|
+
notification: {
|
|
294
|
+
input: NotificationHookInput;
|
|
295
|
+
output: void;
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* task.* hook 的 **hook-owned** payload 契约。
|
|
300
|
+
*
|
|
301
|
+
* Task/TaskResult/TaskError 定义在 orchestrator 领域包(依赖 hook-contracts),反向 import 成环;
|
|
302
|
+
* 故 hook 层拥有自己暴露的 payload 形状(生产者 orchestrator 的 Task 是其结构超集,emit 时直接赋值,
|
|
303
|
+
* spread 的额外字段经 TS 豁免)。取代原 `Record<string, unknown>` + orchestrator 侧 `as unknown as` 下降。
|
|
304
|
+
*/
|
|
305
|
+
interface TaskHookError {
|
|
306
|
+
code: string;
|
|
307
|
+
message: string;
|
|
308
|
+
retriable: boolean;
|
|
309
|
+
}
|
|
310
|
+
interface TaskHookOutput {
|
|
311
|
+
text: string;
|
|
312
|
+
summary?: string;
|
|
313
|
+
tokenUsage?: {
|
|
314
|
+
input: number;
|
|
315
|
+
output: number;
|
|
316
|
+
cacheRead: number;
|
|
317
|
+
};
|
|
318
|
+
durationMs?: number;
|
|
319
|
+
}
|
|
320
|
+
interface TaskHookInfo {
|
|
321
|
+
id: string;
|
|
322
|
+
parentId?: string;
|
|
323
|
+
status: string;
|
|
324
|
+
sessionId?: string;
|
|
325
|
+
attempts: number;
|
|
326
|
+
maxAttempts: number;
|
|
327
|
+
createdAt: number;
|
|
328
|
+
completedAt?: number;
|
|
329
|
+
output?: TaskHookOutput;
|
|
330
|
+
error?: TaskHookError;
|
|
331
|
+
/**
|
|
332
|
+
* Swarm 编排事件上下文(RFC-107 D1 / M-N6)。
|
|
333
|
+
* 当 task 属于 swarm 编排时由 Swarm.emitEvent 经 hookRegistry 桥接注入;
|
|
334
|
+
* 下游 hook 据此区分普通 task 与 swarm 成员 turn,并消费路由/编组元数据。
|
|
335
|
+
*/
|
|
336
|
+
swarmEvent?: SwarmEventPayload;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Swarm 编排事件载荷(hook-contracts 拥有最小形状;实际数据由 orchestrator/swarm 填充)。
|
|
340
|
+
* 不新建 swarm.* HookTiming 家族——经既有 task.*(如 task.started)携带。
|
|
341
|
+
*/
|
|
342
|
+
interface SwarmEventPayload {
|
|
343
|
+
/** 事件类型:swarm.start | swarm.end | agent.start | agent.end | handoff |
|
|
344
|
+
* routing.decision | parallel.fanOut | parallel.fanIn | pipeline.step |
|
|
345
|
+
* hierarchy.delegate | error */
|
|
346
|
+
type: string;
|
|
347
|
+
/** 事件附加元数据(按 type 不同携带 agentId/durationMs/decision 等字段)。 */
|
|
348
|
+
[key: string]: unknown;
|
|
349
|
+
}
|
|
350
|
+
/** 通知 hook 出站 payload(producer=HookChannel;consumer=.claude 桥/用户 hook)。 */
|
|
351
|
+
interface NotificationHookInput {
|
|
352
|
+
sessionId: string;
|
|
353
|
+
message: string;
|
|
354
|
+
title?: string;
|
|
355
|
+
/** 归一类别:turn_complete / error / approval_required / input_required(matcher 据此过滤)。 */
|
|
356
|
+
notification_type: string;
|
|
357
|
+
}
|
|
358
|
+
type HookInput<T extends HookTiming> = HookPayloadMap[T]['input'];
|
|
359
|
+
type HookOutput<T extends HookTiming> = HookPayloadMap[T]['output'];
|
|
360
|
+
type ObserverTiming = { [K in HookTiming]: HookPayloadMap[K]['output'] extends void ? K : never }[HookTiming];
|
|
361
|
+
type InterceptorTiming = { [K in HookTiming]: HookPayloadMap[K]['output'] extends void ? never : K }[HookTiming];
|
|
362
|
+
type HookHandle<T extends HookTiming> = T extends ObserverTiming ? (input: HookInput<T>) => void | Promise<void> : (input: HookInput<T>, output: HookOutput<T>) => void | Promise<void>;
|
|
363
|
+
//#endregion
|
|
364
|
+
//#region src/permission-config.d.ts
|
|
365
|
+
/**
|
|
366
|
+
* 权限**配置形状**单一真源(RFC-077 mirror-debt 收口,HK-1)。
|
|
367
|
+
*
|
|
368
|
+
* 背景:权限配置形状(mode 词表 + policy/rule 的 config 结构)历史上双份定义——
|
|
369
|
+
* `@x-otto/setting` 的 zod schema(z.infer)与 `@x-otto/hooks` 引擎的手写 interface。二者层序不可互依
|
|
370
|
+
* (hooks L2 < setting L3,hooks 不能上依赖 setting),故各写一套、无 drift guard。
|
|
371
|
+
*
|
|
372
|
+
* 收口:把配置形状沉到二者都能**下依赖**的零依赖叶 `@x-otto/hook-contracts`(L1):
|
|
373
|
+
* - `@x-otto/hooks` 引擎 import 这些类型(删手写镜像)。
|
|
374
|
+
* - `@x-otto/setting` 的 zod schema `satisfies z.ZodType<…>` 钉死到此(drift→编译报错),并 re-export。
|
|
375
|
+
*
|
|
376
|
+
* 这里只放**配置/wire 形状**(作者在 config.json 写的东西);运行时引擎类型
|
|
377
|
+
* (PermissionPolicy/PermissionContext/PermissionDecision/PolicyScope 等,含 RegExp/函数/时间戳)
|
|
378
|
+
* 仍属引擎、留 `@x-otto/hooks`。
|
|
379
|
+
*/
|
|
380
|
+
/** 权限模式词表(config.json `permission_mode` + 运行时模式)。 */
|
|
381
|
+
declare const PERMISSION_MODES: readonly ["bypass", "auto", "confirm", "strict", "readonly"];
|
|
382
|
+
type PermissionMode = (typeof PERMISSION_MODES)[number];
|
|
383
|
+
/** 规则效果。 */
|
|
384
|
+
type RuleEffect = 'allow' | 'deny' | 'ask';
|
|
385
|
+
/** 单条权限规则的**配置**形状(config.json)。运行时 `PermissionRule`(含编译后 RegExp)属引擎。 */
|
|
386
|
+
interface PermissionRuleConfig {
|
|
387
|
+
name: string;
|
|
388
|
+
effect: RuleEffect;
|
|
389
|
+
tools?: string[];
|
|
390
|
+
paths?: string[];
|
|
391
|
+
deny_reason?: string;
|
|
392
|
+
ask_prompt?: string;
|
|
393
|
+
}
|
|
394
|
+
/** 单个权限策略的**配置**形状(config.json)。运行时 `PermissionPolicy`(含 safety/priority 语义)属引擎。 */
|
|
395
|
+
interface PermissionPolicySetting {
|
|
396
|
+
name: string;
|
|
397
|
+
priority?: number;
|
|
398
|
+
enabled?: boolean;
|
|
399
|
+
scope?: {
|
|
400
|
+
agents?: string[];
|
|
401
|
+
sessions?: string[];
|
|
402
|
+
};
|
|
403
|
+
rules: PermissionRuleConfig[];
|
|
404
|
+
}
|
|
405
|
+
//#endregion
|
|
406
|
+
export { type AgentMessage, type AgentSessionEvent, type AgentSessionEventMap, type AgentSessionEventType, type AgentSessionSubscriber, type AgentTool, type ApprovalRisk, type AskUserQuestion, type ChatMessageInput, type ChatMessageOutput, type ChatParamsInput, type ChatParamsOutput, type CustomAgentMessages, type GrillAnswer, type GrillOption, type GrillQuestion, type GrillRequest, type HookHandle, type HookInput, type HookOutput, type HookPayloadMap, type HookTiming, type InterceptorTiming, type MessagesTransformInput, type MessagesTransformOutput, type NotificationHookInput, type ObserverTiming, PERMISSION_MODES, type PermissionDecision, type PermissionMode, type PermissionPolicySetting, type PermissionRuleConfig, type RuleEffect, type SessionEventInput, type SwarmEventPayload, type SystemAgentMessage, type SystemMessageLevel, type SystemPromptTransformInput, type SystemPromptTransformOutput, type TaskHookError, type TaskHookInfo, type TaskHookOutput, type ToolCallContext, type ToolCallEvent, type ToolErrorKind, type ToolExecuteAfterInput, type ToolExecuteAfterOutput, type ToolExecuteBeforeInput, type ToolExecuteBeforeOutput, type ToolResult };
|
|
407
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/messages.ts","../src/timings.ts","../src/permission-config.ts"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/permission-config.ts"],"sourcesContent":["/**\n * 权限**配置形状**单一真源(RFC-077 mirror-debt 收口,HK-1)。\n *\n * 背景:权限配置形状(mode 词表 + policy/rule 的 config 结构)历史上双份定义——\n * `@x-otto/setting` 的 zod schema(z.infer)与 `@x-otto/hooks` 引擎的手写 interface。二者层序不可互依\n * (hooks L2 < setting L3,hooks 不能上依赖 setting),故各写一套、无 drift guard。\n *\n * 收口:把配置形状沉到二者都能**下依赖**的零依赖叶 `@x-otto/hook-contracts`(L1):\n * - `@x-otto/hooks` 引擎 import 这些类型(删手写镜像)。\n * - `@x-otto/setting` 的 zod schema `satisfies z.ZodType<…>` 钉死到此(drift→编译报错),并 re-export。\n *\n * 这里只放**配置/wire 形状**(作者在 config.json 写的东西);运行时引擎类型\n * (PermissionPolicy/PermissionContext/PermissionDecision/PolicyScope 等,含 RegExp/函数/时间戳)\n * 仍属引擎、留 `@x-otto/hooks`。\n */\n\n/** 权限模式词表(config.json `permission_mode` + 运行时模式)。 */\nexport const PERMISSION_MODES = ['bypass', 'auto', 'confirm', 'strict', 'readonly'] as const\nexport type PermissionMode = (typeof PERMISSION_MODES)[number]\n\n/** 规则效果。 */\nexport type RuleEffect = 'allow' | 'deny' | 'ask'\n\n/** 单条权限规则的**配置**形状(config.json)。运行时 `PermissionRule`(含编译后 RegExp)属引擎。 */\nexport interface PermissionRuleConfig {\n name: string\n effect: RuleEffect\n tools?: string[]\n paths?: string[]\n deny_reason?: string\n ask_prompt?: string\n}\n\n/** 单个权限策略的**配置**形状(config.json)。运行时 `PermissionPolicy`(含 safety/priority 语义)属引擎。 */\nexport interface PermissionPolicySetting {\n name: string\n priority?: number\n enabled?: boolean\n scope?: {\n agents?: string[]\n sessions?: string[]\n }\n rules: PermissionRuleConfig[]\n}\n"],"mappings":"AAiBA,MAAa,EAAmB,CAAC,SAAU,OAAQ,UAAW,SAAU,WAAW"}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@x-otto/hook-contracts",
|
|
3
|
+
"version": "0.0.1-alpha.0",
|
|
4
|
+
"files": [
|
|
5
|
+
"dist"
|
|
6
|
+
],
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org",
|
|
19
|
+
"tag": "alpha"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@x-otto/interchange": "0.1.0-alpha.1"
|
|
23
|
+
},
|
|
24
|
+
"private": false,
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsdown",
|
|
27
|
+
"typecheck:project": "tsc -p tsconfig.json --noEmit",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"clean": "rm -rf dist"
|
|
30
|
+
}
|
|
31
|
+
}
|