Skip to content

Show the agent product as a table column, detail line, and search field - #70

Merged
ndr-ds merged 1 commit into
mainfrom
ndr-ds/agentctl-provider-column
Aug 24, 2026
Merged

ndr-ds merged 1 commit into
mainfrom
ndr-ds/agentctl-provider-column

Conversation

@ndr-ds

@ndr-ds ndr-ds commented Aug 24, 2026

Copy link
Copy Markdown

Task 4 of the multi-provider plan: the product a session belongs to is now visible — an Agent column between PID and Name, a line in the detail panel, and a searchable field.

Done test-first, and the tests are proven

Written before the column existed, and confirmed red for the right reasons:

test the_agent_column_sits_between_pid_and_name ... FAILED
  Agent belongs between PID and Name, got ["PID", "Name", "Project", …]
test sort_arrow_lands_on_the_column_it_names ... FAILED
  sort column 0 claims header 4, which is "Context", not "Status"

Then green. Each new test was also re-run against the specific bug it guards, so none of them passes by construction — see below.

The hazard this column walks into

src/ui/table.rs already carried a warning:

ORIGIN is last deliberately: sort_header_idx below maps sort columns to header positions by hand, so inserting mid-table would silently mis-point the sort arrow.

This task inserts at position 1, which shifts all seven mappings. Getting it wrong moves the sort arrow one column over with no error.

Rather than shift the literals and hope, sort_header_idx is extracted from render into a function, and sort_arrow_lands_on_the_column_it_names asserts — for every entry in SORT_COLUMNS — that the mapped header's name matches the sort column's name. The map can no longer rot silently.

Proven by re-introducing the realistic mistake, adding the column but leaving the map un-shifted:

test sort_arrow_lands_on_the_column_it_names ... FAILED
  sort column 0 claims header 3, which is "Project", not "Status"

no_two_sort_columns_share_a_header covers the other direction, a duplicated slot.

Search

provider.label() joins the searched fields, so /codex filters to Codex sessions. Verified by discrimination rather than a bare assertion: every fixture session is Claude, so claude must match all of them and codex none. Removing the field from the search set fails it.

Row-cell counts

The same comment notes ratatui "silently renders a short row rather than failing". Both explicit Row::new builders were counted against HEADER_NAMES after the change — 15 and 15, matching. The group-header and parked-separator rows pad to HEADER_NAMES.len() and needed no change.

A subagent row leaves Agent blank: it runs inside its parent, so repeating the product on every child line is noise, consistent with how Origin is already handled.

Verification

cargo fmt --check and cargo clippy --all-targets -- -D warnings clean. 754 lib tests pass, including 4 new ones.

perf_do_refresh_io_does_not_explode_with_repeated_calls fails on a loaded box and passes in isolation; it is a wall-clock assertion and predates this branch.

Keyboard behaviour, layout priorities and sort semantics are untouched — the only width change is a fixed Length(7) for the new column, sized to fit Claude.

@ndr-ds
ndr-ds marked this pull request as ready for review August 24, 2026 17:28
@ndr-ds
ndr-ds merged commit 2715349 into main Aug 24, 2026
5 checks passed
@ndr-ds
ndr-ds deleted the ndr-ds/agentctl-provider-column branch August 24, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant