feat: 支持 UserPromptSubmit 事件,将 prompt 存入 MySQL

- 新增 db.go:MySQL 连接管理、自动建表、兼容旧表 ALTER
- handler.go:处理 UserPromptSubmit,从 cwd 提取项目名称
- main.go:可选初始化 MySQL,优雅关闭释放连接
- config.go:新增 MYSQL_DSN 配置项
- 表结构:session_id + project_name + prompt + created_at
This commit is contained in:
2026-06-25 23:52:42 +08:00
parent ea7f57d984
commit 717d2c70be
8 changed files with 229 additions and 10 deletions
+33 -2
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"net/http"
"path/filepath"
)
// ClaudeCodeHookEvent represents the JSON payload from Claude Code hooks
@@ -20,10 +21,11 @@ type ClaudeCodeHookEvent struct {
type HookHandler struct {
config Config
db *PromptDB // 可能为 nil,未配置 MySQL 时跳过数据库写入
}
func NewHookHandler(config Config) *HookHandler {
return &HookHandler{config: config}
func NewHookHandler(config Config, db *PromptDB) *HookHandler {
return &HookHandler{config: config, db: db}
}
func (h *HookHandler) HandleHook(w http.ResponseWriter, r *http.Request) {
@@ -51,6 +53,11 @@ func (h *HookHandler) HandleHook(w http.ResponseWriter, r *http.Request) {
title, message, priority = h.handleStop(event)
case "PreToolUse":
title, message, priority = h.handlePreToolUse(event)
case "UserPromptSubmit":
h.handleUserPromptSubmit(event)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, `{"status":"ok"}`)
return
default:
log.Printf("ignored event: %s", event.HookEventName)
w.WriteHeader(http.StatusOK)
@@ -124,3 +131,27 @@ func (h *HookHandler) handleStop(event ClaudeCodeHookEvent) (title, message stri
return title, message, priority
}
// handleUserPromptSubmit 将用户提交的 prompt 写入数据库
func (h *HookHandler) handleUserPromptSubmit(event ClaudeCodeHookEvent) {
if h.db == nil {
log.Printf("mysql not configured, skip saving prompt for session %s", event.SessionID)
return
}
prompt, _ := event.ToolInput["prompt"].(string)
if prompt == "" {
log.Printf("empty prompt in UserPromptSubmit, session=%s", event.SessionID)
return
}
// 从 cwd 提取项目名称(最后一级目录)
projectName := filepath.Base(event.CWD)
if err := h.db.SavePrompt(event.SessionID, projectName, prompt); err != nil {
log.Printf("failed to save prompt: %v", err)
return
}
log.Printf("prompt saved: session=%s, project=%s, len=%d", event.SessionID, projectName, len(prompt))
}