# terminal — Manual

## What it does
Runs shell commands on the local machine (where Navi's server is running).

The tool supports **two modes**:
- **One-shot** (`run`) — execute a command and wait for the result. Classic behaviour.
- **Persistent session** (`open`/`close`/`list`/`status`/`send_input`) — create named terminal sessions that survive across tool calls. Use this for long-running processes (dev servers, build pipelines) or interactive workflows (programs that read stdin).

## Actions

### `run` — one-shot execution
Run a command and return the full output immediately.

**Parameters:**
- `action`: `"run"`
- `command` (string, required) — the shell command
- `working_dir` (string, optional) — directory to run in
- `timeout` (integer, optional, default 20, max 300) — seconds to wait

**Example:**
```json
{
  "action": "run",
  "command": "ls -la",
  "working_dir": "/home/gmikcon/Projects/navi-1"
}
```

### `open` — start a persistent terminal session
Create a named terminal that keeps running in the background.

**Parameters:**
- `action`: `"open"`
- `terminal_name` (string, required) — unique name for this terminal
- `description` (string, required) — why you opened it (shown in `list`)
- `command` (string, required) — the command to run
- `background` (boolean, optional, default false) — if true, returns immediately; if false, waits for completion but still creates a persistent session
- `working_dir` (string, optional)
- `timeout` (integer, optional)

**Example — background dev server:**
```json
{
  "action": "open",
  "terminal_name": "dev_server",
  "description": "Local HTTP dev server",
  "command": "python -m http.server 8765",
  "background": true
}
```

**Important:**
- `terminal_name` must be unique per Navi session. Opening with an existing name will fail.
- Maximum **10 active terminals per session**.
- Background terminals are **streamed live** — output appears in the UI as it is produced.
- Foreground (`background: false`) terminals automatically close after the command finishes.

### `close` — stop a persistent terminal
Kill the process and remove the session.

**Parameters:**
- `action`: `"close"`
- `terminal_name` (string, required)

### `list` — show active terminals
Returns all running/persistent terminals for the current Navi session with status (busy/idle), PID, and uptime.

**Parameters:**
- `action`: `"list"`

### `status` — detailed info about one terminal
Returns command, PID, CWD, uptime, and the last 20 lines of output.

**Parameters:**
- `action`: `"status"`
- `terminal_name` (string, required)

### `send_input` — write to a terminal's stdin
Send text to a background terminal that is waiting for input (e.g. `cat`, `python` REPL, `npm init`).

**Parameters:**
- `action`: `"send_input"`
- `terminal_name` (string, required)
- `input` (string, required) — text to send. Include `\n` for Enter.

**Example:**
```json
{
  "action": "send_input",
  "terminal_name": "interactive_python",
  "input": "print(2 + 2)\n"
}
```

## When to use persistent sessions instead of `run`

| Situation | Use |
|---|---|
| Single command with quick output | `run` |
| Long-running server or daemon | `open` with `background: true` |
| Interactive program needing stdin | `open` + `send_input` |
| Sequence of commands sharing state | Not yet supported (each `open` is a new shell). Use `run` with `;` or write a script. |

## Safety
- Non-admin users are restricted to a sandbox directory (`user_data/<user_id>/`) and a curated allowlist.
- Dangerous patterns (curl, wget, ssh, sudo, `python -c`, `node -e`, etc.) are blocked for non-admins.
- Admins bypass restrictions when `TERMINAL_ALLOWED_COMMANDS=*`.
- Timeout prevents runaway processes (`run` defaults to 20s; background terminals are cleaned up after 30 min of inactivity).
