Skip to content

Commit bc0bbb3

Browse files
committed
feat: add claude code hook
1 parent 2d9f313 commit bc0bbb3

File tree

9 files changed

+1149
-160
lines changed

9 files changed

+1149
-160
lines changed

bun.lock

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"lockfileVersion": 1,
3+
"workspaces": {
4+
"": {
5+
"name": "gograph-claude-hook",
6+
"dependencies": {
7+
"@anthropic-ai/claude-code": "^1.0.41",
8+
},
9+
"devDependencies": {
10+
"@types/node": "^20.0.0",
11+
},
12+
},
13+
},
14+
"packages": {
15+
"@anthropic-ai/claude-code": ["@anthropic-ai/[email protected]", "", { "optionalDependencies": { "@img/sharp-darwin-arm64": "^0.33.5", "@img/sharp-darwin-x64": "^0.33.5", "@img/sharp-linux-arm": "^0.33.5", "@img/sharp-linux-arm64": "^0.33.5", "@img/sharp-linux-x64": "^0.33.5", "@img/sharp-win32-x64": "^0.33.5" }, "bin": { "claude": "cli.js" } }, "sha512-6E5SCb1I/pC4WCEFGwmyo4M4bL9vBuk7qkC78v9ZFX9PAxmKX94SEj422igdLeucBYX99ZqKSMYfsJEqTeIo2Q=="],
16+
17+
"@img/sharp-darwin-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="],
18+
19+
"@img/sharp-darwin-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="],
20+
21+
"@img/sharp-libvips-darwin-arm64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg=="],
22+
23+
"@img/sharp-libvips-darwin-x64": ["@img/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ=="],
24+
25+
"@img/sharp-libvips-linux-arm": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g=="],
26+
27+
"@img/sharp-libvips-linux-arm64": ["@img/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA=="],
28+
29+
"@img/sharp-libvips-linux-x64": ["@img/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw=="],
30+
31+
"@img/sharp-linux-arm": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.5" }, "os": "linux", "cpu": "arm" }, "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ=="],
32+
33+
"@img/sharp-linux-arm64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA=="],
34+
35+
"@img/sharp-linux-x64": ["@img/[email protected]", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA=="],
36+
37+
"@img/sharp-win32-x64": ["@img/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="],
38+
39+
"@types/node": ["@types/[email protected]", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA=="],
40+
41+
"undici-types": ["[email protected]", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
42+
}
43+
}

package.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "gograph",
3+
"version": "1.0.0",
4+
"description": "Go codebase dependency graph analysis tool with Claude Code integration",
5+
"type": "module",
6+
"scripts": {
7+
"hook": "bun run scripts/gograph-hook.ts",
8+
"test-hook": "bun run scripts/test-hook.ts"
9+
},
10+
"dependencies": {
11+
"@anthropic-ai/claude-code": "^1.0.41"
12+
},
13+
"devDependencies": {
14+
"@types/node": "^20.0.0"
15+
},
16+
"engines": {
17+
"bun": ">=1.0.0",
18+
"go": ">=1.21.0"
19+
},
20+
"keywords": [
21+
"go",
22+
"dependency-graph",
23+
"code-analysis",
24+
"claude-code",
25+
"mcp"
26+
]
27+
}

