SIGN IN SIGN UP

fix(web): the grouped list must not invent spaces, bury the ask, or rename a pane

Six defects in 037d5f2, four of them reproduced against real payloads.

spaceKey stringified a missing id into "local|undefined", which reads as a real
space to everything downstream: splitKey hands back the truthy "undefined",
render()'s `!k.endsWith('|')` guard passes it, and the Unsorted fallback is
unreachable. So a relay reporting no hierarchy at all -- demo-worker serves six
agents with no workspace_id across three hosts, and so does any relay older than
`spaces` -- got one fabricated group per host named after whichever project came
first, with the blocked agent buried as the third card. `${id || ''}` and the
guard works, the fallback is reachable, and such a relay falls back to the flat
status list it always had. A `blocked` push is the same shape (blocked_message
carries no workspace_id), so a pane pushed ahead of its first snapshot now lands
in an Unsorted group whose header is a heading rather than a button.

groupCards sorted by tab alone, so a blocked agent sat below any tabmate from an
earlier tab -- which made dropping the "Needs you" hoist a straight regression,
since the claim it rested on was that the first card IS the one asking. A blocked
pane now jumps its tab.

paneLabel dropped the operator's own `label` when it matched the heading, and the
pane id that replaced it went into data-agent-name -- so long-press, Rename,
Enter sent `rename_agent {label: "w6:pH"}` and overwrote the real herdr label on
every client. An operator label is never suppressed now, and data-agent-name
carries paneName (the real name) while the card shows the display string.

Switching pane from a sibling chip left the search open with the previous pane's
HTML in `originalContent`, so the next keystroke rendered pane A's output inside
pane B's session. openTerminal hides search alongside history on a real switch.

renderSiblings deduped by nothing, and paneById's own comment admits a pane can
briefly be in both arrays -- two chips for one pane. It also claimed `Tab` for
panes it had no tab ids to compare.

A workspace chip now shows herdr's own pane count whenever it exceeds what this
client can serve, not only when the space holds no agent: with HERDR_SHELL_PANES
off, a space of five panes drew one card and said nothing about the other four.

Two tests were wrong rather than the code. test_a_relay_with_no_hierarchy never
cleared `spaces`, so the path it was named for was never taken -- which is why
the demo regression shipped green; it now feeds the real demo payload. And the
terminals-never-in-an-agent-section invariant was never what groupCards
implements (a group is ordered by tab), only what the fixture happened to
satisfy; it now asserts what must hold, that no `panes` entry is drawn by
agentCard.
N
Nick007 committed
7d2c98827af0a650b9842e4f37732aa37628c1b3
Parent: f276fe1