mirror of
https://github.com/imjasonh/cnotes
synced 2026-07-16 20:33:41 +00:00
- Add missing hook handlers: Stop, SubagentStop, PreCompact
- Replace all string type casting with proper JSON unmarshaling
- Change ToolUseRequest.Parameters from map[string]interface{} to json.RawMessage
- Update helper methods to use json.Unmarshal directly to typed structs
- Replace speech notifications with simple logging notifications
- Update documentation to reflect all hook events and remove speech references
- Add comprehensive CLAUDE.md with architecture overview and development guidance
All hooks now use type-safe JSON handling without .(string) assertions.
Complete coverage of Claude Code events: PreToolUse, PostToolUse,
UserPromptSubmit, Notification, Stop, SubagentStop, PreCompact.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/imjasonh/hooks/internal/hooks"
|
|
)
|
|
|
|
func AddProjectContext(ctx context.Context, input hooks.HookInput) (hooks.HookOutput, error) {
|
|
var contexts []string
|
|
|
|
if gitRoot := findGitRoot(input.CWD); gitRoot != "" {
|
|
contexts = append(contexts, fmt.Sprintf("Git repository root: %s", gitRoot))
|
|
|
|
if branch := getCurrentBranch(gitRoot); branch != "" {
|
|
contexts = append(contexts, fmt.Sprintf("Current branch: %s", branch))
|
|
}
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(input.CWD, "go.mod")); err == nil {
|
|
contexts = append(contexts, "Project type: Go module")
|
|
} else if _, err := os.Stat(filepath.Join(input.CWD, "package.json")); err == nil {
|
|
contexts = append(contexts, "Project type: Node.js/npm")
|
|
} else if _, err := os.Stat(filepath.Join(input.CWD, "Cargo.toml")); err == nil {
|
|
contexts = append(contexts, "Project type: Rust/Cargo")
|
|
}
|
|
|
|
if len(contexts) > 0 {
|
|
additionalContext := "Project context:\n" + strings.Join(contexts, "\n")
|
|
slog.Info("adding project context", "context_lines", len(contexts))
|
|
return hooks.HookOutput{
|
|
Decision: "approve",
|
|
AdditionalContext: additionalContext,
|
|
}, nil
|
|
}
|
|
|
|
return hooks.HookOutput{Decision: "approve"}, nil
|
|
}
|
|
|
|
func findGitRoot(dir string) string {
|
|
current := dir
|
|
for {
|
|
if _, err := os.Stat(filepath.Join(current, ".git")); err == nil {
|
|
return current
|
|
}
|
|
parent := filepath.Dir(current)
|
|
if parent == current {
|
|
return ""
|
|
}
|
|
current = parent
|
|
}
|
|
}
|
|
|
|
func getCurrentBranch(gitRoot string) string {
|
|
headPath := filepath.Join(gitRoot, ".git", "HEAD")
|
|
content, err := os.ReadFile(headPath)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
ref := strings.TrimSpace(string(content))
|
|
if strings.HasPrefix(ref, "ref: refs/heads/") {
|
|
return strings.TrimPrefix(ref, "ref: refs/heads/")
|
|
}
|
|
return ""
|
|
}
|