[FEATURE] Mods: let a plugin switch the terminal to another session (attach from a Pane button)

Status Open
Reported on v2.1.294
Maintainer reply None cached
Activity 0 comments · opened Oct 8, 2026

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, and SiteView.agentId is "the person's to switch, the plugin's to read", for in-process agents only.
  • $.command.run reaches no command that opens another session: /resume loads a conversation into this process, /background moves this one away, and the clickable name in /fork's confirmation is not available to plugins.
  • Button.action maps 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.open waits 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):

  • /background gives the conversation a new session id (the old transcript ends in a continued-in row), while claude --resume <id> --bg keeps 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).

View original on GitHub ↗