TUI: Closed column, legacy 30m stale window, filtered-view fix, header shown-count, toggle tests
This commit is contained in:
73
state.go
73
state.go
@@ -12,34 +12,34 @@ import (
|
||||
|
||||
// AgentState matches the TypeScript interface from dashboard.ts
|
||||
type AgentState struct {
|
||||
Session string `json:"session"`
|
||||
Machine string `json:"machine"`
|
||||
Cwd string `json:"cwd"`
|
||||
AgentType string `json:"agent_type"`
|
||||
Model string `json:"model"`
|
||||
AgentStatus string `json:"agent_status"`
|
||||
Status string `json:"status"` // legacy alias of agent_status
|
||||
SessionState string `json:"session_state"`
|
||||
SessionStartedAt *string `json:"session_started_at"`
|
||||
ClosedAt *string `json:"closed_at"`
|
||||
LastSeenAt *string `json:"last_seen_at"`
|
||||
StartedAt *string `json:"started_at"`
|
||||
CompletedAt *string `json:"completed_at"`
|
||||
DurationSeconds int `json:"duration_seconds"`
|
||||
ToolCalls int `json:"tool_calls"`
|
||||
CurrentTask string `json:"current_task"`
|
||||
LastTool *string `json:"last_tool"`
|
||||
LastToolAt *string `json:"last_tool_at"`
|
||||
TerminalType string `json:"terminal_type"`
|
||||
ZellijSession string `json:"zellij_session"`
|
||||
TmuxSession string `json:"tmux_session"`
|
||||
PID int `json:"pid"`
|
||||
IsSubagent bool `json:"is_subagent"`
|
||||
ConnectionType string `json:"connection_type"`
|
||||
ConnectionName string `json:"connection_name"`
|
||||
Blocked bool `json:"blocked"`
|
||||
BlockedPrompt *string `json:"blocked_prompt"`
|
||||
CostEstimate float64 `json:"cost_estimate"`
|
||||
Session string `json:"session"`
|
||||
Machine string `json:"machine"`
|
||||
Cwd string `json:"cwd"`
|
||||
AgentType string `json:"agent_type"`
|
||||
Model string `json:"model"`
|
||||
AgentStatus string `json:"agent_status"`
|
||||
Status string `json:"status"` // legacy alias of agent_status
|
||||
SessionState string `json:"session_state"`
|
||||
SessionStartedAt *string `json:"session_started_at"`
|
||||
ClosedAt *string `json:"closed_at"`
|
||||
LastSeenAt *string `json:"last_seen_at"`
|
||||
StartedAt *string `json:"started_at"`
|
||||
CompletedAt *string `json:"completed_at"`
|
||||
DurationSeconds int `json:"duration_seconds"`
|
||||
ToolCalls int `json:"tool_calls"`
|
||||
CurrentTask string `json:"current_task"`
|
||||
LastTool *string `json:"last_tool"`
|
||||
LastToolAt *string `json:"last_tool_at"`
|
||||
TerminalType string `json:"terminal_type"`
|
||||
ZellijSession string `json:"zellij_session"`
|
||||
TmuxSession string `json:"tmux_session"`
|
||||
PID int `json:"pid"`
|
||||
IsSubagent bool `json:"is_subagent"`
|
||||
ConnectionType string `json:"connection_type"`
|
||||
ConnectionName string `json:"connection_name"`
|
||||
Blocked bool `json:"blocked"`
|
||||
BlockedPrompt *string `json:"blocked_prompt"`
|
||||
CostEstimate float64 `json:"cost_estimate"`
|
||||
}
|
||||
|
||||
// agentStatus returns the agent-turn status, falling back to the legacy
|
||||
@@ -51,6 +51,17 @@ func (a AgentState) agentStatus() string {
|
||||
return a.Status
|
||||
}
|
||||
|
||||
// legacyStale is the staleness window applied to legacy state files (written
|
||||
// by the pre-heartbeat extension). Those files are only rewritten on events,
|
||||
// so an idle-but-alive session can go minutes without a write — be generous.
|
||||
const legacyStale = 30 * time.Minute
|
||||
|
||||
// isLegacy reports whether the state file predates the heartbeat extension
|
||||
// (new files always carry pid + session_state; legacy ones have neither).
|
||||
func (a AgentState) isLegacy() bool {
|
||||
return a.PID == 0 && a.SessionState == ""
|
||||
}
|
||||
|
||||
// IsClosed reports whether the session is no longer alive:
|
||||
// - the extension marked it closed (session_state == "closed"), or
|
||||
// - the heartbeat (last_seen_at) is older than staleAfter (killed
|
||||
@@ -68,7 +79,11 @@ func (a AgentState) IsClosed(staleAfter time.Duration) bool {
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
return time.Since(t) > staleAfter
|
||||
window := staleAfter
|
||||
if a.isLegacy() {
|
||||
window = legacyStale
|
||||
}
|
||||
return time.Since(t) > window
|
||||
}
|
||||
|
||||
// WasKilled is true when the session died without a graceful shutdown
|
||||
|
||||
Reference in New Issue
Block a user