scripts/HOOK_ARCHITECTURE.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# gograph Claude Code Hook Architecture
2+
3+
## Overview
4+
5+
This hook implements Claude Code's PreToolUse hook system to provide intelligent Go code analysis before file operations.
6+
7+
## Implementation Details
8+
9+
### Hook Configuration Format
10+
11+
The hook uses the correct Claude Code hooks structure:
12+
13+
```json
14+
{
15+
"hooks": {
16+
"PreToolUse": [
17+
{
18+
"matcher": "Write|Edit|MultiEdit",
19+
"hooks": [
20+
{
21+
"type": "command",
22+
"command": "cd /path/to/gograph && bun run scripts/gograph-hook.ts"
23+
}
24+
]
25+
}
26+
]
27+
}
28+
}
29+
```
30+
31+
### Input Processing
32+
33+
The hook receives JSON input via stdin with this structure:
34+
35+
```typescript
36+
interface PreToolUseInput {
37+
session_id: string;
38+
transcript_path: string;
39+
tool_name: string;
40+
tool_input: Record<string, any>;
41+
}
42+
```
43+
44+
### Output Format
45+
46+
The hook returns structured JSON output for advanced control:
47+
48+
```typescript
49+
interface HookOutput {
50+
// Common fields
51+
continue?: boolean; // Whether Claude should continue (default: true)
52+
stopReason?: string; // Message shown when continue is false
53+
suppressOutput?: boolean; // Hide stdout from transcript mode (default: false)
54+
55+
// PreToolUse specific
56+
decision?: "approve" | "block" | undefined;
57+
reason?: string; // Explanation for decision
58+
}
59+
```
60+
61+
### Decision Logic
62+
63+
- **Approve**: The hook always approves Go file operations but provides analysis
64+
- **Reason**: Contains the formatted analysis output shown to Claude
65+
- **Continue**: Always true to allow operation to proceed
66+
- **Exit Codes**:
67+
- 0: Success with JSON output
68+
- 1: Non-blocking error (operation continues)
69+
- 2: Would block operation (not used in our implementation)
70+
71+
## Features
72+
73+
### 1. Automatic Go File Detection
74+
- Checks `file_path` parameter for `.go` extension
75+
- Handles MultiEdit operations with multiple edits
76+
- Skips non-Go files silently
77+
78+
### 2. gograph Configuration Detection
79+
- Looks for `gograph.yaml` in project hierarchy
80+
- Provides appropriate analysis based on configuration presence
81+
82+
### 3. Claude SDK Integration
83+
- Uses existing Claude Code session (no API key needed)
84+
- Includes `allowedTools` for MCP permissions
85+
- Graceful fallback to static analysis on failures
86+
87+
### 4. Comprehensive Logging
88+
- Logs all operations to `~/.claude/gograph-hook.log`
89+
- Includes timestamps and detailed error messages
90+
- Helps with debugging hook issues
91+
92+
## Security Considerations
93+
94+
- Runs with user permissions in current directory
95+
- No sensitive data exposed in logs
96+
- Uses structured JSON output to prevent injection
97+
- Validates all input data before processing
98+
99+
## Testing
100+
101+
The `test-hook.ts` script provides comprehensive testing:
102+
103+
```bash
104+
bun run test-hook
105+
```
106+
107+
Tests include:
108+
- Write operations on Go files
109+
- Edit operations on Go files
110+
- MultiEdit operations with multiple changes
111+
- Non-Go file handling (should skip)
112+
- Error handling and edge cases
113+
114+
## Integration Flow
115+
116+
1. Claude Code triggers hook before Write/Edit/MultiEdit
117+
2. Hook receives tool information via stdin
118+
3. Hook analyzes Go file context
119+
4. Returns approval with analysis feedback
120+
5. Claude sees analysis and proceeds with operation
121+
6. User benefits from contextual guidance
122+
123+
## Troubleshooting
124+
125+
### Hook Not Triggering
126+
- Check matcher regex in settings.json
127+
- Verify command path is absolute
128+
- Ensure bun is accessible in PATH
129+
130+
### Analysis Not Showing
131+
- Check exit code is 0
132+
- Verify JSON output format
133+
- Review logs for errors
134+
135+
### Permission Issues
136+
- Hook includes allowedTools configuration
137+
- Add global permissions if needed
138+
- Ensure gograph MCP server is running

