SIGN IN SIGN UP

feat(relay): serve herdr's real workspace and tab hierarchy

`pane list` gives every pane a workspace_id and a tab_id, but only the ids -- so a client
that wanted the hierarchy had to reverse-derive it from the agents it could see. It could
name a space only after the basename of some pane's cwd, number tabs by the order agents
happened to appear in, and could not see a space at all unless an agent was sitting in it.
On this host that hides three workspaces outright and 17 of 26 panes.

Poll `workspace list` and `tab list` alongside it and send the result as `spaces` on the
`agents` message: the operator's own labels and numbering, which space and tab herdr itself
has focused, and the total pane count -- so a space holding only shell panes can say "3 panes
here, none running an agent" instead of being invisible. Two extra CLI calls per host against
a hierarchy that only moves when someone creates, closes, renames or focuses something, so
they run on their own slower cadence plus a forced refresh after any message that moves it,
and a failed read keeps the last good hierarchy rather than blanking every client.

With the hierarchy real, the actions that go with it work:

- `focus` moves herdr's own focus, choosing the CLI by which id the client sent, so a pane, a
  tab and a space all go through one message. Panes now report `focused`, since where the
  operator is standing was not visible from any client.
- `rename_tab` and `close_tab` were sent by the web client and handled by nobody.
- `rename_agent` asks `herdr agent rename` instead of typing `/rename <name>` at the pane,
  which claude has no command for: it landed in the composer as literal text.
- Ids are host-qualified. Every herdr numbers its own spaces w1, w2, ... so `create_tab` used
  to hand the CLI whatever a client sent, always against the local host; ids the relay has
  never listed are now refused, and an id two hosts share is refused rather than guessed.
- Labels bound for herdr's own UI go through `clean_label`, so a leading dash cannot arrive as
  a flag and a newline cannot be written into the tab strip.
N
Nick007 committed
d230b97e22a04fdf97723a1f4dd497b5f126e2fc
Parent: 40ce988