sink_plan.go

 1package acp
 2
 3import (
 4	"log/slog"
 5
 6	"github.com/charmbracelet/crush/internal/pubsub"
 7	"github.com/charmbracelet/crush/internal/session"
 8	"github.com/coder/acp-go-sdk"
 9)
10
11// HandleSession translates session updates to ACP plan updates.
12func (s *Sink) HandleSession(event pubsub.Event[session.Session]) {
13	sess := event.Payload
14
15	// Only handle updates for our session.
16	if sess.ID != s.sessionID {
17		return
18	}
19
20	// Only handle update events (not created/deleted).
21	if event.Type != pubsub.UpdatedEvent {
22		return
23	}
24
25	// Convert todos to plan entries.
26	entries := make([]acp.PlanEntry, len(sess.Todos))
27	for i, todo := range sess.Todos {
28		entries[i] = acp.PlanEntry{
29			Content:  todo.Content,
30			Status:   acp.PlanEntryStatus(todo.Status),
31			Priority: acp.PlanEntryPriorityMedium,
32		}
33		if todo.ActiveForm != "" {
34			entries[i].Meta = map[string]string{"active_form": todo.ActiveForm}
35		}
36	}
37
38	update := acp.UpdatePlan(entries...)
39	if err := s.conn.SessionUpdate(s.ctx, acp.SessionNotification{
40		SessionId: acp.SessionId(s.sessionID),
41		Update:    update,
42	}); err != nil {
43		slog.Error("Failed to send plan update", "error", err)
44	}
45}