[FEATURE] Mods: let a plugin switch the terminal to another session (attach from a Pane button)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
I run several long-lived sessions at once: one or two orchestrator sessions that plan and supervise work, and background sessions (claude --bg) that implement it. A mod pane in each orchestrator already lists them (from claude agents --json) with their state. What I can't do is open one of them from that pane: a click on a session's name should show that session in this terminal, fully interactive, the way Enter does on a row of agent view.
On 2.1.294 nothing in the plugin API does it:
$.session.messages()reads only this session's own agents, andSiteView.agentIdis "the person's to switch, the plugin's to read", for in-process agents only.$.command.runreaches no command that opens another session:/resumeloads a conversation into this process,/backgroundmoves this one away, and the clickable name in/fork's confirmation is not available to plugins.Button.actionmaps a key to a button, not a button to an engine action.$.session.send({ to: { sessionId } })can talk to the session, but not show it.
Agent view does the switching, but it lists every session on the machine, and the switch happens there, not from the UI that knows which sessions matter.
Proposed Solution
A plugin call that switches the terminal to another session, the same thing Enter on a row does in agent view, for example:
await $.session.open({ sessionId }) // or the short id `claude attach` takes
- From an attached background session, it detaches the current one and attaches the target in place.
- From a foreground interactive session, it backgrounds it first, as
←does. - A stopped background session is started, as attaching it does today.
- It resolves with a reason when the target can't be opened (for example, an interactive session open in another terminal).
- It runs only in answer to the person (a press or a command), like an unrequested
$.ui.openwaits today.
Alternative Solutions
A workaround we measured on Windows (2.1.294, Windows Terminal, fullscreen): a wrapper process owns the terminal and runs claude attach <id>; on click, the mod writes the target to a file; the wrapper injects Ctrl+Z into its console with WriteConsoleInput, which drops back to it, and attaches the target. It works: 10 of 10 switches in about 0.4 s, a clean screen, dialogs fine, and a stopped session revives on attach. But the terminal has to start from a script, it relies on console key injection, and it has to follow how Claude Code was installed and updated. It is not something to roll out to a team.
Agent view with the n: filter is the other option, but it still lists everything and adds the list step to every switch.
Priority
Medium - Would be very helpful
Feature Category
Interactive mode (TUI)
Use Case Example
A campaign panel (a mod) shows each campaign with its orchestrator session and its worker sessions. Clicking a campaign's title opens its orchestrator in this terminal; clicking a worker asks for confirmation and opens it. One terminal, no list in between, and the same panel inside every session.
Additional Context
Related: #99615 (mods outside a chat session), #97746 (agent view: reply to several sessions), #91870 (mods).
Two observations from the same test (2.1.294, Windows 11):
/backgroundgives the conversation a new session id (the old transcript ends in acontinued-inrow), whileclaude --resume <id> --bgkeeps it. Anything keyed by session id breaks after/background.- A stopped background session is not reachable by
SendMessage("No agent named ... is reachable"). A plugin that needs a session to stay reachable has no way to pin it outside agent view (Ctrl+T).