feat: fix Cursor hook delivery and improve notify workflow
Route hook notifications through /dev/tty and client_tty so OSC reaches Ghostty when Cursor captures stdout. Add afterAgentResponse hook, hook logging, debounce, split test modes, and use directory name for titles. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package logx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Path() string {
|
||||
return filepath.Join(os.Getenv("HOME"), ".local", "state", "agent-notify", "hook.log")
|
||||
}
|
||||
|
||||
func Append(format string, args ...any) {
|
||||
path := Path()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
fmt.Fprintf(f, "[%s] %s\n", time.Now().Format(time.RFC3339), msg)
|
||||
}
|
||||
|
||||
func Tail(n int) ([]string, error) {
|
||||
data, err := os.ReadFile(Path())
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
lines := splitLines(string(data))
|
||||
if n <= 0 || n >= len(lines) {
|
||||
return lines, nil
|
||||
}
|
||||
return lines[len(lines)-n:], nil
|
||||
}
|
||||
|
||||
func splitLines(s string) []string {
|
||||
var lines []string
|
||||
start := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == '\n' {
|
||||
line := s[start:i]
|
||||
if line != "" {
|
||||
lines = append(lines, line)
|
||||
}
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
if start < len(s) {
|
||||
lines = append(lines, s[start:])
|
||||
}
|
||||
return lines
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package logx
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAppendAndTail(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
t.Setenv("HOME", dir)
|
||||
|
||||
Append("hello %s", "world")
|
||||
lines, err := Tail(10)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(lines) != 1 {
|
||||
t.Fatalf("expected 1 line, got %d", len(lines))
|
||||
}
|
||||
if lines[0] == "" {
|
||||
t.Fatal("empty line")
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, ".local", "state", "agent-notify", "hook.log")
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
t.Fatalf("log file not created: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user