aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_pane_origin.py (follow)
Commit message (Collapse)AuthorAge
* Put a spawned pane beside US, not beside whoever is lookingblasty2026-09-29
The slosh backend worked out "where do I live" from `panes[].focused`. Exactly one pane in a session is focused, it is always in the tab currently on screen, and it belongs to whoever is looking -- so a TUI spawned "beside the agent" landed in whatever tab the human had wandered into, and in a session running several agents it was reliably a stranger's. `apply-layout` jumping the view to the tab it built made it self-inflicted too: one spawn moved the focus the next spawn would read. Identity now comes from four sources, in order, none of which is "whoever has focus": $IDATUI_SLOSH_PANE (an operator saying so), $SLOSH_PANE (slosh telling the pane's program which pane it is), our own /proc ancestry matched against panes[].pid (the answer for an agent's shell-out, which has neither a scrubbed environment nor a controlling tty), and a purpose named by $IDATUI_ORIGIN_PURPOSE / $SLOSH_PANE_PURPOSE. If none of them can answer, the pane stays in the tab the layout built it in -- visible, findable by purpose, and nobody else's tab -- and says so, since the fix is one variable in the caller's environment. The id-addressed verbs are probed, not assumed, and the probe is a field rather than a verb: slosh ignores arguments it does not know, so `raw` with an `id` on an older build answers ok and writes the bytes into whatever pane has focus -- silently, into somebody's shell. panes[].pid arrived with those verbs, so its presence is the capability. Where they exist: `raw id=` writes without touching focus, `capture id=` reads a pane in any tab without hopping the view (the old snapshot-and-slice route is kept as the fallback, and is rude precisely because it moves what other people are looking at), `apply-layout focus=false` builds the tab without jumping to it, and `move-pane beside=` names our pane rather than letting slosh pick that tab's focused one. Detached is now the default and `--focus` is the opt-in. The other way round, every spawn ended by pulling the session's focus -- and so the viewed tab -- to a pane nobody asked to look at: fine when a human typed the command and is waiting for it, wrong for an agent opening a binary while somebody works two tabs away. `--detached` still parses, for callers that say it. tests/test_pane_origin.py (22 checks, pure stdlib, no IDA and no slosh: the decisions are made about a `panes` reply, so the reply is the input) pins the precedence order, the focus-is-not-identity rule, the ancestry walk and that an unanswerable session leaves the pane where it was built.