Files
agent-dashboard/internal/hook/cursor.go
T
2026-05-26 17:49:31 +08:00

78 lines
2.1 KiB
Go

package hook
import (
"io"
"os"
"github.com/longbin/agent-notify/internal/config"
"github.com/longbin/agent-notify/internal/context"
"github.com/longbin/agent-notify/internal/logx"
"github.com/longbin/agent-notify/internal/notify"
"github.com/longbin/agent-notify/internal/tmux"
)
type cursorPayload struct {
WorkspaceRoots []string `json:"workspace_roots"`
HookEventName string `json:"hook_event_name"`
Status string `json:"status"`
}
var (
sendForHook = notify.SendForHookWithResult
sendAuto = notify.SendAutoWithResult
)
func RunCursor(r io.Reader, cfg config.Config, event string, _ io.Writer) error {
var payload cursorPayload
fromHook := !isInteractiveStdin(r)
decodeJSON(r, &payload)
hookName := payload.HookEventName
if hookName == "" {
hookName = event
}
clientTTY, _ := tmux.ClientTTY()
logx.Append("hook cursor event=%s hook_event_name=%s status=%s enabled=%v from_hook=%v stdout_tty=%v client_tty=%q",
event, hookName, payload.Status, cfg.EventEnabled(event), fromHook, stdoutIsTerminal(), clientTTY)
if !cfg.EventEnabled(event) {
logx.Append("hook cursor event=%s skipped (disabled in config)", event)
return nil
}
meta := context.MetaFromEnv("Cursor", event)
if len(payload.WorkspaceRoots) > 0 {
meta.CWD = payload.WorkspaceRoots[0]
}
title := context.Render(cfg.Notify.TitleTemplate, meta)
body := cfg.BodyForEvent(event)
if shouldDebounce(title) {
logx.Append("hook cursor event=%s skipped (debounced duplicate)", event)
return nil
}
var result notify.SendResult
var err error
if fromHook {
result, err = sendForHook(cfg.Notify.Protocol, title, body)
} else {
result, err = sendAuto(cfg.Notify.Protocol, title, body)
}
if err != nil {
logx.Append("hook cursor event=%s send FAILED: %v", event, err)
return err
}
logx.Append("hook cursor event=%s send OK via %s title=%q", event, result.Method, title)
recordInbox(cfg, "Cursor", event, meta.CWD, title, body)
return nil
}
func stdoutIsTerminal() bool {
fi, err := os.Stdout.Stat()
if err != nil {
return false
}
return fi.Mode()&os.ModeCharDevice != 0
}