You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Spaces panel has structure: worktrees nest under their repo, and groups can be
collapsed. The Agents panel is flat — every agent is a sibling, no matter how many
there are or how they relate to each other.
I'd like to ask for grouping as a generic capability in the Agents panel, not a
specific grouping rule. What people want to group by varies a lot, so the useful
thing to ship is the mechanism, and let the grouping key come from the user.
Why this can't be done today
agent.view.set is close, but stops one step short. It gives me:
filter — hide rows by a predicate over built-ins or custom $tokens
sort — order rows by a token, then pane order
There's no group dimension. So the best a plugin can do is simulate grouping:
sort by a synthetic ordering token, write tree-drawing characters into another token
to fake indentation, and filter out the rows that should be "collapsed". That's what
I ended up doing, and it has real limits:
no group headers, and no count of what's hidden unless I render it into a token myself
collapse/expand is a global mode toggle, not per-group — there's no per-row
disclosure state to hook into
indentation has to be baked into a token's value; leading whitespace in token
values gets trimmed, so it can only be done with box-drawing glyphs
every change means rewriting metadata tokens on every pane and re-issuing the view
None of this is reachable from config either — [ui.sidebar.agents] rows controls
which tokens appear in a row and how they're styled, but not how rows relate to each
other.
What a generic version might look like
Something like a group field on the view, keyed the same way sort already is:
and rows carrying that token get gathered under a collapsible header. Whether the
header text is the token value, whether groups can nest, and whether collapse state
lives in herdr or is reported back — all open questions I'd defer to you.
Example use cases
Just to show the range — these are all the same mechanism with a different key:
group by who spawned what, so orchestrator-launched sub-agents collapse under
their parent instead of flooding the panel (this is my case; adjacent to Sub-agent management and visibility? #1274,
which asks for visibility into a CLI's internal subagents — different problem,
same underlying wish for structure)
group by kind of work — reviewers vs. implementers vs. long-running watchers
group by repo or team, when one screen spans several projects
group by model or cost tier, to see at a glance what's running something expensive
Related but distinct: #1406 asks for per-space filtering of this panel and #944 asked
for configurable rows (shipped). #1620 asks for hierarchical groups on the Spaces
side. This is the Agents-side structural counterpart.
Questions
Is grouping in the Agents panel something you'd want at all, or is a flat panel a
deliberate design choice?
If yes — does extending agent.view.set with a group field fit how you think
about that API, or would you rather it be config-driven?
Should collapse state be owned by herdr, or reported by whoever set the view?
I built the specific version of this and have been running it for about ten days, so some notes from that in case they're useful to your open questions.
I went with parent-based nesting rather than a general group key: an agent declares its owner with a parent=<pane_id> metadata token, and if there's no token it falls back to whichever pane asked the server to create it. Rows nest into collapsible subtrees, orphans and cycles fall back to flat rows, and the whole thing is behind an experimental flag that's off by default.
None of it is tied to any particular CLI. Herdr only reads a metadata token and a creation record, so any agent or tooling that can set a token, or that opens panes over the socket API, gets nested for free. The screenshot below happens to be pi, but claude, codex or anything else nests the same way.
The one thing I'd flag for your generic version: a token-keyed group handles attributes well (team, model, kind of work) but a parent is an edge, not an attribute. Grouping by a parent token would give flat buckets keyed on a pane id rather than a tree, and it can't recurse. So I think the two are complementary rather than one subsuming the other, and it might be worth deciding up front whether nesting is in scope for group or a separate thing.
Three things that turned out to matter more than I expected:
Lineage needs plumbing. Panes are created over the socket API and the caller's identity wasn't carried through, so I had to add an optional caller_pane_id to the creation params. Additive, absent means none, no protocol version bump. Human splits send no caller, so they never auto-parent.
Nesting has to be scoped to the pane's own tab. I hit a real bug where my own tooling rewrote a parent id when it took over a worker from a session that had ended, and an agent from one tab showed up inside a tree in another.
The relationship has to persist or the trees die on restart. I ended up storing the creator in the pane snapshot and doing an id remap pass on restore.
On your third question, I put collapse state on the client side and it's caused no problems, since it's presentation rather than a runtime fact.
Here's what it looks like in the sidebar:
1 - The collapsible/expandable parent row, just like spaces -> worktrees.
2 - Each subagent with metadata.
Not trying to get ahead of you here, this is your thread. Happy to share the branch if any of it is useful.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
The Spaces panel has structure: worktrees nest under their repo, and groups can be
collapsed. The Agents panel is flat — every agent is a sibling, no matter how many
there are or how they relate to each other.
I'd like to ask for grouping as a generic capability in the Agents panel, not a
specific grouping rule. What people want to group by varies a lot, so the useful
thing to ship is the mechanism, and let the grouping key come from the user.
Why this can't be done today
agent.view.setis close, but stops one step short. It gives me:filter— hide rows by a predicate over built-ins or custom$tokenssort— order rows by a token, then pane orderThere's no
groupdimension. So the best a plugin can do is simulate grouping:sort by a synthetic ordering token, write tree-drawing characters into another token
to fake indentation, and filter out the rows that should be "collapsed". That's what
I ended up doing, and it has real limits:
disclosure state to hook into
values gets trimmed, so it can only be done with box-drawing glyphs
None of this is reachable from config either —
[ui.sidebar.agents] rowscontrolswhich tokens appear in a row and how they're styled, but not how rows relate to each
other.
What a generic version might look like
Something like a
groupfield on the view, keyed the same waysortalready is:{ "source": "my-plugin", "group": { "field": { "token": "team" } }, // or a built-in: workspace, agent, ... "sort": [{ "field": "pane_order" }] }and rows carrying that token get gathered under a collapsible header. Whether the
header text is the token value, whether groups can nest, and whether collapse state
lives in herdr or is reported back — all open questions I'd defer to you.
Example use cases
Just to show the range — these are all the same mechanism with a different key:
their parent instead of flooding the panel (this is my case; adjacent to Sub-agent management and visibility? #1274,
which asks for visibility into a CLI's internal subagents — different problem,
same underlying wish for structure)
Related but distinct: #1406 asks for per-space filtering of this panel and #944 asked
for configurable rows (shipped). #1620 asks for hierarchical groups on the Spaces
side. This is the Agents-side structural counterpart.
Questions
deliberate design choice?
agent.view.setwith agroupfield fit how you thinkabout that API, or would you rather it be config-driven?
Happy to work on it if the direction is welcome.
Environment: herdr 0.7.5, Linux.
All reactions