@goodfoot/claude-code-hooks 1.0.1 → 1.0.3
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 +9 -9
- package/dist/cli.js +9 -9
- package/dist/scaffold.js +3 -3
- package/package.json +5 -15
- package/types/cli.d.ts +5 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @goodfoot/claude-code-hooks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Build Claude Code hooks in TypeScript.**
|
|
4
4
|
|
|
5
5
|
This package is not just a library; it is a **build system** and a **runtime wrapper**. You write TypeScript, this package compiles it into self-contained executables, and _those_ are what Claude runs.
|
|
6
6
|
|
|
@@ -10,11 +10,11 @@ Load the "claude-code-hooks:sdk" skill to enable Claude to use this package.
|
|
|
10
10
|
|
|
11
11
|
Run:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
claude plugin marketplace add goodfoot-io/marketplace && claude plugin install claude-code-hooks@goodfoot"
|
|
13
|
+
`claude plugin marketplace add goodfoot-io/marketplace && claude plugin install claude-code-hooks@goodfoot"`
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
then:
|
|
16
|
+
|
|
17
|
+
`claude -p "Load the 'claude-code-hooks:sdk' skill then scaffold a new hook package in ./packages/hooks that outputs to '.claude/hooks/hooks.json' and contains an example SessionStart hook."`
|
|
18
18
|
|
|
19
19
|
## ⚡ Quick Start
|
|
20
20
|
|
|
@@ -157,9 +157,9 @@ Violating these rules will cause your hooks to fail silently or block Claude ent
|
|
|
157
157
|
|
|
158
158
|
1. **NO `console.log`**: The hook communicates with Claude via `stdout`. If you print "Hello world", you corrupt the JSON protocol.
|
|
159
159
|
- **Bad:** `console.log("Checking command")`
|
|
160
|
-
- **Good:** `
|
|
161
|
-
2. **Relative Paths via Environment Variable**: The generated `hooks.json` uses `node $CLAUDE_PLUGIN_ROOT/hooks/
|
|
162
|
-
- Compiled hooks are placed in a `
|
|
160
|
+
- **Good:** `logger.info("Checking command")`
|
|
161
|
+
2. **Relative Paths via Environment Variable**: The generated `hooks.json` uses `node $CLAUDE_PLUGIN_ROOT/hooks/bin/` paths.
|
|
162
|
+
- Compiled hooks are placed in a `bin/` subdirectory relative to `hooks.json`.
|
|
163
163
|
- The `$CLAUDE_PLUGIN_ROOT` environment variable is set by Claude Code at runtime.
|
|
164
164
|
- Use the `--executable` CLI option to specify a custom executable (e.g., `bun`, `/usr/local/bin/node22`).
|
|
165
165
|
3. **`export default` is Mandatory**: The CLI uses static analysis to find your hooks. It looks specifically for `export default factory(...)`.
|
|
@@ -252,7 +252,7 @@ plugins/my-plugin/
|
|
|
252
252
|
│ ├── block-dangerous.ts
|
|
253
253
|
│ └── inject-context.ts
|
|
254
254
|
├── hooks.json # Build output (auto-loaded by plugin)
|
|
255
|
-
└──
|
|
255
|
+
└── bin/
|
|
256
256
|
├── block-dangerous.abc123.mjs
|
|
257
257
|
└── inject-context.def456.mjs
|
|
258
258
|
```
|
package/dist/cli.js
CHANGED
|
@@ -89,7 +89,7 @@ Examples:
|
|
|
89
89
|
npx -y @goodfoot/claude-code-hooks -i "hooks/**/*.ts" -o "dist/hooks.json"
|
|
90
90
|
|
|
91
91
|
2. With Runtime Logging:
|
|
92
|
-
npx -y @goodfoot/claude-code-hooks -i "src/hooks/*.ts" -o "
|
|
92
|
+
npx -y @goodfoot/claude-code-hooks -i "src/hooks/*.ts" -o "bin/hooks.json" --log /tmp/claude-hooks.log
|
|
93
93
|
|
|
94
94
|
3. Scaffold a New Hook Project:
|
|
95
95
|
npx -y @goodfoot/claude-code-hooks --scaffold ./my-hooks --hooks Stop,SubagentStop -o dist/hooks.json
|
|
@@ -575,19 +575,19 @@ function detectHookContext(outputPath) {
|
|
|
575
575
|
/**
|
|
576
576
|
* Generates a command path based on the hook context.
|
|
577
577
|
*
|
|
578
|
-
* Calculates the relative path from the root directory to the
|
|
578
|
+
* Calculates the relative path from the root directory to the bin directory.
|
|
579
579
|
* Prepends the node executable.
|
|
580
580
|
*
|
|
581
|
-
* - `plugin`: Uses `node $CLAUDE_PLUGIN_ROOT/hooks/
|
|
582
|
-
* - `agent`: Uses `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/
|
|
581
|
+
* - `plugin`: Uses `node $CLAUDE_PLUGIN_ROOT/hooks/bin/filename`
|
|
582
|
+
* - `agent`: Uses `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/bin/filename`
|
|
583
583
|
* @param filename - The compiled hook filename
|
|
584
|
-
* @param buildDir - Absolute path to the
|
|
584
|
+
* @param buildDir - Absolute path to the bin directory
|
|
585
585
|
* @param contextInfo - Hook context info including root directory
|
|
586
586
|
* @param executable - Node executable path (default: "node")
|
|
587
587
|
* @returns The command path string
|
|
588
588
|
*/
|
|
589
589
|
function generateCommandPath(filename, buildDir, contextInfo, executable = 'node') {
|
|
590
|
-
// Calculate relative path from root to
|
|
590
|
+
// Calculate relative path from root to bin directory
|
|
591
591
|
const relativeBuildPath = path.relative(contextInfo.rootDir, buildDir);
|
|
592
592
|
// Normalize to forward slashes for cross-platform compatibility
|
|
593
593
|
const normalizedRelativePath = relativeBuildPath.replace(/\\/g, '/');
|
|
@@ -603,7 +603,7 @@ function generateCommandPath(filename, buildDir, contextInfo, executable = 'node
|
|
|
603
603
|
*
|
|
604
604
|
* Format: { hooks: { EventType: [ { matcher?, hooks: [...] } ] } }
|
|
605
605
|
* @param compiledHooks - Array of compiled hooks
|
|
606
|
-
* @param buildDir - Absolute path to the
|
|
606
|
+
* @param buildDir - Absolute path to the bin directory
|
|
607
607
|
* @param contextInfo - Hook context info for path resolution
|
|
608
608
|
* @param executable - Node executable path (default: "node")
|
|
609
609
|
* @returns The hooks.json structure
|
|
@@ -802,8 +802,8 @@ async function main() {
|
|
|
802
802
|
const cwd = process.cwd();
|
|
803
803
|
const outputPath = path.resolve(cwd, args.output);
|
|
804
804
|
const hooksJsonDir = path.dirname(outputPath);
|
|
805
|
-
// Compiled hooks go in a '
|
|
806
|
-
const buildDir = path.join(hooksJsonDir, '
|
|
805
|
+
// Compiled hooks go in a 'bin' subdirectory relative to hooks.json
|
|
806
|
+
const buildDir = path.join(hooksJsonDir, 'bin');
|
|
807
807
|
// Resolve log file path to absolute if provided
|
|
808
808
|
const logFilePath = args.log !== undefined ? path.resolve(cwd, args.log) : undefined;
|
|
809
809
|
log('info', 'Starting hook compilation', {
|
package/dist/scaffold.js
CHANGED
|
@@ -181,7 +181,7 @@ function generateBiomeConfig() {
|
|
|
181
181
|
}
|
|
182
182
|
},
|
|
183
183
|
"files": {
|
|
184
|
-
"ignore": ["node_modules", "dist", "
|
|
184
|
+
"ignore": ["node_modules", "dist", "bin", "*.json"]
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
`;
|
|
@@ -220,7 +220,7 @@ node_modules/
|
|
|
220
220
|
|
|
221
221
|
# Build outputs
|
|
222
222
|
dist/
|
|
223
|
-
|
|
223
|
+
bin/
|
|
224
224
|
*.mjs
|
|
225
225
|
|
|
226
226
|
# Generated files
|
|
@@ -357,8 +357,8 @@ function generateTestFile(eventName, hookFilename) {
|
|
|
357
357
|
* Tests for the ${eventName} hook.
|
|
358
358
|
*/
|
|
359
359
|
|
|
360
|
-
import { describe, expect, it } from "vitest";
|
|
361
360
|
import { Logger } from "@goodfoot/claude-code-hooks";
|
|
361
|
+
import { describe, expect, it } from "vitest";
|
|
362
362
|
import hook from "../src/${hookFilename}.js";
|
|
363
363
|
|
|
364
364
|
// Logger is silent by default (no stdout/stderr output) — no mocking needed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodfoot/claude-code-hooks",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Type-safe Claude Code hooks library with camelCase types and output builders",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -27,28 +27,18 @@
|
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
".": {
|
|
30
|
-
"import": "./
|
|
31
|
-
"types": "./
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"types": "./types/index.d.ts"
|
|
32
32
|
},
|
|
33
33
|
"./*": {
|
|
34
|
-
"import": "./
|
|
35
|
-
"types": "./
|
|
34
|
+
"import": "./dist/*.js",
|
|
35
|
+
"types": "./types/*.d.ts"
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"bin": "./dist/cli.js",
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"bin": {
|
|
41
41
|
"claude-code-hooks": "./dist/cli.js"
|
|
42
|
-
},
|
|
43
|
-
"exports": {
|
|
44
|
-
".": {
|
|
45
|
-
"import": "./dist/index.js",
|
|
46
|
-
"types": "./types/index.d.ts"
|
|
47
|
-
},
|
|
48
|
-
"./*": {
|
|
49
|
-
"import": "./dist/*.js",
|
|
50
|
-
"types": "./types/*.d.ts"
|
|
51
|
-
}
|
|
52
42
|
}
|
|
53
43
|
},
|
|
54
44
|
"dependencies": {
|
package/types/cli.d.ts
CHANGED
|
@@ -197,13 +197,13 @@ declare function detectHookContext(outputPath: string): HookContextInfo;
|
|
|
197
197
|
/**
|
|
198
198
|
* Generates a command path based on the hook context.
|
|
199
199
|
*
|
|
200
|
-
* Calculates the relative path from the root directory to the
|
|
200
|
+
* Calculates the relative path from the root directory to the bin directory.
|
|
201
201
|
* Prepends the node executable.
|
|
202
202
|
*
|
|
203
|
-
* - `plugin`: Uses `node $CLAUDE_PLUGIN_ROOT/hooks/
|
|
204
|
-
* - `agent`: Uses `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/
|
|
203
|
+
* - `plugin`: Uses `node $CLAUDE_PLUGIN_ROOT/hooks/bin/filename`
|
|
204
|
+
* - `agent`: Uses `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/bin/filename`
|
|
205
205
|
* @param filename - The compiled hook filename
|
|
206
|
-
* @param buildDir - Absolute path to the
|
|
206
|
+
* @param buildDir - Absolute path to the bin directory
|
|
207
207
|
* @param contextInfo - Hook context info including root directory
|
|
208
208
|
* @param executable - Node executable path (default: "node")
|
|
209
209
|
* @returns The command path string
|
|
@@ -219,7 +219,7 @@ declare function generateCommandPath(
|
|
|
219
219
|
*
|
|
220
220
|
* Format: { hooks: { EventType: [ { matcher?, hooks: [...] } ] } }
|
|
221
221
|
* @param compiledHooks - Array of compiled hooks
|
|
222
|
-
* @param buildDir - Absolute path to the
|
|
222
|
+
* @param buildDir - Absolute path to the bin directory
|
|
223
223
|
* @param contextInfo - Hook context info for path resolution
|
|
224
224
|
* @param executable - Node executable path (default: "node")
|
|
225
225
|
* @returns The hooks.json structure
|