1
0
Fork 0
mirror of https://github.com/imjasonh/cnotes synced 2026-07-16 20:33:41 +00:00
cnotes/internal/handlers/userprompt.go
Jason Hall 45ef980233
Scaffold all 7 hook events and eliminate type casting
- 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>
2025-07-21 12:01:55 -04:00

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 ""
}