scripts/INTEGRATION.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# gograph Claude Code Hook Integration
2+
3+
This guide shows how to manually integrate the gograph hook with your Claude Code settings.
4+
5+
## Prerequisites
6+
7+
- [bun](https://bun.sh) installed
8+
- Claude Code CLI installed and authenticated
9+
- gograph project with `gograph.yaml` configuration
10+
11+
## Setup Steps
12+
13+
### 1. Install Dependencies
14+
15+
```bash
16+
# From project root
17+
bun install
18+
```
19+
20+
### 2. Update Claude Code Settings
21+
22+
Add the hook configuration to your `~/.claude/settings.json`:
23+
24+
```json
25+
{
26+
"hooks": {
27+
"PreToolUse": [
28+
{
29+
"matcher": "Write|Edit|MultiEdit",
30+
"hooks": [
31+
{
32+
"type": "command",
33+
"command": "cd /path/to/your/gograph && bun run scripts/gograph-hook.ts"
34+
}
35+
]
36+
}
37+
]
38+
}
39+
}
40+
```
41+
42+
**Important**: Replace `/path/to/your/gograph` with the actual absolute path to your gograph project root directory.
43+
44+
### 3. Optional: Configure Global MCP Tool Permissions
45+
46+
The hook includes `allowedTools` configuration to permit gograph MCP tools automatically. However, you can also add global permissions to your `~/.claude/settings.json` if preferred:
47+
48+
```json
49+
{
50+
"permissions": {
51+
"allow": [
52+
"mcp__gograph__analyze_project",
53+
"mcp__gograph__get_package_structure",
54+
"mcp__gograph__query_dependencies",
55+
"mcp__gograph__get_function_info",
56+
"mcp__gograph__natural_language_query"
57+
]
58+
}
59+
}
60+
```
61+
62+
Note: The hook automatically includes these permissions via `allowedTools` configuration, so this step is optional.
63+
64+
### 4. Complete Settings Example
65+
66+
Here's a minimal `~/.claude/settings.json` example:
67+
68+
```json
69+
{
70+
"hooks": {
71+
"PreToolUse": [
72+
{
73+
"matcher": "Write|Edit|MultiEdit",
74+
"hooks": [
75+
{
76+
"type": "command",
77+
"command": "cd /Users/username/projects/gograph && bun run scripts/gograph-hook.ts"
78+
}
79+
]
80+
}
81+
]
82+
}
83+
}
84+
```
85+
86+
The hook handles tool permissions automatically via the SDK's `allowedTools` configuration.
87+
88+
## Testing the Integration
89+
90+
### 1. Test the Hook Directly
91+
92+
```bash
93+
cd scripts/
94+
bun run test-hook.ts
95+
```
96+
97+
### 2. Test with Claude Code
98+
99+
1. Open Claude Code in a Go project with gograph configuration
100+
2. Try editing or creating a `.go` file
101+
3. The hook should trigger and provide analysis before the operation
102+
4. Check logs at `~/.claude/gograph-hook.log` if needed
103+
104+
## How It Works
105+
106+
1. **Trigger**: Hook activates before `Write`, `Edit`, or `MultiEdit` operations on `.go` files
107+
2. **Analysis**: Uses Claude Code SDK with your existing session to analyze via gograph MCP
108+
3. **Output**: Provides dependency analysis, architectural recommendations, and integration guidance
109+
4. **Fallback**: If MCP analysis fails, provides static analysis based on gograph configuration
110+
111+
## Configuration Options
112+
113+
### Hook Matchers
114+
115+
You can customize which operations trigger the hook:
116+
117+
```json
118+
{
119+
"hooks": {
120+
"PreToolUse": [
121+
{
122+
"matcher": "Write|Edit|MultiEdit",
123+
"hooks": [
124+
{
125+
"type": "command",
126+
"command": "cd /path/to/your/gograph && bun run scripts/gograph-hook.ts"
127+
}
128+
]
129+
}
130+
]
131+
}
132+
}
133+
```
134+
135+
You can also use more specific regex patterns:
136+
- `"Write"` - Only Write operations
137+
- `"Edit|MultiEdit"` - Only Edit operations
138+
- `".*"` - All tools
139+
- `"Notebook.*"` - All notebook operations
140+
141+
### Working Directory
142+
143+
The hook automatically detects your project's working directory from the Claude Code session.
144+
145+
### Permissions
146+
147+
Without the permissions configuration, Claude Code will prompt you to approve each MCP tool use. Adding the permissions list prevents these prompts for a smoother experience.
148+
149+
## Troubleshooting
150+
151+
### Hook Not Triggering
152+
- Check that the path in your settings.json is correct and absolute
153+
- Ensure bun is installed and accessible
154+
- Verify the hook file is executable: `chmod +x scripts/gograph-hook.ts`
155+
156+
### Permission Errors
157+
- Add the gograph MCP tool permissions to your settings.json
158+
- Ensure your gograph MCP server is running and connected
159+
160+
### Analysis Failures
161+
- Check that you have a `gograph.yaml` file in your project
162+
- Verify gograph MCP tools are working: test with Claude Code directly
163+
- Check logs at `~/.claude/gograph-hook.log`
164+
165+
## Security Considerations
166+
167+
- The hook uses your existing Claude Code authentication session
168+
- No API keys or additional authentication required
169+
- Only processes Go files in projects with gograph configuration
170+
- Logs activity to `~/.claude/gograph-hook.log` for transparency
171+
172+
## Uninstalling
173+
174+
To remove the hook integration:
175+
176+
1. Remove the hook entry from your `~/.claude/settings.json`
177+
2. Optionally remove the gograph MCP permissions
178+
3. Delete the scripts directory if no longer needed

0 commit comments

Comments
 (0)