@s_s/agent-kit 1.0.0 → 1.1.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 CHANGED
@@ -6,7 +6,7 @@ MCP Server / Skill 开发基础设施库。提供 agent 检测、prompt 注入
6
6
 
7
7
  - **Agent 检测** — 通过文件系统特征或 MCP clientInfo 自动识别 agent 类型(OpenCode、Claude Code、OpenClaw、Codex)
8
8
  - **Prompt 注入** — 向 agent 配置文件(`AGENTS.md`、`CLAUDE.md`、manifests 等)注入自定义指令,支持幂等更新
9
- - **Intent-based Hook 系统**按意图声明,自动翻译为各 agent 原生格式,支持三层优先级和显式降级
9
+ - **Hook 安装**用户提供完整 hook 内容,agent-kit 负责写入正确路径、管理 settings.json 和生命周期
10
10
  - **跨平台数据目录** — 自动适配 macOS / Linux / Windows,支持 global / project 两种作用域
11
11
  - **零运行时依赖** — 纯 TypeScript,零 dependencies
12
12
  - **工厂模式** — `createKit(name)` 返回绑定了工具名的函数集,支持解构,无全局状态
@@ -20,42 +20,52 @@ npm install @s_s/agent-kit
20
20
  ## 快速开始
21
21
 
22
22
  ```typescript
23
- import { createKit, hooks, detectAgent } from '@s_s/agent-kit';
23
+ import { createKit, defineHooks, detectAgent } from '@s_s/agent-kit';
24
24
 
25
- // 1. 创建 kit 实例(支持解构)
25
+ // 1. 创建 kit 实例
26
26
  const { injectPrompt, installHooks, getDataDir } = createKit('my-mcp');
27
27
 
28
- // 2. 声明 hook 意图(全局 API,不绑定实例)
29
- hooks.inject({
30
- perTurn: 'Remember to use my-mcp tools when relevant.',
31
- sessionStart: 'Welcome! Check my-mcp for context.',
32
- compaction: 'Preserve my-mcp context during compaction.',
33
- });
34
-
35
- hooks.beforeToolCall({
36
- match: /^Bash/,
37
- handler: (ctx) => {
38
- if (ctx.args.command?.includes('rm -rf')) {
39
- return { block: true, reason: 'Dangerous command blocked' };
40
- }
28
+ // 2. 声明 hook(每个 agent 独立声明,内容由用户完全控制)
29
+ // hooks/claude-code.ts
30
+ const claudeHooks = defineHooks('claude-code', [
31
+ {
32
+ events: ['UserPromptSubmit'],
33
+ content: '#!/bin/bash\necho "<reminder>Use my-mcp tools.</reminder>"',
34
+ },
35
+ {
36
+ events: ['PreToolUse'],
37
+ content:
38
+ '#!/bin/bash\n# 拦截危险操作\nTOOL_NAME="$HOOK_TOOL_NAME"\nif [[ "$TOOL_NAME" == "Bash" ]]; then echo "checked"; fi',
41
39
  },
40
+ ]);
41
+
42
+ // hooks/opencode.ts
43
+ const opencodeHooks = defineHooks('opencode', {
44
+ events: ['experimental.chat.messages.transform'],
45
+ content: `export default {
46
+ name: 'my-mcp',
47
+ hooks: {
48
+ 'experimental.chat.messages.transform': async (messages) => {
49
+ messages.push({ role: 'user', content: '<reminder>Use my-mcp tools.</reminder>' });
50
+ return messages;
51
+ },
52
+ },
53
+ };`,
42
54
  });
43
55
 
44
56
  // 3. 检测当前 agent
45
57
  const agent = await detectAgent();
46
58
  if (!agent) throw new Error('No supported agent detected');
47
59
 
48
- // 4. 注入 prompt 到 agent 配置文件
60
+ // 4. 注入 prompt
49
61
  await injectPrompt(agent, '## My MCP\nInstructions for the agent...');
50
62
 
51
- // 5. 安装 hooks(自动翻译为 agent 原生格式)
52
- const result = await installHooks(agent);
63
+ // 5. 安装 hooks
64
+ const result = await installHooks(agent, [claudeHooks, opencodeHooks]);
53
65
  console.log(`Hooks installed: ${result.filesWritten.join(', ')}`);
54
- console.log(`Warnings: ${result.warnings.join('\n')}`);
55
66
 
56
67
  // 6. 获取数据目录路径
57
68
  const dataDir = getDataDir(); // global scope
58
- const projectDir = getDataDir({ scope: 'project', projectRoot: '/path/to/project' });
59
69
  ```
60
70
 
61
71
  ## API
@@ -83,23 +93,14 @@ createKit(name: string, options?: KitOptions): Kit
83
93
 
84
94
  返回的 Kit 对象包含以下方法:
85
95
 
86
- | 方法 | 说明 |
87
- | --------------------------------------- | ----------------------------- |
88
- | `injectPrompt(agent, prompt, options?)` | 注入 prompt 到 agent 配置文件 |
89
- | `hasPromptInjected(agent, options?)` | 检查 prompt 是否已注入 |
90
- | `installHooks(agent)` | 安装 hooks |
91
- | `uninstallHooks(agent)` | 卸载 hooks |
92
- | `hasHooksInstalled(agent)` | 检查 hooks 是否已安装 |
93
- | `getDataDir(options?)` | 获取跨平台数据目录路径 |
94
-
95
- ### Hook 系统
96
-
97
- Hook 系统分为两个阶段:**声明**和**安装**。
98
-
99
- 1. **声明**:通过全局 `hooks.*` API 声明意图(`inject` / `beforeToolCall` / `afterToolCall` / `onSession` / `onPermission`),以及 `raw` / `extend` 两种高级注册方式
100
- 2. **安装**:调用 `kit.installHooks(agent)` 时,从全局注册中心读取所有声明,翻译为目标 agent 的原生格式并写入磁盘
101
-
102
- 详细的 API 说明、示例、三层优先级机制和降级行为,请参阅 **[Hook 使用指南](docs/hook-usage.md)**。各 agent 原生 hook 能力的完整横向对比,请参阅 **[Hook 横向对比](docs/hooks-comparison.md)**。
96
+ | 方法 | 说明 |
97
+ | --------------------------------------- | ----------------------------------- |
98
+ | `injectPrompt(agent, prompt, options?)` | 注入 prompt 到 agent 配置文件 |
99
+ | `hasPromptInjected(agent, options?)` | 检查 prompt 是否已注入 |
100
+ | `installHooks(agent, hooks)` | 安装 hooks(传入 defineHooks 声明) |
101
+ | `uninstallHooks(agent)` | 卸载 hooks |
102
+ | `hasHooksInstalled(agent)` | 检查 hooks 是否已安装 |
103
+ | `getDataDir(options?)` | 获取跨平台数据目录路径 |
103
104
 
