agent tracker update

This commit is contained in:
David Chen 2026-04-02 13:45:55 -07:00
parent 5064629d61
commit 0bfcb8d7c3
31 changed files with 1741 additions and 3320 deletions

View file

@ -204,6 +204,21 @@ func (s *server) handleCommand(env ipc.Envelope) error {
s.broadcastStateAsync()
s.statusRefreshAsync()
return nil
case "update_task":
target, err := requireSessionWindow(env)
if err != nil {
return err
}
summary := firstNonEmpty(env.Summary, env.Message)
if summary == "" {
return fmt.Errorf("update_task requires summary")
}
if err := s.updateTaskSummary(target, summary); err != nil {
return err
}
s.broadcastStateAsync()
s.statusRefreshAsync()
return nil
case "notifications_toggle":
enabled, err := s.toggleNotifications()
if err != nil {
@ -255,16 +270,64 @@ func (s *server) startTask(target tmuxTarget, summary string) error {
now := time.Now()
s.mu.Lock()
defer s.mu.Unlock()
s.tasks[taskKey(target.SessionID, target.WindowID, target.PaneID)] = &taskRecord{
SessionID: target.SessionID,
SessionName: strings.TrimSpace(target.SessionName),
WindowID: target.WindowID,
WindowName: strings.TrimSpace(target.WindowName),
Pane: target.PaneID,
Summary: summary,
StartedAt: now,
Status: statusInProgress,
Acknowledged: true,
key := taskKey(target.SessionID, target.WindowID, target.PaneID)
t, ok := s.tasks[key]
if !ok {
s.tasks[key] = &taskRecord{
SessionID: target.SessionID,
SessionName: strings.TrimSpace(target.SessionName),
WindowID: target.WindowID,
WindowName: strings.TrimSpace(target.WindowName),
Pane: target.PaneID,
Summary: summary,
StartedAt: now,
Status: statusInProgress,
Acknowledged: true,
}
return nil
}
mergeTaskNamesFromTarget(t, target)
if !(t.Status == statusInProgress && strings.TrimSpace(t.Summary) != "") {
t.Summary = summary
}
t.StartedAt = now
t.Status = statusInProgress
t.CompletedAt = nil
t.CompletionNote = ""
t.Acknowledged = true
return nil
}
func (s *server) updateTaskSummary(target tmuxTarget, summary string) error {
if target.SessionID == "" || target.WindowID == "" {
return fmt.Errorf("cannot update task: missing session or window ID")
}
target = normalizeTargetNames(target)
now := time.Now()
s.mu.Lock()
defer s.mu.Unlock()
key := taskKey(target.SessionID, target.WindowID, target.PaneID)
t, ok := s.tasks[key]
if !ok {
t = &taskRecord{
SessionID: target.SessionID,
SessionName: strings.TrimSpace(target.SessionName),
WindowID: target.WindowID,
WindowName: strings.TrimSpace(target.WindowName),
Pane: target.PaneID,
StartedAt: now,
Status: statusInProgress,
Acknowledged: true,
}
s.tasks[key] = t
}
mergeTaskNamesFromTarget(t, target)
t.Summary = summary
if t.Status == "" {
t.Status = statusInProgress
}
if t.StartedAt.IsZero() {
t.StartedAt = now
}
return nil
}

View file

@ -1,53 +0,0 @@
package main
import (
"testing"
"time"
)
func TestNormalizeTargetNamesClearsIDPlaceholders(t *testing.T) {
target := normalizeTargetNames(tmuxTarget{
SessionName: "$3",
SessionID: "$3",
WindowName: "@12",
WindowID: "@12",
PaneID: "%7",
})
if target.SessionName != "" {
t.Fatalf("expected placeholder session name to be cleared, got %q", target.SessionName)
}
if target.WindowName != "" {
t.Fatalf("expected placeholder window name to be cleared, got %q", target.WindowName)
}
}
func TestBuildStateEnvelopeUsesStoredTaskNames(t *testing.T) {
srv := newServer()
started := time.Date(2026, 3, 24, 10, 0, 0, 0, time.UTC)
srv.tasks[taskKey("$3", "@12", "%7")] = &taskRecord{
SessionID: "$3",
SessionName: "workbench",
WindowID: "@12",
WindowName: "agent-tracker",
Pane: "%7",
Summary: "Polish notifications",
StartedAt: started,
Status: statusInProgress,
Acknowledged: true,
}
env := srv.buildStateEnvelope()
if env == nil {
t.Fatal("expected state envelope")
}
if len(env.Tasks) != 1 {
t.Fatalf("expected 1 task, got %d", len(env.Tasks))
}
task := env.Tasks[0]
if task.Session != "workbench" {
t.Fatalf("expected stored session name, got %q", task.Session)
}
if task.Window != "agent-tracker" {
t.Fatalf("expected stored window name, got %q", task.Window)
}
}