- Manage interactive and persistent terminals (REPLs, prompts, dev servers, watchers)
- Returns terminal information and output
- Supports creating, reading, writing, listing, and killing terminals

## Operations

### start
- Spawns a new persistent terminal (interactive shell by default)
- Returns terminal ID for future operations
- Use for commands that need stdin, a TTY, interactive input, or persistence across turns
- Before starting, call `terminal(operation: "list")` to see if a matching service is already running
- Provide a clear `purpose` or `title` (e.g. "web dev server port 9100") so humans can recognize it
- Parameters:
  - command (optional when `shell` is true): Command to run
  - purpose (required): Description of what this terminal is for
  - title (optional): Short UI label shown beside the terminal
  - cwd (optional): Working directory relative to project root (default: '.')
  - args (optional): Array of command arguments
  - shell (optional, default: true): Launch an interactive shell and run the command via stdin. Set to `false` to spawn the process directly.

### read
- Read output from a terminal's buffer (last N lines)
- Strips ANSI escape codes by default so responses are easy to read
- Parameters:
  - terminalId (required): Terminal ID from start operation
  - lines (optional): Number of lines to read from end (default: 100)
  - raw (optional): Include `rawOutput` array with ANSI escape sequences (default: false)
- Returns sanitized output lines, combined `text`, status, and exit code

### write
- Write input to a terminal's stdin
- Useful for interactive commands or sending signals
- Parameters:
  - terminalId (required): Terminal ID
  - input (required): String to write to stdin

### interrupt
- Sends SIGINT (Ctrl+C) to the terminal without closing the PTY
- Useful for stopping dev servers or watchers while keeping the shell alive
- Parameters:
  - terminalId (required): Terminal ID

### list
- List all active terminals
- Returns array of terminal metadata (id, purpose, status, pid, uptime)
- No parameters required

### kill
- Kill a running terminal
- Sends SIGTERM by default
- Parameters:
  - terminalId (required): Terminal ID to kill

## When to Use Terminal vs Shell

### Use terminal for:
- Interactive commands that need stdin or a TTY: REPLs, prompts, shells, debuggers
- Dev servers: npm run dev, bun dev
- File watchers: bun test --watch, nodemon
- Build watchers: bun build --watch
- Log tailing: tail -f logs/app.log
- Background services: docker compose up
- Any process that needs to stay alive and produce continuous output
- Any process you need to read from or write to across turns

### Use shell for:
- Status checks: git status, ls, ps
- One-off commands: mkdir, rm, curl
- Quick scripts: bun run build, git commit
- File operations: cat, sed, awk
- Non-interactive long-running commands that finish on their own (set an appropriate timeout)
- Any command that does not need stdin, a TTY, or follow-up interaction

## Example Workflow

1. Start dev server:
   terminal(operation: "start", command: "npm", args: ["run", "dev"], purpose: "dev server")
   → Returns { terminalId: "term-abc123", pid: 12345 }

2. Later, check for errors:
   terminal(operation: "read", terminalId: "term-abc123", lines: 50)
   → Returns last 50 lines of output

3. Kill when done:
   terminal(operation: "kill", terminalId: "term-abc123")

## Notes

- Terminals persist across multiple LLM turns (unlike shell commands)
- Maximum 10 terminals per session
- Exited terminals auto-cleanup after 5 minutes
- Output is buffered (last 500 lines kept)
- Both user-created and LLM-created terminals are visible
- You can read from user-created terminals to understand context
- Prefer `read` over `start` when you only need status — avoid duplicating services that already exist
- Mention running terminals (purpose, command, port) in your responses so humans know what is active
