> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/agent-orchestrator/llms.txt
> Use this file to discover all available pages before exploring further.

# Terminal

> Plugin interface for terminal UI integrations (iTerm2, web) that manage how humans view and interact with running agent sessions

## Overview

The `Terminal` interface manages how humans view and interact with running sessions. Terminal plugins open IDE tabs, browser windows, or terminal sessions for direct agent interaction.

**Plugin Slot:** `terminal`\
**Default Plugin:** `iterm2`

## Interface Definition

```typescript theme={null}
export interface Terminal {
  readonly name: string;
  
  openSession(session: Session): Promise<void>;
  openAll(sessions: Session[]): Promise<void>;
  isSessionOpen?(session: Session): Promise<boolean>;
}
```

## Methods

<ResponseField name="name" type="string" required>
  Plugin name identifier (e.g. `"iterm2"`, `"web"`, `"none"`).
</ResponseField>

<ResponseField name="openSession" type="(session: Session) => Promise<void>" required>
  Open a session for human interaction.

  **Parameters:**

  * `session` - Session to open

  **Implementation:**

  * iTerm2: Create new tab with tmux attach command
  * Web: Open browser to web terminal URL
  * None: No-op (headless mode)
</ResponseField>

<ResponseField name="openAll" type="(sessions: Session[]) => Promise<void>" required>
  Open all sessions for a project.

  **Parameters:**

  * `sessions` - Array of sessions to open

  **Implementation:**

  * iTerm2: Create window with multiple tabs
  * Web: Open browser with multiple tabs
  * None: No-op
</ResponseField>

<ResponseField name="isSessionOpen" type="(session: Session) => Promise<boolean>">
  Optional: Check if a session is already open in a tab/window.

  **Parameters:**

  * `session` - Session to check

  **Returns:** true if session is open, false otherwise
</ResponseField>

## Usage Examples

### Implementing a Terminal Plugin (iTerm2)

```typescript theme={null}
import type { Terminal, Session } from "@composio/ao-core";
import { execFile } from "node:child_process";
import { promisify } from "node:util";

const execFileAsync = promisify(execFile);

export function create(): Terminal {
  return {
    name: "iterm2",
    
    async openSession(session: Session): Promise<void> {
      if (!session.runtimeHandle) {
        throw new Error("Cannot open session: no runtime handle");
      }
      
      const tmuxSession = session.runtimeHandle.id;
      
      // AppleScript to create iTerm2 tab with tmux attach
      const script = `
        tell application "iTerm"
          activate
          tell current window
            create tab with default profile
            tell current session
              write text "tmux attach -t ${tmuxSession}"
            end tell
          end tell
        end tell
      `;
      
      await execFileAsync("osascript", ["-e", script], { timeout: 5_000 });
    },
    
    async openAll(sessions: Session[]): Promise<void> {
      if (sessions.length === 0) return;
      
      // Create window with tabs for each session
      const tmuxSessions = sessions
        .map(s => s.runtimeHandle?.id)
        .filter(Boolean);
      
      if (tmuxSessions.length === 0) return;
      
      const script = `
        tell application "iTerm"
          activate
          create window with default profile
          tell current window
            ${tmuxSessions.map((id, i) => `
              ${i > 0 ? 'create tab with default profile' : ''}
              tell current session
                write text "tmux attach -t ${id}"
              end tell
            `).join('')}
          end tell
        end tell
      `;
      
      await execFileAsync("osascript", ["-e", script], { timeout: 10_000 });
    },
    
    async isSessionOpen(session: Session): Promise<boolean> {
      // Check if iTerm has a tab attached to this tmux session
      // This is complex - simplified implementation returns false
      return false;
    }
  };
}
```

### Implementing a Web Terminal Plugin

```typescript theme={null}
import type { Terminal, Session } from "@composio/ao-core";
import { execFile } from "node:child_process";
import { promisify } from "node:util";

const execFileAsync = promisify(execFile);

export function create(config: { baseUrl: string }): Terminal {
  return {
    name: "web",
    
    async openSession(session: Session): Promise<void> {
      const url = `${config.baseUrl}/terminal/${session.id}`;
      
      // Open in browser
      await execFileAsync("open", [url], { timeout: 5_000 });
    },
    
    async openAll(sessions: Session[]): Promise<void> {
      // Open browser with multiple tabs
      const urls = sessions.map(s => `${config.baseUrl}/terminal/${s.id}`);
      
      for (const url of urls) {
        await execFileAsync("open", [url], { timeout: 5_000 });
      }
    }
  };
}
```

### Using Terminal in CLI

```typescript theme={null}
import type { Terminal } from "@composio/ao-core";

const terminal: Terminal = registry.get("terminal", "iterm2");

// Open single session
await terminal.openSession(session);

// Open all sessions for project
const sessions = await sessionManager.list("my-app");
await terminal.openAll(sessions);
```

## Implementation Notes

### Runtime Integration

Terminal plugins should use `runtime.getAttachInfo()` to get connection details:

```typescript theme={null}
import type { AttachInfo } from "@composio/ao-core";

const runtime = registry.get("runtime", session.runtimeHandle!.runtimeName);
const attachInfo: AttachInfo | undefined = await runtime.getAttachInfo?.(session.runtimeHandle!);

if (attachInfo) {
  switch (attachInfo.type) {
    case "tmux":
      // Open iTerm2 tab with tmux attach
      break;
    case "docker":
      // Run docker exec in terminal
      break;
    case "web":
      // Open browser to URL
      break;
  }
}
```

### Platform Detection

Terminal plugins should check platform:

```typescript theme={null}
if (process.platform === "darwin") {
  // Use iTerm2 or Terminal.app
} else if (process.platform === "linux") {
  // Use gnome-terminal, konsole, or xterm
} else {
  // Fallback to web terminal
}
```

### Session Deduplication

The `isSessionOpen()` method helps avoid opening duplicate tabs:

```typescript theme={null}
if (terminal.isSessionOpen && await terminal.isSessionOpen(session)) {
  console.log("Session already open");
  return;
}

await terminal.openSession(session);
```

### Built-in Plugins

* **iterm2** - iTerm2 on macOS (default)
* **web** - Web-based terminal (browser)
* **none** - No-op for headless/CI environments

Future plugins could support:

* **terminal-app** - macOS Terminal.app
* **gnome-terminal** - GNOME Terminal on Linux
* **konsole** - KDE Konsole on Linux
* **vscode** - VS Code integrated terminal
* **warp** - Warp terminal

## See Also

* [Runtime](/api/runtime) - Runtime execution environment interface
* [Session](/api/session) - Session interface
* [Notifier](/api/notifier) - Notification interface


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.