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