refactor(review): consolidate one-row-per-agent collapse + drill-in polish · Entire
refactor(review): consolidate one-row-per-agent collapse + drill-in polish
d2707ba·
peyton-alt·3d ago·5 files·+282 added/-130 removed
Pre-merge cleanup of the agent-row collapse, which had accreted across three commits as scattered TUISink fields/methods. Same behavior, one owner, plus the two facets found by reading rather than design.
(c) New agentGrouping type owns the whole reconciliation between per-worker execution and one-row-per-agent display: worker->row routing, live per-agent token summing, and the summary fold. TUISink holds one *agentGrouping (nil on the single-agent path) instead of four fields and four methods.
(a) The folded summary's duration now spans earliest-worker-start to latest-worker-end instead of keeping one worker's slice. The live row duration was already correct (wall-clock from first event to finish); this makes the folded field honest for any future consumer.
(b) Drill-in (Ctrl+O) into a collapsed agent tags each event with its skill when the buffer holds more than one worker, so two skills running in parallel read cleanly instead of interleaving anonymously; single-source buffers stay untagged. agentEventMsg carries the source worker; the row buffer keeps it per event.
Execution, summary, manifest, and per-skill session attribution are untouched — the collapse remains display-only.
Sessions
01KXH6FFA9B5JWVHSRGMH1W20BView transcript
Changes
5
cmd/entire/cli/review
Aagent_grouping.go+143
Mtui_detail.go+40/-5
Mtui_model.go+12/-4
Mtui_sink.go+26/-118
Mtui_sink_test.go+61/-3
// Package review — see env.go for package-level rationale.
package review
import (
"time"
reviewtypes "github.com/entireio/cli/cmd/entire/cli/review/types"
)
type agentGrouping struct {
rowOrder []string // per-agent row labels, in display order
workerToAgent map[string]string // worker label → agent row
rowWorkers map[string][]string // agent row → its worker labels
workerTokens map[string]reviewtypes.Tokens
}
func newAgentGrouping(rowOrder []string, workerToAgent map[string]string) *agentGrouping {
g := &agentGrouping{...}
return g
}
// rowFor resolves a worker label to its agent row, passing through any name absent from the map.
func (g *agentGrouping) rowFor(name string) string {
if row, ok := g.workerToAgent[name]; ok {
return row
}
return name
}
// liveTokens records worker's latest cumulative Tokens...
func (g *agentGrouping) liveTokens(worker string, tk reviewtypes.Tokens) reviewtypes.Tokens {
...
}
// collapseSummary folds a per-worker summary into one AgentRun per agent row.
func (g *agentGrouping) collapseSummary(summary reviewtypes.RunSummary) reviewtypes.RunSummary {
...
}
// reviewStatusWorse reports whether a is a worse terminal status than b.
func reviewStatusWorse(a, b reviewtypes.AgentStatus) bool {
...
}
...
- Aagent_grouping.go+143
// buildEventLines returns every wrapped body line for the supplied event buffer, in order.
func buildEventLines(buffer []reviewtypes.Event, maxWidth int) []string {
...
}
// multiSource reports whether a buffer holds events from more than one distinct worker.
func multiSource(buffer []bufferedEvent) bool {
...
}
// skillTag reduces a worker label to its skill for drill-in tagging:
func skillTag(worker string) string {
...
}
// detailFrame renders the alt-screen drill-in chrome around a body string.
Mtui_detail.go+40/-5
Mtui_model.go+12/-4
Mtui_sink.go+26/-118
// TestTUISink_CollapsesSummaryToAgentRows tests that the TUISink can correctly collapse the summary. func TestTUISink_CollapsesSummaryToAgentRows(t *testing.T) { ... }
// TestAgentGrouping_CollapseAggregatesDurationSpan tests the aggregation of duration across collapsed runs. func TestAgentGrouping_CollapseAggregatesDurationSpan(t *testing.T) { ... }
// TestBuildEventLines_LabelsSkillWhenMultipleSources tests that events from multiple sources are correctly labeled. func TestBuildEventLines_LabelsSkillWhenMultipleSources(t *testing.T) { ... }