104
105
  ### Kit 方法详情
105
106
 
@@ -115,15 +116,20 @@ injectPrompt(agent: AgentType, prompt: string, options?: ScopeOptions): Promise<
115
116
  - 后续调用:替换已有标记块(幂等更新)
116
117
  - 自动创建目录和文件
117
118
 
118
- #### `kit.installHooks(agent)`
119
+ #### `kit.installHooks(agent, hooks)`
119
120
 
120
- 为指定 agent 安装 hooks。从 hook 注册中心读取所有声明,翻译为原生格式,写入文件。
121
+ 为指定 agent 安装 hooks。接受一个或多个 `HookSet`(由 `defineHooks()` 返回),将内容写入 agent 的 hook 目录。
121
122
 
122
123
  ```typescript
123
- installHooks(agent: AgentType): Promise<HookInstallResult>
124
+ installHooks(agent: AgentType, hooks: HookSet | HookSet[]): Promise<HookInstallResult>
124
125
  ```
125
126
 
126
- 返回值包含完整的降级信息:
127
+ - 自动过滤:只处理与 `agent` 匹配的 `HookSet`,其余忽略
128
+ - Claude Code / Codex:写入 shell 脚本 + 自动注册到 `settings.json`
129
+ - OpenCode:写入 TypeScript 插件文件到 plugins 目录
130
+ - OpenClaw:生成 `HOOK.md`(YAML frontmatter)+ `handler.ts`
131
+
132
+ 返回值:
127
133
 
128
134
  ```typescript
129
135
  interface HookInstallResult {
@@ -132,20 +138,11 @@ interface HookInstallResult {
132
138
  filesWritten: string[];
133
139
  settingsUpdated: boolean;
134
140
  notes: string[];
135
- warnings: string[]; // 降级/冲突警告
136
- skipped: SkippedIntent[]; // 被跳过的意图
141
+ warnings: string[];
137
142
  error?: string;
138
143
  }
139
144
  ```
140
145
 
141
- 各 agent 的翻译方式:
142
-
143
- | Agent | 生成内容 |
144
- | ------------------- | ------------------------------------------------------- |
145
- | claude-code / codex | Shell 脚本(多个原生 hook),自动注册到 `settings.json` |
146
- | openclaw | `HOOK.md` + `handler.ts`(内部 hook + 插件 hook) |
147
- | opencode | 单个 TypeScript 插件文件(多个 hook 合并) |
148
-
149
146
  #### `kit.uninstallHooks(agent)`
150
147
 
151
148
  清理已安装的 hook 文件和 settings.json 条目。
@@ -169,6 +166,49 @@ getDataDir(options?: ScopeOptions): string
169
166
 
170
167
  全局路径可通过环境变量覆盖(默认变量名:`{NAME}_DATA_DIR`)。
171
168
 
169
+ ### Hook 系统
170
+
171
+ Hook 系统分为两个阶段:**声明**和**安装**。
172
+
173
+ 1. **声明**:通过 `defineHooks(agent, definitions)` 纯函数声明 hook 内容。每个 agent 独立声明,内容由用户完全控制。支持分文件组织。
174
+ 2. **安装**:调用 `kit.installHooks(agent, hooks)` 时,将声明内容写入目标 agent 的 hook 目录。
175
+
176
+ #### `defineHooks(agent, definitions)`
177
+
178
+ 纯函数,不依赖任何实例或全局状态。做运行时校验(事件名合法性、content 非空),返回类型安全的 `HookSet` 数据对象。
179
+
180
+ ```typescript
181
+ import { defineHooks } from '@s_s/agent-kit';
182
+
183
+ // 单条声明
184
+ const hooks = defineHooks('claude-code', {
185
+ events: ['PreToolUse', 'PostToolUse'], // 多事件共享同一内容
186
+ content: '#!/bin/bash\necho "hook fired"',
187
+ });
188
+
189
+ // 多条声明
190
+ const hooks = defineHooks('claude-code', [
191
+ { events: ['PreToolUse'], content: '#!/bin/bash\necho "pre"' },
192
+ { events: ['PostToolUse'], content: '#!/bin/bash\necho "post"' },
193
+ ]);
194
+
195
+ // OpenClaw — 支持 description 参数
196
+ const hooks = defineHooks('openclaw', {
197
+ events: ['session_start', 'before_tool_call'],
198
+ content: 'export default async function(event) { return event; }',
199
+ description: '注入项目规范到每轮对话',
200
+ });
201
+ ```
202
+
203
+ **设计原则**:agent-kit 是"安装器"而非"翻译器"。用户提供各 agent 的原生 hook 内容,agent-kit 只负责:
204
+
205
+ - 知道正确的文件路径
206
+ - 写入文件
207
+ - 管理 settings.json 合并(Claude Code / Codex)
208
+ - 安装 / 卸载生命周期
209
+
210
+ 详细的使用示例和各 agent 事件名列表,请参阅 **[Hook 使用指南](docs/hook-usage.md)**。各 agent 原生 hook 能力的完整横向对比,请参阅 **[Hook 横向对比](docs/hooks-comparison.md)**。
211
+
172
212
  ### 独立函数
173
213
 
174
214
  以下函数不依赖 kit 实例,可直接使用。
@@ -208,23 +248,6 @@ detectProjectRoot(cwd?: string): Promise<string>
208
248
 
209
249
  优先使用 `git rev-parse --show-toplevel`,失败则向上遍历查找标记文件(`.git`、`package.json`、`pyproject.toml`、`Cargo.toml`、`go.mod`),都未找到则回退到 `cwd`。
210
250
 
211
- ### 能力矩阵 API
212
-
213
- 编程式查询各 agent 对各 intent 的支持程度。
214
-
215
- ```typescript
216
- import { CAPABILITY_MATRIX, checkDegradation, isIntentFullyUnsupported } from '@s_s/agent-kit';
217
-
218
- // 查询特定能力
219
- CAPABILITY_MATRIX.opencode.beforeToolCall.block.level; // 'partial'
220
-
221
- // 检查某 intent 在某 agent 上的降级情况
222
- const warnings = checkDegradation('opencode', 'beforeToolCall');
223
-
224
- // 检查是否完全不支持
225
- isIntentFullyUnsupported('openclaw', 'onPermission'); // true
226
- ```
227
-
228
251
  ## 类型
