TermAl

Feature Brief: Concurrent Session Link Cards

Status

Exploratory. Codex subagent and parallel-agent messages are implemented as structured cards, but the explicit linked-session card workflow described here is still future design work.

Related:

This brief describes a message type that represents another agent session linked from the current conversation. The linked sessions remain fully disjoined; the card is purely a graphical representation, a UI convenience for keeping related work visible in one place.

Problem

TermAl already has first-class sessions, workspace tabs, and several message types for things that happen inside a session. What it does not have is a clean way for one conversation to say:

And no way for a user to say:

Today the closest fallback is plain assistant text, but that loses structure:

Core idea

Add a new message type that links to another real session.

The current conversation keeps a compact card pointing to the linked session. The linked session remains a normal first-class session with its own history, status, commands, diffs, approvals, and tabs. The two sessions are fully disjoined — they share no state and know nothing about each other. The card is purely a graphical shortcut.

This is a linked-session model, not a nested transcript model.

Three entry paths produce the same card:

  1. Spawn: an agent kicks off a new session from the current one. The card appears automatically so you can check back when the work is done.
  2. Drag in: drag an existing session from the session list (or another tab) into the current conversation. A link card is inserted so you can monitor that session’s progress without switching tabs.
  3. Prompt: the user types a TermAl-native /async command in the composer. TermAl creates a new linked session, starts it with the provided prompt, and inserts the card into the current conversation.

Conversation model

The linked session is a whole conversation, not a snippet. The two sessions are fully disjoined — there is no ownership relationship, no shared state, and no coupling beyond the card that references a sessionId.

That means:

Why linked sessions are the right shape

The card should not embed a copy of the linked session conversation.

If the full linked transcript is duplicated into the current conversation:

If the card only stores link metadata:

User experience

Automatic card (spawn flow)

When an agent starts concurrent work, the current session receives a compact message card automatically, for example:

The card should show:

Manual card (drag-in flow)

The user drags an existing session from the session list or another tab into the current conversation. A link card is inserted at the current scroll position. This lets the user assemble a single conversation view that tracks all the related work they care about.

The dragged session is not moved or modified — only a link card is created.

Prompt-created linked session (/async flow)

The composer should also be able to create a linked session directly.

Examples:

Recommended behavior:

Recommended v1 flags:

Recommended default if no agent flag is provided:

Open questions for later:

Linked session

The linked session is just a normal session:

Reading inline vs opening separately

This design supports both behaviors the user asked for:

The inline card should stay summary-only. Detailed reading belongs in the linked session itself.

Recommended inline summary sources, in order:

Proposed message type

Frontend:

type ConcurrentSessionMessage = BaseMessage & {
  type: "concurrentSession";
  sessionId: string;
  agent: AgentType;
  title: string;
  detail?: string | null;
  workdir: string;
  originMessageId?: string | null;
};

Backend:

Message::ConcurrentSession {
    id: String,
    timestamp: String,
    author: Author,
    session_id: String,
    agent: Agent,
    title: String,
    detail: Option<String>,
    workdir: String,
    origin_message_id: Option<String>,
}

Notes:

Rendering rules

The UI should resolve live state for the linked session from the global sessions array.

That means the card should:

Missing-session fallback:

This split should stay explicit:

Workspace behavior

The card should integrate with the current workspace model the same way any other session-opening action does.

Primary actions:

Because the linked target is already a real session, no special nested pane model is needed.

If a session is already open somewhere, Open session should prefer focusing the existing tab instead of creating duplicates.

Backend changes

Open question:

Recommended v1:

Recommended request shape for /async:

type CreateLinkedSessionRequest = {
  sourceSessionId: string;
  agent?: "claude" | "codex";
  prompt: string;
  model?: string;
  workdir?: string;
  title?: string;
};

This should be a TermAl-native path, not a message that gets passed through to the underlying agent runtime unchanged.

Frontend changes

Card behavior:

Minimal renderer inputs:

Use cases

Suggested UX copy

Examples:

Possible subcopy:

Non-goals for v1

Future extensions

Once the basic linked-session card exists, it can grow into richer coordination features:

  1. Add the new message type in backend and frontend types.
  2. Render a compact card that links to a real sessionId.
  3. Show live status and preview by looking up the referenced session.
  4. Add Open session and Open in new tab actions.
  5. Add backend support for creating a linked session from a parent in one call (spawn flow).
  6. Add drag-in support: drop a session from the session list or another tab into the current conversation to insert a link card (drag-in flow).
  7. Add a TermAl-native /async composer path for creating a linked session from a prompt, with --claude and --codex as the initial explicit switches.

That delivers the main value quickly without introducing duplicated transcript state or a more complex nested conversation model.