Files
skrueckenandCursor 2dbf0918de Add local JSON daemon and route TUI/CLI through it.
A per-DataDir background process owns ticket JSON, history, and sync so
multiple TUI instances stay consistent; MCP token APIs are ready for phase 2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-01 16:32:13 +01:00

54 lines
1.1 KiB
Go

package client
import (
"bufio"
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"task/internal/daemon/api"
)
// SubscribeEvents streams SSE change events until ctx is cancelled.
func (c *Client) SubscribeEvents(ctx context.Context, emit func(api.Event)) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://daemon/v1/events", nil)
if err != nil {
return err
}
req.Header.Set(api.HeaderClient, c.kind)
if c.kind == api.ClientMCP {
if c.token != "" {
req.Header.Set("Authorization", "Bearer "+c.token)
}
if c.project != "" {
req.Header.Set("X-TM-Project", c.project)
}
}
// No overall timeout for long-lived SSE.
httpClient := *c.http
httpClient.Timeout = 0
resp, err := httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return fmt.Errorf("events: %s", resp.Status)
}
sc := bufio.NewScanner(resp.Body)
for sc.Scan() {
line := sc.Text()
if !strings.HasPrefix(line, "data: ") {
continue
}
var ev api.Event
if err := json.Unmarshal([]byte(strings.TrimPrefix(line, "data: ")), &ev); err != nil {
continue
}
emit(ev)
}
return sc.Err()
}