@hasna/hooks 0.2.3 → 0.2.5
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 +302 -107
- package/bin/index.js +521 -61
- package/dist/index.js +264 -15
- package/hooks/hook-stylescheck/LICENSE +191 -0
- package/hooks/hook-stylescheck/README.md +41 -0
- package/hooks/hook-stylescheck/package.json +52 -0
- package/hooks/hook-stylescheck/src/hook.ts +213 -0
- package/hooks/hook-stylescheck/tsconfig.json +25 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,95 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @hasna/hooks
|
|
2
2
|
|
|
3
|
-
Open source library
|
|
3
|
+
Open source lifecycle hooks library for AI coding agents. 30 hooks across 10 categories, installable with a single command. Works with Claude Code and Gemini CLI.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Interactive mode - browse and select hooks
|
|
9
|
-
npx @hasna/hooks
|
|
10
|
-
|
|
11
|
-
# Install specific hooks
|
|
12
|
-
npx @hasna/hooks install gitguard branchprotect checkpoint
|
|
5
|
+
## Features
|
|
13
6
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
- **30 hooks** in 10 categories (git safety, code quality, security, notifications, and more)
|
|
8
|
+
- **Interactive CLI** (`hooks`) with React/Ink TUI for browsing, installing, and managing hooks
|
|
9
|
+
- **MCP server** (13 tools) for agent-driven hook management over stdio or SSE
|
|
10
|
+
- **Library** for programmatic access from Node.js/Bun
|
|
11
|
+
- **Multi-agent support** for Claude Code and Gemini CLI with per-agent event mapping
|
|
12
|
+
- **Agent profiles** with unique 8-char UUID identity system
|
|
13
|
+
- **Zero file copy** -- hooks run from the globally installed package, nothing is copied to your project
|
|
14
|
+
- **Web dashboard** for browsing hooks (Vite + React 19 + TailwindCSS 4)
|
|
15
|
+
- **Health checks** via `hooks doctor` to verify hook installation integrity
|
|
16
|
+
- Global or project-scoped installation
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
# Global install
|
|
22
21
|
bun install -g @hasna/hooks
|
|
23
|
-
|
|
24
|
-
# Or use npx (no install needed)
|
|
25
|
-
npx @hasna/hooks
|
|
26
22
|
```
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
If you need a scoped registry token (publish or private installs), copy an example file and set `NPM_TOKEN`:
|
|
24
|
+
Or with npm:
|
|
31
25
|
|
|
32
26
|
```bash
|
|
33
|
-
|
|
27
|
+
npm install -g @hasna/hooks
|
|
34
28
|
```
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## Usage
|
|
39
|
-
|
|
40
|
-
### Interactive Mode
|
|
41
|
-
|
|
42
|
-
Run without arguments to browse hooks by category:
|
|
30
|
+
Or use without installing:
|
|
43
31
|
|
|
44
32
|
```bash
|
|
45
|
-
hooks
|
|
33
|
+
npx @hasna/hooks
|
|
46
34
|
```
|
|
47
35
|
|
|
48
|
-
|
|
36
|
+
## Quick Start
|
|
49
37
|
|
|
50
38
|
```bash
|
|
51
|
-
#
|
|
39
|
+
# Interactive mode -- browse and select hooks
|
|
40
|
+
hooks
|
|
41
|
+
|
|
42
|
+
# Install specific hooks
|
|
52
43
|
hooks install gitguard branchprotect checkpoint
|
|
53
44
|
|
|
54
|
-
#
|
|
55
|
-
|
|
45
|
+
# Install all hooks in a category
|
|
46
|
+
hooks install --category "Git Safety"
|
|
56
47
|
|
|
57
|
-
|
|
48
|
+
# Install all 30 hooks
|
|
49
|
+
hooks install --all
|
|
50
|
+
|
|
51
|
+
# List all available hooks
|
|
52
|
+
hooks list
|
|
58
53
|
|
|
59
|
-
```bash
|
|
60
54
|
# Search by name, description, or tags
|
|
61
55
|
hooks search security
|
|
62
|
-
hooks search git
|
|
63
|
-
```
|
|
64
56
|
|
|
65
|
-
|
|
57
|
+
# Check health of installed hooks
|
|
58
|
+
hooks doctor
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
hooks
|
|
69
|
-
hooks list --category "Code Quality"
|
|
60
|
+
# Start MCP server for agent integration
|
|
61
|
+
hooks mcp --stdio
|
|
70
62
|
```
|
|
71
63
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
## Hook Categories
|
|
65
|
+
|
|
66
|
+
| Category | Count | Description |
|
|
67
|
+
|----------|------:|-------------|
|
|
68
|
+
| Git Safety | 3 | Block destructive git ops, protect branches, create snapshots |
|
|
69
|
+
| Code Quality | 6 | Check tests, lint, bugs, docs, files, and task completion |
|
|
70
|
+
| Security | 2 | Security audits and typosquatting prevention |
|
|
71
|
+
| Notifications | 5 | Phone, desktop, Slack, sound, and inter-agent messages |
|
|
72
|
+
| Context Management | 2 | Re-inject context and save state before compaction |
|
|
73
|
+
| Workflow Automation | 3 | Auto-format, auto-stage, and TDD enforcement |
|
|
74
|
+
| Environment | 1 | Detect nvm/virtualenv/asdf/rbenv activation needs |
|
|
75
|
+
| Permissions | 3 | Auto-approve safe commands, protect files, block prompt injection |
|
|
76
|
+
| Observability | 4 | Session logs, command logs, cost tracking, error detection |
|
|
77
|
+
| Agent Teams | 1 | Validate task completion criteria |
|
|
78
|
+
|
|
79
|
+
## Hook Events
|
|
80
|
+
|
|
81
|
+
| Event | Timing | Can Block | Matcher |
|
|
82
|
+
|-------|--------|:---------:|---------|
|
|
83
|
+
| PreToolUse | Before tool execution | Yes | Tool name pattern (e.g., `Bash`, `Write\|Edit`) |
|
|
84
|
+
| PostToolUse | After tool execution | No | Tool name pattern |
|
|
85
|
+
| Stop | Session ends | No | Empty string |
|
|
86
|
+
| Notification | System events (e.g., compaction) | No | Empty string |
|
|
77
87
|
|
|
78
|
-
|
|
88
|
+
Each hook receives JSON on stdin and outputs JSON on stdout:
|
|
79
89
|
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
```json
|
|
91
|
+
// Input (PreToolUse)
|
|
92
|
+
{
|
|
93
|
+
"session_id": "abc123",
|
|
94
|
+
"cwd": "/path/to/project",
|
|
95
|
+
"tool_name": "Bash",
|
|
96
|
+
"tool_input": { "command": "git push --force" }
|
|
97
|
+
}
|
|
83
98
|
|
|
84
|
-
|
|
99
|
+
// Output (block)
|
|
100
|
+
{ "decision": "block", "reason": "Destructive git operation blocked" }
|
|
85
101
|
|
|
86
|
-
|
|
87
|
-
|
|
102
|
+
// Output (approve)
|
|
103
|
+
{ "decision": "approve" }
|
|
88
104
|
```
|
|
89
105
|
|
|
90
106
|
## Available Hooks (30)
|
|
91
107
|
|
|
92
108
|
### Git Safety (3)
|
|
109
|
+
|
|
93
110
|
| Hook | Event | Description |
|
|
94
111
|
|------|-------|-------------|
|
|
95
112
|
| gitguard | PreToolUse | Blocks destructive git operations like reset --hard, push --force, clean -f |
|
|
@@ -97,6 +114,7 @@ hooks remove gitguard
|
|
|
97
114
|
| checkpoint | PreToolUse | Creates shadow git snapshots before file modifications for easy rollback |
|
|
98
115
|
|
|
99
116
|
### Code Quality (6)
|
|
117
|
+
|
|
100
118
|
| Hook | Event | Description |
|
|
101
119
|
|------|-------|-------------|
|
|
102
120
|
| checktests | PostToolUse | Checks for missing tests after file edits |
|
|
@@ -107,12 +125,14 @@ hooks remove gitguard
|
|
|
107
125
|
| checktasks | PostToolUse | Validates task completion and tracks progress |
|
|
108
126
|
|
|
109
127
|
### Security (2)
|
|
128
|
+
|
|
110
129
|
| Hook | Event | Description |
|
|
111
130
|
|------|-------|-------------|
|
|
112
131
|
| checksecurity | PostToolUse | Runs security checks via headless agents |
|
|
113
132
|
| packageage | PreToolUse | Checks package age before install to prevent typosquatting |
|
|
114
133
|
|
|
115
134
|
### Notifications (5)
|
|
135
|
+
|
|
116
136
|
| Hook | Event | Description |
|
|
117
137
|
|------|-------|-------------|
|
|
118
138
|
| phonenotify | Stop | Sends push notifications to phone via ntfy.sh |
|
|
@@ -122,12 +142,14 @@ hooks remove gitguard
|
|
|
122
142
|
| soundnotify | Stop | Plays a system sound when Claude finishes (macOS/Linux) |
|
|
123
143
|
|
|
124
144
|
### Context Management (2)
|
|
145
|
+
|
|
125
146
|
| Hook | Event | Description |
|
|
126
147
|
|------|-------|-------------|
|
|
127
148
|
| contextrefresh | Notification | Re-injects important context every N prompts to prevent drift |
|
|
128
149
|
| precompact | Notification | Saves session state before context compaction |
|
|
129
150
|
|
|
130
151
|
### Workflow Automation (3)
|
|
152
|
+
|
|
131
153
|
| Hook | Event | Description |
|
|
132
154
|
|------|-------|-------------|
|
|
133
155
|
| autoformat | PostToolUse | Runs project formatter (Prettier, Biome, Ruff, Black, gofmt) after file edits |
|
|
@@ -135,11 +157,13 @@ hooks remove gitguard
|
|
|
135
157
|
| tddguard | PreToolUse | Blocks implementation edits unless corresponding test files exist |
|
|
136
158
|
|
|
137
159
|
### Environment (1)
|
|
160
|
+
|
|
138
161
|
| Hook | Event | Description |
|
|
139
162
|
|------|-------|-------------|
|
|
140
163
|
| envsetup | PreToolUse | Warns when nvm, virtualenv, asdf, or rbenv may need activation before commands |
|
|
141
164
|
|
|
142
165
|
### Permissions (3)
|
|
166
|
+
|
|
143
167
|
| Hook | Event | Description |
|
|
144
168
|
|------|-------|-------------|
|
|
145
169
|
| permissionguard | PreToolUse | Auto-approves safe read-only commands and blocks dangerous operations |
|
|
@@ -147,6 +171,7 @@ hooks remove gitguard
|
|
|
147
171
|
| promptguard | PreToolUse | Blocks prompt injection attempts and credential access requests |
|
|
148
172
|
|
|
149
173
|
### Observability (4)
|
|
174
|
+
|
|
150
175
|
| Hook | Event | Description |
|
|
151
176
|
|------|-------|-------------|
|
|
152
177
|
| sessionlog | PostToolUse | Logs every tool call to .claude/session-log-\<date\>.jsonl |
|
|
@@ -155,74 +180,206 @@ hooks remove gitguard
|
|
|
155
180
|
| errornotify | PostToolUse | Detects tool failures and logs errors to .claude/errors.log |
|
|
156
181
|
|
|
157
182
|
### Agent Teams (1)
|
|
183
|
+
|
|
158
184
|
| Hook | Event | Description |
|
|
159
185
|
|------|-------|-------------|
|
|
160
186
|
| taskgate | PostToolUse | Validates task completion criteria before allowing tasks to be marked done |
|
|
161
187
|
|
|
162
|
-
##
|
|
188
|
+
## CLI Commands
|
|
189
|
+
|
|
190
|
+
| Command | Alias | Description |
|
|
191
|
+
|---------|-------|-------------|
|
|
192
|
+
| `hooks` | `hooks interactive`, `hooks i` | Interactive hook browser (default) |
|
|
193
|
+
| `hooks install <names...>` | `hooks add` | Install one or more hooks |
|
|
194
|
+
| `hooks install --all` | | Install all 30 hooks |
|
|
195
|
+
| `hooks install --category <cat>` | | Install all hooks in a category |
|
|
196
|
+
| `hooks list` | `hooks ls` | List available hooks |
|
|
197
|
+
| `hooks list --registered` | `hooks list -r` | Show currently registered hooks |
|
|
198
|
+
| `hooks list --category <cat>` | `hooks list -c <cat>` | Filter by category |
|
|
199
|
+
| `hooks search <query>` | | Search hooks by name, description, or tags |
|
|
200
|
+
| `hooks info <name>` | | Show detailed info about a hook |
|
|
201
|
+
| `hooks remove <name>` | `hooks rm` | Unregister a hook |
|
|
202
|
+
| `hooks update [names...]` | | Re-register hooks (picks up new package version) |
|
|
203
|
+
| `hooks doctor` | | Check health of installed hooks |
|
|
204
|
+
| `hooks docs [name]` | | Show documentation (general or hook-specific) |
|
|
205
|
+
| `hooks categories` | | List all categories with counts |
|
|
206
|
+
| `hooks init` | | Register a new agent profile |
|
|
207
|
+
| `hooks run <name>` | | Execute a hook (called by AI agents) |
|
|
208
|
+
| `hooks mcp` | | Start MCP server (SSE or `--stdio`) |
|
|
209
|
+
| `hooks upgrade` | | Self-update to latest version |
|
|
210
|
+
|
|
211
|
+
### Scope Options
|
|
212
|
+
|
|
213
|
+
Most commands accept scope flags:
|
|
214
|
+
|
|
215
|
+
| Flag | Description |
|
|
216
|
+
|------|-------------|
|
|
217
|
+
| `--global`, `-g` | Global scope (`~/.claude/settings.json`) -- default |
|
|
218
|
+
| `--project`, `-p` | Project scope (`.claude/settings.json`) |
|
|
219
|
+
| `--json`, `-j` | Machine-readable JSON output |
|
|
220
|
+
| `--profile <id>` | Agent profile ID to scope hooks to |
|
|
221
|
+
| `--overwrite`, `-o` | Overwrite existing hook registration |
|
|
222
|
+
|
|
223
|
+
## MCP Server
|
|
224
|
+
|
|
225
|
+
Start the MCP server for AI agent integration:
|
|
163
226
|
|
|
164
|
-
|
|
227
|
+
```bash
|
|
228
|
+
# Stdio transport (for agent MCP registration)
|
|
229
|
+
hooks mcp --stdio
|
|
165
230
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
231
|
+
# SSE transport (default, port 39427)
|
|
232
|
+
hooks mcp
|
|
233
|
+
hooks mcp --port 8080
|
|
234
|
+
```
|
|
170
235
|
|
|
171
|
-
|
|
236
|
+
### Registration
|
|
237
|
+
|
|
238
|
+
Add to `~/.claude/mcp.json` or equivalent agent config:
|
|
172
239
|
|
|
173
240
|
```json
|
|
174
|
-
// PreToolUse input
|
|
175
241
|
{
|
|
176
|
-
"
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
242
|
+
"mcpServers": {
|
|
243
|
+
"hooks": {
|
|
244
|
+
"command": "hooks",
|
|
245
|
+
"args": ["mcp", "--stdio"]
|
|
246
|
+
}
|
|
247
|
+
}
|
|
180
248
|
}
|
|
249
|
+
```
|
|
181
250
|
|
|
182
|
-
|
|
183
|
-
{ "decision": "block", "reason": "Destructive git operation blocked" }
|
|
251
|
+
### MCP Tools (13)
|
|
184
252
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
253
|
+
| Tool | Description |
|
|
254
|
+
|------|-------------|
|
|
255
|
+
| `hooks_list` | List all available hooks, optionally filtered by category |
|
|
256
|
+
| `hooks_search` | Search for hooks by name, description, or tags |
|
|
257
|
+
| `hooks_info` | Get detailed information about a specific hook including install status |
|
|
258
|
+
| `hooks_install` | Install one or more hooks by name |
|
|
259
|
+
| `hooks_install_category` | Install all hooks in a category |
|
|
260
|
+
| `hooks_install_all` | Install all available hooks |
|
|
261
|
+
| `hooks_remove` | Remove (unregister) a hook from agent settings |
|
|
262
|
+
| `hooks_doctor` | Check health of installed hooks |
|
|
263
|
+
| `hooks_categories` | List all hook categories with counts |
|
|
264
|
+
| `hooks_docs` | Get documentation (general overview or hook-specific README) |
|
|
265
|
+
| `hooks_registered` | Get list of currently registered hooks for a scope |
|
|
266
|
+
| `hooks_init` | Register a new agent profile |
|
|
267
|
+
| `hooks_profiles` | List all registered agent profiles |
|
|
268
|
+
|
|
269
|
+
## Agent Profiles
|
|
270
|
+
|
|
271
|
+
Agents can register a profile to get a unique 8-char UUID. This identity is injected into hook input when running with `--profile`.
|
|
188
272
|
|
|
189
|
-
|
|
273
|
+
```bash
|
|
274
|
+
# Register a profile
|
|
275
|
+
hooks init --agent claude --name "my-agent"
|
|
276
|
+
# Agent profile created
|
|
277
|
+
# Agent ID: a1b2c3d4
|
|
278
|
+
# Type: claude
|
|
190
279
|
|
|
191
|
-
|
|
280
|
+
# Install hooks scoped to a profile
|
|
281
|
+
hooks install gitguard --profile a1b2c3d4
|
|
192
282
|
|
|
283
|
+
# The registered settings entry becomes:
|
|
284
|
+
# hooks run gitguard --profile a1b2c3d4
|
|
193
285
|
```
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
286
|
+
|
|
287
|
+
Profiles are stored at `~/.hooks/profiles/<agent_id>.json`.
|
|
288
|
+
|
|
289
|
+
## Library Usage
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import {
|
|
293
|
+
HOOKS,
|
|
294
|
+
CATEGORIES,
|
|
295
|
+
searchHooks,
|
|
296
|
+
getHook,
|
|
297
|
+
getHooksByCategory,
|
|
298
|
+
installHook,
|
|
299
|
+
installHooks,
|
|
300
|
+
getRegisteredHooks,
|
|
301
|
+
removeHook,
|
|
302
|
+
createProfile,
|
|
303
|
+
listProfiles,
|
|
304
|
+
type HookMeta,
|
|
305
|
+
type Category,
|
|
306
|
+
} from "@hasna/hooks";
|
|
307
|
+
|
|
308
|
+
// Search for hooks
|
|
309
|
+
const securityHooks = searchHooks("security");
|
|
310
|
+
|
|
311
|
+
// Get hooks by category
|
|
312
|
+
const gitHooks = getHooksByCategory("Git Safety");
|
|
313
|
+
|
|
314
|
+
// Install a hook programmatically
|
|
315
|
+
const result = installHook("gitguard", { scope: "global" });
|
|
316
|
+
|
|
317
|
+
// Check what's registered
|
|
318
|
+
const registered = getRegisteredHooks("global");
|
|
319
|
+
|
|
320
|
+
// Create an agent profile
|
|
321
|
+
const profile = createProfile({ agent_type: "claude", name: "my-bot" });
|
|
203
322
|
```
|
|
204
323
|
|
|
205
|
-
##
|
|
324
|
+
## Writing a Custom Hook
|
|
206
325
|
|
|
207
|
-
|
|
326
|
+
Hooks follow a stdin/stdout JSON protocol. Create a new hook at `hooks/hook-<name>/`:
|
|
208
327
|
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
328
|
+
```
|
|
329
|
+
hooks/hook-myhook/
|
|
330
|
+
src/
|
|
331
|
+
hook.ts # Main hook logic (stdin JSON -> stdout JSON)
|
|
332
|
+
package.json
|
|
333
|
+
README.md
|
|
213
334
|
```
|
|
214
335
|
|
|
215
|
-
|
|
336
|
+
### Hook Template (PreToolUse)
|
|
216
337
|
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
338
|
+
```typescript
|
|
339
|
+
#!/usr/bin/env bun
|
|
340
|
+
import { readFileSync } from "fs";
|
|
341
|
+
|
|
342
|
+
interface HookInput {
|
|
343
|
+
session_id: string;
|
|
344
|
+
cwd: string;
|
|
345
|
+
tool_name: string;
|
|
346
|
+
tool_input: Record<string, unknown>;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
interface HookOutput {
|
|
350
|
+
decision?: "approve" | "block";
|
|
351
|
+
reason?: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Read JSON from stdin
|
|
355
|
+
const input: HookInput = JSON.parse(readFileSync(0, "utf-8"));
|
|
356
|
+
|
|
357
|
+
// Your logic here
|
|
358
|
+
if (input.tool_name === "Bash") {
|
|
359
|
+
const command = input.tool_input.command as string;
|
|
360
|
+
if (command.includes("rm -rf /")) {
|
|
361
|
+
console.log(JSON.stringify({ decision: "block", reason: "Dangerous command" }));
|
|
362
|
+
process.exit(0);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Approve by default
|
|
367
|
+
console.log(JSON.stringify({ decision: "approve" }));
|
|
221
368
|
```
|
|
222
369
|
|
|
370
|
+
Key rules:
|
|
371
|
+
- Read from **stdin** (JSON), write to **stdout** (JSON)
|
|
372
|
+
- Log diagnostics to **stderr** only (stdout must be clean JSON)
|
|
373
|
+
- PreToolUse hooks return `{ "decision": "approve" | "block", "reason"?: string }`
|
|
374
|
+
- PostToolUse/Stop/Notification hooks return informational JSON (not blocking)
|
|
375
|
+
|
|
376
|
+
### Registering a Custom Hook
|
|
377
|
+
|
|
378
|
+
Add the hook to `src/lib/registry.ts` in the `HOOKS` array, then update `dashboard/src/data.ts` to keep the dashboard in sync.
|
|
379
|
+
|
|
223
380
|
## Configuration
|
|
224
381
|
|
|
225
|
-
Hooks are registered in `~/.claude/settings.json
|
|
382
|
+
Hooks are registered in `~/.claude/settings.json` (Claude) or `~/.gemini/settings.json` (Gemini):
|
|
226
383
|
|
|
227
384
|
```json
|
|
228
385
|
{
|
|
@@ -231,7 +388,7 @@ Hooks are registered in `~/.claude/settings.json`:
|
|
|
231
388
|
{
|
|
232
389
|
"matcher": "Bash",
|
|
233
390
|
"hooks": [
|
|
234
|
-
{ "type": "command", "command": "
|
|
391
|
+
{ "type": "command", "command": "hooks run gitguard" }
|
|
235
392
|
]
|
|
236
393
|
}
|
|
237
394
|
]
|
|
@@ -239,29 +396,67 @@ Hooks are registered in `~/.claude/settings.json`:
|
|
|
239
396
|
}
|
|
240
397
|
```
|
|
241
398
|
|
|
399
|
+
Event names are mapped per agent:
|
|
400
|
+
|
|
401
|
+
| Internal Event | Claude Code | Gemini CLI |
|
|
402
|
+
|---------------|-------------|------------|
|
|
403
|
+
| PreToolUse | PreToolUse | BeforeTool |
|
|
404
|
+
| PostToolUse | PostToolUse | AfterTool |
|
|
405
|
+
| Stop | Stop | AfterAgent |
|
|
406
|
+
| Notification | Notification | Notification |
|
|
407
|
+
|
|
242
408
|
## Development
|
|
243
409
|
|
|
244
410
|
```bash
|
|
245
|
-
|
|
411
|
+
git clone https://github.com/hasna/hooks.git
|
|
412
|
+
cd hooks
|
|
246
413
|
bun install
|
|
247
414
|
|
|
248
|
-
# Run CLI in development
|
|
249
|
-
bun run
|
|
415
|
+
bun run dev # Run CLI in development (interactive mode)
|
|
416
|
+
bun run build # Build CLI (bin/) + library (dist/)
|
|
417
|
+
bun run typecheck # TypeScript type checking
|
|
418
|
+
bun test # Run all tests (592 tests, 1816+ assertions)
|
|
250
419
|
|
|
251
|
-
#
|
|
252
|
-
bun run
|
|
420
|
+
# Dashboard (separate Vite + React 19 app)
|
|
421
|
+
bun run dashboard:dev # Dev server at localhost:5173
|
|
422
|
+
bun run dashboard:build # Production build to dashboard/dist/
|
|
423
|
+
```
|
|
253
424
|
|
|
254
|
-
|
|
255
|
-
|
|
425
|
+
## Architecture
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
src/
|
|
429
|
+
cli/ Commander.js CLI + React/Ink interactive TUI
|
|
430
|
+
components/ App, Header, CategorySelect, HookSelect, SearchView, DataTable, InstallProgress
|
|
431
|
+
index.tsx CLI entry point (all commands)
|
|
432
|
+
lib/ Core logic
|
|
433
|
+
registry.ts Hook metadata registry (HOOKS array, categories, search)
|
|
434
|
+
installer.ts Hook registration in agent settings files
|
|
435
|
+
profiles.ts Agent profile identity system
|
|
436
|
+
mcp/ MCP server (stdio + SSE transport, 13 tools)
|
|
437
|
+
server.ts Tool definitions and transport setup
|
|
438
|
+
hooks/ Hook runtime test
|
|
439
|
+
index.ts Library re-exports
|
|
440
|
+
|
|
441
|
+
hooks/ 30 hook implementations
|
|
442
|
+
hook-gitguard/
|
|
443
|
+
src/hook.ts Main hook logic (stdin -> stdout)
|
|
444
|
+
package.json
|
|
445
|
+
README.md
|
|
446
|
+
hook-branchprotect/
|
|
447
|
+
hook-checkpoint/
|
|
448
|
+
...
|
|
449
|
+
|
|
450
|
+
dashboard/ Web dashboard (Vite + React 19 + TailwindCSS 4)
|
|
451
|
+
src/data.ts Static copy of hook metadata (sync with registry.ts)
|
|
256
452
|
```
|
|
257
453
|
|
|
258
|
-
|
|
454
|
+
### Build Outputs
|
|
259
455
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
4. Submit a pull request
|
|
456
|
+
Two separate `bun build` invocations:
|
|
457
|
+
- **CLI binary** (`bin/index.js`) -- Commander.js + Ink/React interactive UI
|
|
458
|
+
- **Library** (`dist/index.js` + `dist/index.d.ts`) -- Registry + installer + profile APIs
|
|
264
459
|
|
|
265
460
|
## License
|
|
266
461
|
|
|
267
|
-
Apache
|
|
462
|
+
[Apache License 2.0](LICENSE)
|