feat(coding-agent): agents-view usage columns, section legend, empty-session sort, zebra striping - #2056
Merged
Merged
Conversation
Optional background token for alternate agents-view rows. Unset or empty disables striping, so existing custom themes stay valid; built-in themes get subtle values.
…session sort, zebra rows - Row details become aligned columns: in/out tokens, own cost, total descendant count (explicit 0), recursive total, age. Empty sessions (no messages) keep only the age. - Descendant counts roll up through the same unfiltered enumeration as recursive costs (computeRecursiveCosts -> computeRecursiveRollups), so passive/saved children are counted for inactive sessions too. - Every section header shows its row count and a bold right-aligned usage legend. - Empty sessions sort last within their section, except the session the view was entered from, which keeps its recency slot. - Session rows zebra-stripe per top-level block, restarting at each section header; selection highlight takes precedence and the stripe uses the optional agentsZebraBg theme color.
…gents-view legend and rows Column width = max(widest row value in the section, legend label width); legend labels and row values are all right-aligned into those columns, so the ' . ' separators land in the same terminal column for the legend and every row. Widths are per section, so an expensive row widens only its own section, and empty sections show the legend at natural label widths.
…e of the real terminal background A theme stripe darker than the actual terminal background (or too close to it) rendered as black bands. When the terminal background is known, keep the configured stripe only if it sits on the contrast side with a minimal delta; otherwise re-derive a subtle stripe from the terminal background, like the popup surfaces do.
…ading ellipsis The prepended ellipsis consumed a viewport line without shifting the content window, so a selection at the very end of the agents list was sliced out of view. Pre-existing on main; surfaced by review on #2056.
…ssion lineage Branch/fork headers point parentSession at the source while keeping the source's rlmDepth, so the rollup walk counted a branched chat as a descendant and double-booked its copied-transcript cost. Count a child only when it is a subagent by runtimeKind (resident) or deeper rlmDepth (saved).
…alue Quantization can collapse the configured stripe onto the terminal background's own palette cell (e.g. #202020 and #1c1c1c both map to cell 234), so the keep/re-derive decision now uses the rendered bestAnsiColor value like the selection color path does.
The stripe conflicts visually with the selection highlight. Removes the zebra rendering, the agentsZebraBg theme token, and the adaptive-stripe contrast logic with its pins; history and the PR discussion preserve the adaptive-contrast approach if striping is ever revived. Columns, legend, sort anchor, and viewport fixes stay.
Contributor
Author
|
Fresh-eyes review follow-ups:
|
…usage-legend-zebra
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 42ee2eb. Configure here.
…in the agents view The rollup walk already excluded branch/fork lineage from #sub and $total, but the tree still nested any saved child with parentSessionPath and the expander counted it, so a source could show '1 subagent' next to #sub 0. The nesting decision now shares the rollup's subagent-lineage predicate: a branched/forked session renders as its own top-level row, matching how the daemon reports resident forks (runtimeKind top-level).
xeophon
approved these changes
Sep 5, 2026
This was referenced Sep 5, 2026
snimu
added a commit
that referenced
this pull request
Sep 7, 2026
Brings back the #2056 row format that #2087's consolidation replaced: per-row 'in/out tokens · own cost · descendant count · recursive total · age' with one shared column layout per section (column width = max of the widest section value and the legend label, all right-aligned) and the bold usage legend right-aligned on every section header. The redesign's other features stay: the Model column (compact ids) sits between the session title and the usage cell, Activity still shrinks first at narrow widths, expandable child sessions, the running-subagents line, and the actions panel are untouched. Usage cells right-align to the terminal edge, so age columns line up across sections even when a wide row widens only its own section. Fixes RES-1317.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes RES-1277
Purpose
Make agents-view rows scannable at fleet scale: every session shows the same aligned usage columns (
↑in ↓out · $agent · #sub · $total · age) under a bold per-section legend that shares the exact column layout with the rows, and empty sessions stop crowding the top of their section (except the one the view was entered from).Changes
↑in ↓out · $agent · #sub · $total · ageper row, replacing↑in ↓out · $agent ($total w/ subagents) · age.#subis the TOTAL descendant count (resident + passive) from the same unfiltered enumeration that computes the recursive cost (computeRecursiveCosts->computeRecursiveRollups), shown as an explicit0. The rollup walk follows agent lineage only: branched/forked sessions (parentSession with the source's rlmDepth) no longer count as descendants or double-book their copied-transcript cost. Empty sessions (no messages) render no usage segment at all but keep the age, aligned to the age column. Empty detection reuses the scan's message-count rule (messageCount === 0);TODO(unify: #2055)marks it for the shared user-content rule.Running (n)/Idle (n)/Inactive (n)) carries the legend right-aligned in the header line, bold like the title — including the search-empty header (dropped when the terminal is too narrow). Legend and rows render through ONE shared column layout per section: column width = max(widest row value in that section, label width), everything right-aligned, so the·separators land in the same terminal column for the legend and every row. Widths are per section (an expensive row widens only its own section); empty sections show the legend at natural label widths.backSession/initialSessionsession id, not the selected row), which keeps its normal recency position.Zebra striping was implemented, then removed at user request (conflicts visually with the selection highlight); commits f63590b/c67649271 and the review threads preserve the adaptive-contrast approach if it is ever revived (removed in 9b5c4a2).
Screenshot
BEFORE:
AFTER:
Tests
computeRecursiveRollupspins descendant counting through the passive/saved walk (parent keeps count when a child survives only as a catalog row) and pins that branched-session lineage never inflates#sub/$totalwhile a spawned child counts.0, separator-column equality between legend and every row of a section (fails without the shared layout), and the empty-session age-only cell (merged into the existing usage-cell test); 502 regression regex updated to the new format.LOC
Total src: +212/-36 (net +176); tests: +221/-16 (net +205).
Validation
npm run checkgreen per commit (pre-commit hook: biome, tsgo, installer, browser smoke).--exclude test/daemon-supervisor-process.test.ts): 14 failed files / 82 failed tests, exactly the documented environmental baseline set (extensions-, kernel--skill bridges, tools EACCES-as-root, config, resource-loader, sdk-session-manager, agent-session-recursion, 4428, 4603) — no new failures.Note
Medium Risk
Changes recursive cost/descendant rollup and parent-child classification (fork vs subagent), which affects displayed totals and hierarchy; UI-only but easy to misread if lineage edge cases remain.
Overview
Agents view session rows now use a shared, right-aligned usage strip (
↑in ↓out · $agent · #sub · $total · age) instead of the old parenthetical “w/ subagents” string.buildAgentsViewUsageLayoutcomputes one column width per section so section headers and every row line up; headers showRunning|Idle|Inactive (n)plus a bold legend on the same grid (dropped when the terminal is too narrow). Empty sessions (messageCount === 0) show age only in that grid; everyone else gets the full strip with an explicit#sub.Rollups and tree shape:
computeRecursiveCostsbecomescomputeRecursiveRollups, addingdescendantCountfor#subwhile keeping filter-independent totals. Branched/forked sessions (same **rlmDepthas parent) no longer nest, count as descendants, or inflate$total.anchorSessionId(session you opened agents view from) keeps empty chats in normal sort order; other empty sessions sort to the bottom of their section.Viewport: when a leading
...ellipsis is shown, the visible slice shifts so a selection on the last row is not clipped off-screen.Reviewed by Cursor Bugbot for commit 4831d2b. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add aligned usage columns, section legends, and empty-session ordering to agents-view
computeRecursiveCostexport removed from index.ts; callers must usecomputeRecursiveRollupsinsteadMacroscope summarized 4831d2b.