feat: session busy indicator — daemon tracks mid-turn state (agent_start/settled), busy field on session rows + live broadcast; pulsing pip in sidebar and cards (265 web tests, daemon 95.4%)
This commit is contained in:
@@ -714,3 +714,34 @@ func TestWebResubscribeSplitsEventBatches(t *testing.T) {
|
||||
_ = agent2.WriteJSON(map[string]any{"v": 1, "type": evMessageUpdate, "sessionId": "s2", "seq": 1, "ts": 11, "delta": "two"})
|
||||
readBatch("s2") // event B must arrive as its own frame, never mixed with A's
|
||||
}
|
||||
|
||||
func TestHubBusyFlagLifecycle(t *testing.T) {
|
||||
ts, _, hub := newTestServerHub(t)
|
||||
ws := dialAgent(t, ts)
|
||||
defer ws.Close()
|
||||
_ = ws.WriteJSON(helloFrame("busy-1"))
|
||||
_ = readFrame(t, ws)
|
||||
sendEv := func(typ string, seq int64) {
|
||||
_ = ws.WriteJSON(map[string]any{
|
||||
"v": 1, "sessionId": "busy-1", "seq": seq, "ts": 1, "type": typ,
|
||||
})
|
||||
}
|
||||
sendEv("agent_start", 1)
|
||||
waitFor(t, 3*time.Second, func() bool {
|
||||
for _, s := range hub.SessionsView() {
|
||||
if s.ID == "busy-1" {
|
||||
return s.Busy
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
sendEv("agent_settled", 2)
|
||||
waitFor(t, 3*time.Second, func() bool {
|
||||
for _, s := range hub.SessionsView() {
|
||||
if s.ID == "busy-1" {
|
||||
return !s.Busy
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user