229
252
 
230
253
  ```typescript
@@ -246,12 +269,25 @@ interface Kit {
246
269
  readonly name: string;
247
270
  injectPrompt(agent: AgentType, prompt: string, options?: ScopeOptions): Promise<void>;
248
271
  hasPromptInjected(agent: AgentType, options?: ScopeOptions): Promise<boolean>;
249
- installHooks(agent: AgentType): Promise<HookInstallResult>;
272
+ installHooks(agent: AgentType, hooks: HookSet | HookSet[]): Promise<HookInstallResult>;
250
273
  uninstallHooks(agent: AgentType): Promise<{ success: boolean; removed: string[]; error?: string }>;
251
274
  hasHooksInstalled(agent: AgentType): Promise<boolean>;
252
275
  getDataDir(options?: ScopeOptions): string;
253
276
  }
254
277
 
278
+ // Hook 定义
279
+ interface HookDefinition<A extends AgentType = AgentType> {
280
+ events: string[]; // agent 原生事件名
281
+ content: string; // hook 内容(shell 脚本、TypeScript 代码等)
282
+ description?: string; // OpenClaw 专属 — HOOK.md 描述
283
+ }
284
+
285
+ // defineHooks() 返回的数据对象
286
+ interface HookSet<A extends AgentType = AgentType> {
287
+ readonly agent: A;
288
+ readonly definitions: readonly HookDefinition<A>[];
289
+ }
290
+
255
291
  interface HookInstallResult {
256
292
  success: boolean;
257
293
  hookDir: string;
@@ -259,17 +295,8 @@ interface HookInstallResult {
259
295
  settingsUpdated: boolean;
260
296
  notes: string[];
261
297
  warnings: string[];
262
- skipped: SkippedIntent[];
263
298
  error?: string;
264
299
  }
265
-
266
- interface SkippedIntent {
267
- intent: string;
268
- agent: string;
269
- reason: string;
270
- }
271
-
272
- type SupportLevel = 'supported' | 'partial' | 'unsupported';
273
300
  ```
274
301
 
275
302
  ## 支持的 Agent
