feat: report agent status to remote server from hooks
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,11 +4,14 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/longbin/agent-notify/internal/config"
|
||||
"github.com/longbin/agent-notify/internal/inbox"
|
||||
"github.com/longbin/agent-notify/internal/remote"
|
||||
)
|
||||
|
||||
func TestCursorStopHookDisabled(t *testing.T) {
|
||||
@@ -153,3 +156,69 @@ func stubInbox(t *testing.T, upload func(inbox.Record, config.Config) error, app
|
||||
appendInboxRecord = prevAppend
|
||||
})
|
||||
}
|
||||
|
||||
func stubReportRemote(t *testing.T, fn func(config.Config, string, string, string, string, string)) {
|
||||
t.Helper()
|
||||
prev := reportRemoteHook
|
||||
reportRemoteHook = fn
|
||||
t.Cleanup(func() { reportRemoteHook = prev })
|
||||
}
|
||||
|
||||
func TestCursorHookReportsRemoteOnStop(t *testing.T) {
|
||||
stubCursorSend(t)
|
||||
var got remote.StatusReport
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/api/v1/status" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&got); err != nil {
|
||||
http.Error(w, "decode", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
cfg := config.Default()
|
||||
cfg.Remote.Enabled = true
|
||||
cfg.Remote.URL = srv.URL
|
||||
err := RunCursor(bytes.NewReader([]byte(`{"workspace_roots":["/tmp/proj"],"conversation_id":"conv-1","transcript_path":"/tmp/t.jsonl"}`)), cfg, "stop", &bytes.Buffer{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Agent != "Cursor" || got.Event != "stop" || got.Status != "waiting" || got.CWD != "/tmp/proj" {
|
||||
t.Fatalf("unexpected report: %+v", got)
|
||||
}
|
||||
if got.ConversationID != "conv-1" {
|
||||
t.Fatalf("conversation_id: got %q", got.ConversationID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCursorHookSkipsRemoteWhenDisabled(t *testing.T) {
|
||||
stubCursorSend(t)
|
||||
stubReportRemote(t, func(config.Config, string, string, string, string, string) {
|
||||
t.Fatal("reportRemote should not run when remote disabled")
|
||||
})
|
||||
|
||||
cfg := config.Default()
|
||||
cfg.Remote.Enabled = false
|
||||
if err := RunCursor(bytes.NewReader([]byte(`{"workspace_roots":["/tmp/proj"]}`)), cfg, "stop", &bytes.Buffer{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCursorHookRemoteReportFailureStillOK(t *testing.T) {
|
||||
stubCursorSend(t)
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "fail", http.StatusInternalServerError)
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
cfg := config.Default()
|
||||
cfg.Remote.Enabled = true
|
||||
cfg.Remote.URL = srv.URL
|
||||
if err := RunCursor(bytes.NewReader([]byte(`{"workspace_roots":["/tmp/proj"]}`)), cfg, "stop", &bytes.Buffer{}); err != nil {
|
||||
t.Fatalf("hook should return nil on remote failure, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user