> ## Documentation Index
> Fetch the complete documentation index at: https://docs.novita.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# PTY

A PTY (pseudo-terminal) is a virtual terminal interface that lets programs interact with a shell as if connected to a real terminal. Use the `sandbox.pty` module to create interactive terminal sessions that run commands, accept input, and can be resized while running — useful for REPLs and debuggers, interactive CLIs that prompt for input, and long-running processes you need to monitor.

> [!NOTE]
>
> **Note:** A PTY is identified by its process ID (`pid`), returned from `create()` on the handle. Pass that `pid` to send input, resize, connect, and kill. Output is delivered to a callback as raw bytes.

| Operation | JavaScript / TypeScript | Python |
| - | - | - |
| Create | `sandbox.pty.create(opts)` | `sandbox.pty.create(size, ...)` |
| Connect | `sandbox.pty.connect(pid, opts?)` | `sandbox.pty.connect(pid, ...)` |
| Send input | `sandbox.pty.sendInput(pid, data)` | `sandbox.pty.send_stdin(pid, data)` |
| Resize | `sandbox.pty.resize(pid, size)` | `sandbox.pty.resize(pid, size)` |
| Kill | `sandbox.pty.kill(pid)` | `sandbox.pty.kill(pid)` |

***

## Create a PTY

Create a PTY and receive its output through a callback. It returns a handle whose `pid` identifies the PTY.

| Option | Type | Description |
| - | - | - |
| `cols` / `rows` | number | Terminal dimensions (Python: `PtySize(cols=…, rows=…)`) |
| `onData` (JS) | (data: Uint8Array) => void | Callback for PTY output. Python delivers output via `wait(on_pty=...)` |
| `user` | string (optional) | User to run the PTY as |
| `cwd` | string (optional) | Working directory |
| `envs` | object / dict (optional) | Environment variables (`TERM`, `LANG`, `LC_ALL` are defaulted) |
| `timeoutMs` / `timeout` | number (default 60000 ms / 60 s) | PTY timeout; JS uses ms, Python uses seconds |

```js JavaScript & TypeScript icon="js" theme={"system"}
import { Novita } from 'novita-sandbox'

const novita = new Novita()
const sandbox = await novita.sandbox.create()

const pty = await sandbox.pty.create({
  cols: 120,
  rows: 30,
  cwd: '/home/user',
  envs: { TERM: 'xterm-256color' },
  onData: (data) => {
    process.stdout.write(new TextDecoder().decode(data))
  },
})

console.log('PTY pid:', pty.pid)
```

```python Python icon="python" theme={"system"}
from novita_sandbox import Novita
from novita_sandbox.core.sandbox.commands.command_handle import PtySize

novita = Novita()
sandbox = novita.sandbox.create()

def on_pty(data: bytes):
    print(data.decode('utf-8', errors='replace'), end='')

# PtySize takes keyword args cols / rows
pty = sandbox.pty.create(PtySize(cols=120, rows=30), cwd='/home/user', envs={'TERM': 'xterm-256color'})
print('PTY pid:', pty.pid)
```

***

## Send input

Send input to a running PTY by its `pid`. The data is raw bytes.

```js JavaScript & TypeScript icon="js" theme={"system"}
const enc = new TextEncoder()
await sandbox.pty.sendInput(pty.pid, enc.encode('echo hello\n'))
await sandbox.pty.sendInput(pty.pid, enc.encode('exit\n'))
```

```python Python icon="python" theme={"system"}
sandbox.pty.send_stdin(pty.pid, b'echo hello\n')
sandbox.pty.send_stdin(pty.pid, b'exit\n')
```

***

## Resize a PTY

Call `resize` when the terminal window changes size.

```js JavaScript & TypeScript icon="js" theme={"system"}
await sandbox.pty.resize(pty.pid, { cols: 150, rows: 40 })
```

```python Python icon="python" theme={"system"}
sandbox.pty.resize(pty.pid, PtySize(cols=150, rows=40))
```

***

## Connect to a running PTY

Connect to a PTY that is already running by its `pid`. You can obtain running processes with `sandbox.commands.list()`. The returned handle receives further output through the callback.

```js JavaScript & TypeScript icon="js" theme={"system"}
const handle = await sandbox.pty.connect(pty.pid, {
  onData: (data) => process.stdout.write(new TextDecoder().decode(data)),
})
```

```python Python icon="python" theme={"system"}
handle = sandbox.pty.connect(pty.pid)
```

***

## Kill a PTY

`kill` terminates the PTY with `SIGKILL`. It returns `true` if the PTY was killed, or `false` if no PTY with that `pid` was found.

```js JavaScript & TypeScript icon="js" theme={"system"}
const killed = await sandbox.pty.kill(pty.pid)
console.log('killed:', killed)

await sandbox.kill()
```

```python Python icon="python" theme={"system"}
killed = sandbox.pty.kill(pty.pid)
print('killed:', killed)

sandbox.kill()
```

***

## Interactive example

Create a PTY, send an interactive command that prompts for input, then wait for it to finish and read the exit code. In Python, `wait(on_pty=...)` streams output to the callback and returns the result.

```python Python icon="python" theme={"system"}
from novita_sandbox import Novita
from novita_sandbox.core.sandbox.commands.command_handle import PtySize

novita = Novita()
sandbox = novita.sandbox.create()

output = []

def on_pty(data: bytes):
    output.append(data.decode('utf-8', errors='replace'))

terminal = sandbox.pty.create(PtySize(cols=80, rows=24), envs={'ABC': '123'}, cwd='/')

# Send a command and exit
sandbox.pty.send_stdin(terminal.pid, b'echo $ABC\nexit\n')

# Stream output and wait for completion
result = terminal.wait(on_pty=on_pty)
print('exit code:', result.exit_code)
print(''.join(output))

sandbox.kill()
```


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