@@ -37,8 +37,8 @@ export function createKit(name, options) {
37
37
  hasPromptInjected(agent, scopeOptions) {
38
38
  return hasPromptInjected(name, agent, scopeOptions);
39
39
  },
40
- installHooks(agent) {
41
- return installHooks(name, agent);
40
+ installHooks(agent, hooks) {
41
+ return installHooks(name, agent, hooks);
42
42
  },
43
43
  uninstallHooks(agent) {
44
44
  return uninstallHooks(name, agent);
@@ -1 +1 @@
1
- {"version":3,"file":"create-kit.js","sourceRoot":"","sources":["../src/create-kit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAAoB;IACxD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAsB;QAC9B,IAAI;QACJ,IAAI,EAAE,OAAO,EAAE,IAAI;QACnB,WAAW,EAAE,OAAO,EAAE,WAAW;KACpC,CAAC;IAEF,OAAO;QACH,IAAI,IAAI;YACJ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,YAAY,CAAC,KAAgB,EAAE,MAAc,EAAE,YAA2B;YACtE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC7E,CAAC;YACD,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC3D,CAAC;QAED,iBAAiB,CAAC,KAAgB,EAAE,YAA2B;YAC3D,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QACxD,CAAC;QAED,YAAY,CAAC,KAAgB;YACzB,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QAED,cAAc,CAAC,KAAgB;YAC3B,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAED,iBAAiB,CAAC,KAAgB;YAC9B,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QAED,UAAU,CAAC,YAA2B;YAClC,OAAO,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5C,CAAC;KACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"create-kit.js","sourceRoot":"","sources":["../src/create-kit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAAoB;IACxD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAsB;QAC9B,IAAI;QACJ,IAAI,EAAE,OAAO,EAAE,IAAI;QACnB,WAAW,EAAE,OAAO,EAAE,WAAW;KACpC,CAAC;IAEF,OAAO;QACH,IAAI,IAAI;YACJ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,YAAY,CAAC,KAAgB,EAAE,MAAc,EAAE,YAA2B;YACtE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC7E,CAAC;YACD,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QAC3D,CAAC;QAED,iBAAiB,CAAC,KAAgB,EAAE,YAA2B;YAC3D,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QACxD,CAAC;QAED,YAAY,CAAC,KAAgB,EAAE,KAA0B;YACrD,OAAO,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,cAAc,CAAC,KAAgB;YAC3B,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAED,iBAAiB,CAAC,KAAgB;YAC9B,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QAED,UAAU,CAAC,YAA2B;YAClC,OAAO,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAC5C,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { AgentType, HookDefinition, HookSet } from './types.js';
2
+ /**
3
+ * Define hooks for a specific agent. Returns a validated HookSet that can be
4
+ * passed to `kit.installHooks()`.
5
+ *
6
+ * Pure function — no side effects, no global state, no instance dependency.
7
+ *
8
+ * @param agent - Target agent type.
9
+ * @param definitions - A single HookDefinition or an array of HookDefinitions.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // Single definition
14
+ * const hooks = defineHooks('claude-code', {
15
+ * events: ['PreToolUse', 'PostToolUse'],
16
+ * content: '#!/bin/bash\necho "hook fired"',
17
+ * });
18
+ *
19
+ * // Multiple definitions
20
+ * const hooks = defineHooks('claude-code', [
21
+ * { events: ['PreToolUse'], content: '#!/bin/bash\necho "pre"' },
22
+ * { events: ['PostToolUse'], content: '#!/bin/bash\necho "post"' },
23
+ * ]);
24
+ * ```
25
+ */
26
+ export declare function defineHooks<A extends AgentType>(agent: A, definitions: HookDefinition<A> | HookDefinition<A>[]): HookSet<A>;
27
+ /**
28
+ * Get the set of valid event names for a given agent.
29
+ * Useful for tooling and documentation generation.
30
+ */
31
+ export declare function getValidEvents(agent: AgentType): ReadonlySet<string>;
@@ -0,0 +1,192 @@
1
+ import { AGENT_TYPES } from './types.js';
2
+ // ---------------------------------------------------------------------------
3
+ // Valid event names per agent (for runtime validation)
4
+ // ---------------------------------------------------------------------------
5
+ const VALID_EVENTS = {
6
+ 'claude-code': new Set([
7
+ 'SessionStart',
8
+ 'InstructionsLoaded',
9
+ 'UserPromptSubmit',
10
+ 'PreToolUse',
11
+ 'PermissionRequest',
12
+ 'PostToolUse',
13
+ 'PostToolUseFailure',
14
+ 'Notification',
15
+ 'SubagentStart',
16
+ 'SubagentStop',
17
+ 'Stop',
18
+ 'TeammateIdle',
19
+ 'TaskCompleted',
20
+ 'ConfigChange',
21
+ 'WorktreeCreate',
22
+ 'WorktreeRemove',
23
+ 'PreCompact',
24
+ 'PostCompact',
25
+ 'Elicitation',
26
+ 'ElicitationResult',
27
+ 'SessionEnd',
28
+ ]),
29
+ codex: new Set([
30
+ 'SessionStart',
31
+ 'InstructionsLoaded',
32
+ 'UserPromptSubmit',
33
+ 'PreToolUse',
34
+ 'PermissionRequest',
35
+ 'PostToolUse',
36
+ 'PostToolUseFailure',
37
+ 'Notification',
38
+ 'SubagentStart',
39
+ 'SubagentStop',
40
+ 'Stop',
41
+ 'TeammateIdle',
42
+ 'TaskCompleted',
43
+ 'ConfigChange',
44
+ 'WorktreeCreate',
45
+ 'WorktreeRemove',
46
+ 'PreCompact',
47
+ 'PostCompact',
48
+ 'Elicitation',
49
+ 'ElicitationResult',
50
+ 'SessionEnd',
51
+ ]),
52
+ opencode: new Set([
53
+ 'event',
54
+ 'config',
55
+ 'tool',
56
+ 'auth',
57
+ 'chat.message',
58
+ 'chat.params',
59
+ 'chat.headers',
60
+ 'permission.ask',
61
+ 'command.execute.before',
62
+ 'tool.execute.before',
63
+ 'shell.env',
64
+ 'tool.execute.after',
65
+ 'experimental.chat.messages.transform',
66
+ 'experimental.chat.system.transform',
67
+ 'experimental.session.compacting',
68
+ 'experimental.text.complete',
69
+ 'tool.definition',
70
+ ]),
71
+ openclaw: new Set([
72
+ // Plugin hooks
73
+ 'before_model_resolve',
74
+ 'before_prompt_build',
75
+ 'before_agent_start',
76
+ 'llm_input',
77
+ 'llm_output',
78
+ 'agent_end',
79
+ 'before_compaction',
80
+ 'after_compaction',
81
+ 'before_reset',
82
+ 'message_received',
83
+ 'message_sending',
84
+ 'message_sent',
85
+ 'before_tool_call',
86
+ 'after_tool_call',
87
+ 'tool_result_persist',
88
+ 'before_message_write',
89
+ 'session_start',
90
+ 'session_end',
91
+ 'subagent_spawning',
92
+ 'subagent_delivery_target',
93
+ 'subagent_spawned',
94
+ 'subagent_ended',
95
+ 'gateway_start',
96
+ 'gateway_stop',
97
+ // Internal hooks
98
+ 'command:new',
99
+ 'command:reset',
100
+ 'command:stop',
101
+ 'session:compact:before',
102
+ 'session:compact:after',
103
+ 'agent:bootstrap',
104
+ 'gateway:startup',
105
+ 'message:received',
106
+ 'message:sent',
107
+ 'message:transcribed',
108
+ 'message:preprocessed',
109
+ ]),
110
+ };
111
+ // ---------------------------------------------------------------------------
112
+ // defineHooks — pure validation + packaging function
113
+ // ---------------------------------------------------------------------------
114
+ /**
115
+ * Define hooks for a specific agent. Returns a validated HookSet that can be
116
+ * passed to `kit.installHooks()`.
117
+ *
118
+ * Pure function — no side effects, no global state, no instance dependency.
119
+ *
120
+ * @param agent - Target agent type.
121
+ * @param definitions - A single HookDefinition or an array of HookDefinitions.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * // Single definition
126
+ * const hooks = defineHooks('claude-code', {
127
+ * events: ['PreToolUse', 'PostToolUse'],
128
+ * content: '#!/bin/bash\necho "hook fired"',
129
+ * });
130
+ *
131
+ * // Multiple definitions
132
+ * const hooks = defineHooks('claude-code', [
133
+ * { events: ['PreToolUse'], content: '#!/bin/bash\necho "pre"' },
134
+ * { events: ['PostToolUse'], content: '#!/bin/bash\necho "post"' },
135
+ * ]);
136
+ * ```
137
+ */
138
+ export function defineHooks(agent, definitions) {
139
+ // Validate agent
140
+ if (!AGENT_TYPES.includes(agent)) {
141
+ throw new Error(`defineHooks: unknown agent type "${agent}". Valid types: ${AGENT_TYPES.join(', ')}`);
142
+ }
143
+ // Normalize to array
144
+ const defs = Array.isArray(definitions) ? definitions : [definitions];
145
+ if (defs.length === 0) {
146
+ throw new Error('defineHooks: definitions array cannot be empty.');
147
+ }
148
+ // OpenClaw: warn if multiple definitions provided (only first is used)
149
+ const warnings = [];
150
+ if (agent === 'openclaw' && defs.length > 1) {
151
+ warnings.push(`defineHooks: OpenClaw only supports a single hook definition. ` +
152
+ `Got ${defs.length} definitions — only the first will be used.`);
153
+ // Log warning (user can also see it in installHooks result)
154
+ console.warn(warnings[0]);
155
+ }
156
+ const validEvents = VALID_EVENTS[agent];
157
+ for (let i = 0; i < defs.length; i++) {
158
+ const def = defs[i];
159
+ // Validate events
160
+ if (!Array.isArray(def.events) || def.events.length === 0) {
161
+ throw new Error(`defineHooks: definitions[${i}].events must be a non-empty array.`);
162
+ }
163
+ for (const event of def.events) {
164
+ if (!validEvents.has(event)) {
165
+ throw new Error(`defineHooks: unknown event "${event}" for agent "${agent}". ` +
166
+ `Valid events: ${[...validEvents].join(', ')}`);
167
+ }
168
+ }
169
+ // Validate content
170
+ if (typeof def.content !== 'string' || !def.content.trim()) {
171
+ throw new Error(`defineHooks: definitions[${i}].content must be a non-empty string.`);
172
+ }
173
+ }
174
+ // For OpenClaw, only keep first definition
175
+ const effectiveDefs = agent === 'openclaw' && defs.length > 1 ? [defs[0]] : defs;
176
+ return {
177
+ __brand: 'HookSet',
178
+ agent,
179
+ definitions: Object.freeze([...effectiveDefs]),
180
+ };
181
+ }
182
+ /**
183
+ * Get the set of valid event names for a given agent.
184
+ * Useful for tooling and documentation generation.
185
+ */
186
+ export function getValidEvents(agent) {
187
+ if (!AGENT_TYPES.includes(agent)) {
188
+ throw new Error(`getValidEvents: unknown agent type "${agent}".`);
189
+ }
190
+ return VALID_EVENTS[agent];
191
+ }
192
+ //# sourceMappingURL=define-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-hooks.js","sourceRoot":"","sources":["../src/define-hooks.ts"],"names":[],"mappings":"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"}
package/build/hooks.d.ts CHANGED
@@ -1,14 +1,17 @@
1
- import type { AgentType, HookInstallResult } from './types.js';
1
+ import type { AgentType, HookInstallResult, HookSet } from './types.js';
2
2
  /**
3
3
  * Install hooks for the given agent type.
4
4
  *
5
- * Reads all registered intents, raw hooks, and extend hooks from the hook
6
- * registry. Translates them into native hook files using the agent-specific
7
- * translator. Runs degradation checks and conflict detection.
5
+ * Accepts one or more HookSet (from defineHooks()). Filters to only those
6
+ * matching the target agent. Writes content to the agent's hook directory.
7
+ *
8
+ * For Claude Code / Codex: writes shell scripts, merges into settings.json.
9
+ * For OpenCode: writes TypeScript plugin files directly to plugins dir.
10
+ * For OpenClaw: writes HOOK.md + handler.ts, attempts CLI activation.
8
11
  *
9
12
  * @internal — called by the Kit object returned from createKit().
10
13
  */
11
- export declare function installHooks(name: string, agent: AgentType): Promise<HookInstallResult>;
14
+ export declare function installHooks(name: string, agent: AgentType, hookSets: HookSet | HookSet[]): Promise<HookInstallResult>;
12
15
  /**
13
16
  * Uninstall hooks for the given agent type.
14
17
  *
package/build/hooks.js CHANGED
@@ -4,40 +4,23 @@ import os from 'node:os';
4
4
  import { execFile } from 'node:child_process';
5
5
  import { promisify } from 'node:util';
6
6
  import { AGENT_REGISTRY } from './types.js';
7
- import { getIntents, getRawHooks, getExtendHooks } from './hook-registry.js';
8
- import { checkAllDegradation } from './hook-capabilities.js';
9
- import { ClaudeCodeTranslator } from './hook-translators/claude-code.js';
10
- import { OpenCodeTranslator } from './hook-translators/opencode.js';
11
- import { OpenClawTranslator } from './hook-translators/openclaw.js';
12
7
  const execFileAsync = promisify(execFile);
13
8
  // ---------------------------------------------------------------------------
14
- // Translator factory
15
- // ---------------------------------------------------------------------------
16
- function getTranslator(agent) {
17
- switch (agent) {
18
- case 'claude-code':
19
- return new ClaudeCodeTranslator('claude-code');
20
- case 'codex':
21
- return new ClaudeCodeTranslator('codex');
22
- case 'opencode':
23
- return new OpenCodeTranslator();
24
- case 'openclaw':
25
- return new OpenClawTranslator();
26
- }
27
- }
28
- // ---------------------------------------------------------------------------
29
- // installHooks — main entry point
9
+ // installHooks — write hook files to disk
30
10
  // ---------------------------------------------------------------------------
31
11
  /**
32
12
  * Install hooks for the given agent type.
33
13
  *
34
- * Reads all registered intents, raw hooks, and extend hooks from the hook
35
- * registry. Translates them into native hook files using the agent-specific
36
- * translator. Runs degradation checks and conflict detection.
14
+ * Accepts one or more HookSet (from defineHooks()). Filters to only those
15
+ * matching the target agent. Writes content to the agent's hook directory.
16
+ *
17
+ * For Claude Code / Codex: writes shell scripts, merges into settings.json.
18
+ * For OpenCode: writes TypeScript plugin files directly to plugins dir.
19
+ * For OpenClaw: writes HOOK.md + handler.ts, attempts CLI activation.
37
20
  *
38
21
  * @internal — called by the Kit object returned from createKit().
39
22
  */
40
- export async function installHooks(name, agent) {
23
+ export async function installHooks(name, agent, hookSets) {
41
24
  const home = os.homedir();
42
25
  const entry = AGENT_REGISTRY[agent];
43
26
  const hookDir = entry.getHookDir(home, name);
@@ -48,56 +31,41 @@ export async function installHooks(name, agent) {
48
31
  settingsUpdated: false,
49
32
  notes: [],
50
33
  warnings: [],
51
- skipped: [],
52
34
  };
53
- const intents = getIntents();
54
- const rawHooks = getRawHooks();
55
- const extendHooks = getExtendHooks();
56
- // Check if there's anything to install
57
- if (intents.length === 0 && rawHooks.size === 0 && extendHooks.size === 0) {
58
- result.error =
59
- 'No hooks registered. Use hooks.inject(), hooks.beforeToolCall(), etc. to declare hook behavior.';
35
+ // Normalize and filter to matching agent
36
+ const sets = (Array.isArray(hookSets) ? hookSets : [hookSets]).filter((s) => s.agent === agent);
37
+ if (sets.length === 0) {
38
+ result.error = `No hook definitions found for agent "${agent}".`;
60
39
  return result;
61
40
  }
41
+ // Collect all definitions from matching sets
42
+ const allDefs = [];
43
+ for (const set of sets) {
44
+ allDefs.push(...set.definitions);
45
+ }
62
46
  try {
63
- // Step 1: Run degradation checks
64
- const intentTypes = [...new Set(intents.map((i) => i.type))];
65
- const degradations = checkAllDegradation(agent, intentTypes);
66
- for (const d of degradations) {
67
- if (d.level === 'unsupported') {
68
- result.warnings.push(d.message);
69
- }
70
- else if (d.level === 'partial') {
71
- result.warnings.push(d.message);
72
- }
73
- }
74
- // Step 2: Filter raw/extend hooks for this agent
75
- const agentRawHooks = new Map();
76
- for (const [key, reg] of rawHooks) {
77
- if (key.startsWith(`${agent}::`)) {
78
- agentRawHooks.set(key, reg);
79
- }
47
+ // Generate files based on agent type
48
+ const files = {};
49
+ switch (agent) {
50
+ case 'claude-code':
51
+ case 'codex':
52
+ generateClaudeCodeFiles(files, allDefs, name);
53
+ break;
54
+ case 'opencode':
55
+ generateOpenCodeFiles(files, allDefs, name);
56
+ break;
57
+ case 'openclaw':
58
+ generateOpenClawFiles(files, allDefs, name);
59
+ break;
80
60
  }
81
- const agentExtendHooks = new Map();
82
- for (const [key, regs] of extendHooks) {
83
- if (key.startsWith(`${agent}::`)) {
84
- agentExtendHooks.set(key, regs);
85
- }
86
- }
87
- // Step 3: Translate intents → native files
88
- const translator = getTranslator(agent);
89
- const translation = translator.translate(intents, agentRawHooks, agentExtendHooks, name);
90
- // Merge translation warnings and skipped
91
- result.warnings.push(...translation.warnings);
92
- result.skipped.push(...translation.skipped);
93
- // Step 4: Write hook files
94
- if (Object.keys(translation.files).length === 0) {
95
- result.notes.push('No hook files generated for this agent.');
61
+ if (Object.keys(files).length === 0) {
62
+ result.notes.push('No hook files generated.');
96
63
  result.success = true;
97
64
  return result;
98
65
  }
66
+ // Write files
99
67
  await fs.mkdir(hookDir, { recursive: true });
100
- for (const [fileName, content] of Object.entries(translation.files)) {
68
+ for (const [fileName, content] of Object.entries(files)) {
101
69
  const filePath = path.join(hookDir, fileName);
102
70
  await fs.writeFile(filePath, content, 'utf-8');
103
71
  if (fileName.endsWith('.sh')) {
@@ -105,16 +73,16 @@ export async function installHooks(name, agent) {
105
73
  }
106
74
  result.filesWritten.push(filePath);
107
75
  }
108
- // Step 5: Merge settings.json for agents that need it (Claude Code / Codex)
76
+ // Merge settings.json for Claude Code / Codex
109
77
  if (entry.getSettingsPath) {
110
78
  const settingsPath = entry.getSettingsPath(home);
111
- const shellFiles = Object.keys(translation.files).filter((f) => f.endsWith('.sh'));
79
+ const shellFiles = Object.keys(files).filter((f) => f.endsWith('.sh'));
112
80
  if (shellFiles.length > 0) {
113
- await mergeHookSettings(settingsPath, hookDir, shellFiles, name);
81
+ await mergeHookSettings(settingsPath, hookDir, shellFiles, allDefs, name);
114
82
  result.settingsUpdated = true;
115
83
  }
116
84
  }
117
- // Step 6: Agent-specific post-install
85
+ // OpenClaw post-install: attempt CLI activation
118
86
  if (agent === 'openclaw') {
119
87
  try {
120
88
  await execFileAsync('openclaw', ['hooks', 'enable', name]);
@@ -148,7 +116,7 @@ export async function uninstallHooks(name, agent) {
148
116
  const hookDir = entry.getHookDir(home, name);
149
117
  const removed = [];
150
118
  try {
151
- // Remove hook directory
119
+ // Remove hook directory contents
152
120
  try {
153
121
  const files = await fs.readdir(hookDir);
154
122
  for (const file of files) {
@@ -202,13 +170,69 @@ export async function hasHooksInstalled(name, agent) {
202
170
  }
203
171
  }
204
172
  // ---------------------------------------------------------------------------
173
+ // File generators — per agent
174
+ // ---------------------------------------------------------------------------
175
+ /**
176
+ * Claude Code / Codex: each definition × each event → one shell script.
177
+ * Filename: `{toolName}-{event}.sh`
178
+ */
179
+ function generateClaudeCodeFiles(files, defs, toolName) {
180
+ for (const def of defs) {
181
+ for (const event of def.events) {
182
+ const fileName = `${toolName}-${event}.sh`;
183
+ // If multiple definitions target the same event, later ones win
184
+ files[fileName] = def.content;
185
+ }
186
+ }
187
+ }
188
+ /**
189
+ * OpenCode: each definition × each event → one TypeScript plugin file.
190
+ * Filename: `{toolName}-{event}-plugin.ts`
191
+ *
192
+ * OpenCode plugins dir is flat (all in ~/.config/opencode/plugins/).
193
+ * Content is written as-is — users provide the full plugin file content.
194
+ */
195
+ function generateOpenCodeFiles(files, defs, toolName) {
196
+ for (const def of defs) {
197
+ for (const event of def.events) {
198
+ // Sanitize event name for filename (dots → dashes)
199
+ const sanitized = event.replace(/\./g, '-');
200
+ const fileName = `${toolName}-${sanitized}-plugin.ts`;
201
+ files[fileName] = def.content;
202
+ }
203
+ }
204
+ }
205
+ /**
206
+ * OpenClaw: generates HOOK.md (YAML frontmatter) + handler.ts.
207
+ * Only uses the first definition (OpenClaw = one hook = one HOOK.md + handler.ts).
208
+ */
209
+ function generateOpenClawFiles(files, defs, toolName) {
210
+ if (defs.length === 0)
211
+ return;
212
+ const def = defs[0]; // Only first definition used
213
+ // Generate HOOK.md
214
+ const description = def.description || `Hook installed by ${toolName}`;
215
+ const eventsYaml = def.events.map((e) => ` - ${e}`).join('\n');
216
+ files['HOOK.md'] = [
217
+ '---',
218
+ `name: ${toolName}`,
219
+ `description: ${description}`,
220
+ 'events:',
221
+ eventsYaml,
222
+ '---',
223
+ '',
224
+ ].join('\n');
225
+ // handler.ts — user-provided content
226
+ files['handler.ts'] = def.content;
227
+ }
228
+ // ---------------------------------------------------------------------------
205
229
  // Settings merge (Claude Code / Codex)
206
230
  // ---------------------------------------------------------------------------
207
231
  /**
208
232
  * Merge hook entries into settings.json for Claude Code / Codex.
209
- * Maps each shell script to its corresponding native hook event based on filename conventions.
233
+ * Maps each shell script filename to its hook event via the definitions.
210
234
  */
211
- async function mergeHookSettings(settingsPath, hookDir, shellFiles, toolName) {
235
+ async function mergeHookSettings(settingsPath, hookDir, shellFiles, defs, toolName) {
212
236
  let settings = {};
213
237
  try {
214
238
  const raw = await fs.readFile(settingsPath, 'utf-8');
@@ -221,39 +245,19 @@ async function mergeHookSettings(settingsPath, hookDir, shellFiles, toolName) {
221
245
  settings.hooks = {};
222
246
  }
223
247
  const hooks = settings.hooks;
224
- // Map filename patterns to native hook events
225
- const fileToEvent = {
226
- inject: 'UserPromptSubmit',
227
- 'session-start': 'SessionStart',
228
- 'session-end': 'SessionEnd',
229
- compaction: 'PreCompact',
230
- 'before-tool': 'PreToolUse',
231
- 'after-tool': 'PostToolUse',
232
- 'on-session-start': 'SessionStart',
233
- 'on-session-end': 'SessionEnd',
234
- permission: 'PermissionRequest',
235
- };
236
- for (const fileName of shellFiles) {
237
- const activatorPath = path.join(hookDir, fileName);
238
- // Determine the event from filename
239
- let event;
240
- // Check raw hooks first (pattern: toolName-raw-hookname.sh)
241
- const rawMatch = fileName.match(/^.+-raw-(.+)\.sh$/);
242
- if (rawMatch) {
243
- // Raw hooks use the hook name directly (case-insensitive lookup)
244
- event = rawMatch[1].charAt(0).toUpperCase() + rawMatch[1].slice(1);
245
- }
246
- else {
247
- // Intent-generated hooks use filename conventions
248
- for (const [pattern, hookEvent] of Object.entries(fileToEvent)) {
249
- if (fileName.includes(pattern)) {
250
- event = hookEvent;
251
- break;
252
- }
253
- }
248
+ // Build filename event map from definitions
249
+ const fileToEvent = new Map();
250
+ for (const def of defs) {
251
+ for (const event of def.events) {
252
+ const fileName = `${toolName}-${event}.sh`;
253
+ fileToEvent.set(fileName, event);
254
254
  }
255
+ }
256
+ for (const fileName of shellFiles) {
257
+ const event = fileToEvent.get(fileName);
255
258
  if (!event)
256
259
  continue;
260
+ const activatorPath = path.join(hookDir, fileName);
257
261
  const hookEntry = {
258
262
  matcher: '',
259
263
  hooks: [{ type: 'command', command: activatorPath }],
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
package/build/index.d.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  export { createKit } from './create-kit.js';
2
- export type { AgentType, StorageScope, ScopeOptions, KitOptions, Kit, HookInstallResult, SkippedIntent, } from './types.js';
2
+ export { defineHooks, getValidEvents } from './define-hooks.js';
3
+ export type { AgentType, StorageScope, ScopeOptions, KitOptions, Kit, HookInstallResult, HookDefinition, HookSet, ClaudeCodeEvent, OpenCodeEvent, OpenClawPluginEvent, OpenClawInternalEvent, OpenClawEvent, AgentEventMap, } from './types.js';
3
4
  export { AGENT_TYPES, CLIENT_NAME_MAP } from './types.js';
4
- export type { InjectIntent, BeforeToolCallIntent, AfterToolCallIntent, OnSessionIntent, OnPermissionIntent, HookIntent, IntentType, ToolCallContext, ToolCallInterceptResult, ToolCallObserveContext, SessionContext, PermissionDecision, PermissionContext, RawHookRegistration, ExtendHookRegistration, } from './hook-types.js';
5
- export type { SupportLevel, CapabilityEntry, DegradationWarning } from './hook-capabilities.js';
6
- export { CAPABILITY_MATRIX, checkDegradation, checkAllDegradation, isIntentFullyUnsupported, } from './hook-capabilities.js';
7
5
  export { detectProjectRoot } from './platform.js';
8
6
  export { detectAgent, detectAgentFromClient } from './detect.js';
9
- export { hooks } from './hook-registry.js';
package/build/index.js CHANGED
@@ -1,11 +1,10 @@
1
1
  // Core factory
2
2
  export { createKit } from './create-kit.js';
3
+ // Hook definition
4
+ export { defineHooks, getValidEvents } from './define-hooks.js';
3
5
  export { AGENT_TYPES, CLIENT_NAME_MAP } from './types.js';
4
- export { CAPABILITY_MATRIX, checkDegradation, checkAllDegradation, isIntentFullyUnsupported, } from './hook-capabilities.js';
5
6
  // Platform (only detectProjectRoot is standalone; getDataDir is on Kit)
6
7
  export { detectProjectRoot } from './platform.js';
7
8
  // Detection
8
9
  export { detectAgent, detectAgentFromClient } from './detect.js';
9
- // Hooks — declaration API (global, not bound to kit instance)
10
- export { hooks } from './hook-registry.js';
11
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAY5C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuB1D,OAAO,EACH,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,GAC3B,MAAM,wBAAwB,CAAC;AAEhC,wEAAwE;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEjE,8DAA8D;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,kBAAkB;AAClB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBhE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE1D,wEAAwE;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
package/build/types.d.ts CHANGED
@@ -45,8 +45,8 @@ export interface Kit {
45
45
  injectPrompt(agent: AgentType, prompt: string, options?: ScopeOptions): Promise<void>;
46
46
  /** Check if prompt has been injected. */
47
47
  hasPromptInjected(agent: AgentType, options?: ScopeOptions): Promise<boolean>;
48
- /** Install hooks for the given agent. */
49
- installHooks(agent: AgentType): Promise<HookInstallResult>;
48
+ /** Install hooks for the given agent. Accepts one or more HookSet from defineHooks(). */
49
+ installHooks(agent: AgentType, hooks: HookSet | HookSet[]): Promise<HookInstallResult>;
50
50
  /** Uninstall hooks for the given agent. */
51
51
  uninstallHooks(agent: AgentType): Promise<{
52
52
  success: boolean;
@@ -58,16 +58,46 @@ export interface Kit {
58
58
  /** Get platform-appropriate data directory path. */
59
59
  getDataDir(options?: ScopeOptions): string;
60
60
  }
61
+ /** Claude Code / Codex native hook event names. */
62
+ export type ClaudeCodeEvent = 'SessionStart' | 'InstructionsLoaded' | 'UserPromptSubmit' | 'PreToolUse' | 'PermissionRequest' | 'PostToolUse' | 'PostToolUseFailure' | 'Notification' | 'SubagentStart' | 'SubagentStop' | 'Stop' | 'TeammateIdle' | 'TaskCompleted' | 'ConfigChange' | 'WorktreeCreate' | 'WorktreeRemove' | 'PreCompact' | 'PostCompact' | 'Elicitation' | 'ElicitationResult' | 'SessionEnd';
63
+ /** OpenCode native hook event names. */
64
+ export type OpenCodeEvent = 'event' | 'config' | 'tool' | 'auth' | 'chat.message' | 'chat.params' | 'chat.headers' | 'permission.ask' | 'command.execute.before' | 'tool.execute.before' | 'shell.env' | 'tool.execute.after' | 'experimental.chat.messages.transform' | 'experimental.chat.system.transform' | 'experimental.session.compacting' | 'experimental.text.complete' | 'tool.definition';
65
+ /** OpenClaw plugin hook event names. */
66
+ export type OpenClawPluginEvent = 'before_model_resolve' | 'before_prompt_build' | 'before_agent_start' | 'llm_input' | 'llm_output' | 'agent_end' | 'before_compaction' | 'after_compaction' | 'before_reset' | 'message_received' | 'message_sending' | 'message_sent' | 'before_tool_call' | 'after_tool_call' | 'tool_result_persist' | 'before_message_write' | 'session_start' | 'session_end' | 'subagent_spawning' | 'subagent_delivery_target' | 'subagent_spawned' | 'subagent_ended' | 'gateway_start' | 'gateway_stop';
67
+ /** OpenClaw internal hook event names (type:action). */
68
+ export type OpenClawInternalEvent = 'command:new' | 'command:reset' | 'command:stop' | 'session:compact:before' | 'session:compact:after' | 'agent:bootstrap' | 'gateway:startup' | 'message:received' | 'message:sent' | 'message:transcribed' | 'message:preprocessed';
69
+ /** All OpenClaw hook event names (plugin + internal). */
70
+ export type OpenClawEvent = OpenClawPluginEvent | OpenClawInternalEvent;
71
+ /** Map from agent type to its event name union. */
72
+ export type AgentEventMap = {
73
+ 'claude-code': ClaudeCodeEvent;
74
+ codex: ClaudeCodeEvent;
75
+ opencode: OpenCodeEvent;
76
+ openclaw: OpenClawEvent;
77
+ };
61
78
  /**
62
- * Describes an intent that was skipped during hook installation.
79
+ * A single hook definition for a specific agent.
80
+ *
81
+ * - `events`: one or more native event names for this agent.
82
+ * - `content`: the hook content (shell script, TypeScript code, handler.ts body, etc.).
83
+ * Users are fully responsible for the content — agent-kit only writes it to the correct path.
84
+ * - `description`: (OpenClaw only) human-readable description for HOOK.md. Defaults to auto-generated.
63
85
  */
64
- export interface SkippedIntent {
65
- /** The intent type that was skipped (e.g. 'onPermission'). */
66
- intent: string;
67
- /** The agent for which it was skipped. */
68
- agent: string;
69
- /** Human-readable reason for skipping. */
70
- reason: string;
86
+ export interface HookDefinition<A extends AgentType = AgentType> {
87
+ events: A extends keyof AgentEventMap ? AgentEventMap[A][] : string[];
88
+ content: string;
89
+ /** OpenClaw only — description for HOOK.md. Ignored by other agents. */
90
+ description?: string;
91
+ }
92
+ /**
93
+ * A validated set of hook definitions for a specific agent, returned by defineHooks().
94
+ * This is an opaque token — users should not construct it directly.
95
+ */
96
+ export interface HookSet<A extends AgentType = AgentType> {
97
+ /** @internal brand field */
98
+ readonly __brand: 'HookSet';
99
+ readonly agent: A;
100
+ readonly definitions: readonly HookDefinition<A>[];
71
101
  }
72
102
  /**
73
103
  * Result of hook installation.
@@ -78,10 +108,7 @@ export interface HookInstallResult {
78
108
  filesWritten: string[];
79
109
  settingsUpdated: boolean;
80
110
  notes: string[];
81
- /** Degradation and conflict warnings (e.g. raw overrides, partial support). */
82
111
  warnings: string[];
83
- /** Intents that were completely skipped for this agent. */
84
- skipped: SkippedIntent[];
85
112
  error?: string;
86
113
  }
87
114
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AA6GrF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAA8B;IACtD,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,aAAa;IAC5B,qBAAqB,EAAE,UAAU;IACjC,kBAAkB,EAAE,OAAO;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAA0C;IACjE,QAAQ,EAAE;QACN,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,6BAA6B;QAChE,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,IAAI,2BAA2B;QACnE,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;YAC3B,GAAG,GAAG,gBAAgB;YACtB,GAAG,GAAG,iBAAiB;YACvB,GAAG,IAAI,iCAAiC;SAC3C;KACJ;IACD,aAAa,EAAE;QACX,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,oBAAoB;QACvD,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,kBAAkB,QAAQ,EAAE;QACnE,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,wBAAwB;QAC1D,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,YAAY,EAAE,GAAG,IAAI,oBAAoB,CAAC;KACnF;IACD,QAAQ,EAAE;QACN,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,gCAAgC;QACnE,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,oBAAoB,QAAQ,EAAE;QACrE,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,0BAA0B,CAAC;KACtE;IACD,KAAK,EAAE;QACH,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,mBAAmB;QACtD,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,iBAAiB,QAAQ,EAAE;QAClE,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,uBAAuB;QACzD,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,qBAAqB,EAAE,GAAG,IAAI,qBAAqB,CAAC;KAC7F;CACJ,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;AA4NrF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAA8B;IACtD,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,aAAa;IAC5B,qBAAqB,EAAE,UAAU;IACjC,kBAAkB,EAAE,OAAO;CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAA0C;IACjE,QAAQ,EAAE;QACN,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,6BAA6B;QAChE,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,IAAI,2BAA2B;QACnE,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;YAC3B,GAAG,GAAG,gBAAgB;YACtB,GAAG,GAAG,iBAAiB;YACvB,GAAG,IAAI,iCAAiC;SAC3C;KACJ;IACD,aAAa,EAAE;QACX,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,oBAAoB;QACvD,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,kBAAkB,QAAQ,EAAE;QACnE,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,wBAAwB;QAC1D,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,YAAY,EAAE,GAAG,IAAI,oBAAoB,CAAC;KACnF;IACD,QAAQ,EAAE;QACN,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,gCAAgC;QACnE,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,oBAAoB,QAAQ,EAAE;QACrE,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,0BAA0B,CAAC;KACtE;IACD,KAAK,EAAE;QACH,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,mBAAmB;QACtD,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,YAAY;QAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,IAAI,iBAAiB,QAAQ,EAAE;QAClE,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,uBAAuB;QACzD,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,qBAAqB,EAAE,GAAG,IAAI,qBAAqB,CAAC;KAC7F;CACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@s_s/agent-kit",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "面向 MCP Server 与 Skill 开发的 Agent 适配工具包",
5
5
  "type": "module",
6
6
  "main": "./build/index.js",