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

> ## Agent Instructions
> These docs cover learner integrations through Hosted Lab Pages, the SDK, and the REST API. Content management is outside this integration scope.
> Read the setup page for the chosen approach before implementing it. Keep organization API keys and hosted mint secrets on the server.
> The public SDK is coming soon. Check the SDK quickstart for current availability. Do not invent installation commands or direct readers to a private package.
> Cybr provides completion tracking and CTF verification. The integrating platform decides whether to award points.

# Terminal helper

> Server session methods and the browser terminal controller.

## Server session methods

```ts theme={null}
const session = await cybr.deployments.createTerminalSession(deploymentId, {
  pollIntervalMs: 2000,
  timeoutMs: 30000,
  signal: abortController.signal
})

// A saved or newly launched deployment handle has the same method.
const anotherSession = await deployment.createTerminalSession()
```

All configuration fields are optional. The defaults are a two-second interval and a 30-second startup deadline.

Only `CONTAINER_STARTING` triggers the startup loop. Cancellation produces `aborted`. The deadline produces `timeout`.

```ts theme={null}
interface TerminalSession {
  wsUrl: string
  protocols: string[]
  expiresAt: string
}
```

The SDK normalizes an absent REST `protocols` field to an empty array. It rejects malformed or expired session responses.

Both helpers require `wss:` URLs. Local development also permits `ws:` for `localhost`, `127.0.0.1`, and `[::1]`. The [REST operation](/api-reference/create-terminal-session) defines server errors.

## Browser entry point

```ts theme={null}
import { createTerminalClient } from '@cybr/labs-sdk/terminal'
```

This entry point contains no server client and accepts no organization API key. The SDK includes `dist/terminal.js` as a standalone browser ESM build.

The public SDK package is coming soon. Its [installation instructions](/getting-started/quickstart#install-the-sdk) will appear when the package is available.

## Configuration and callbacks

| Field | Type | Purpose |
| - | - | - |
| `connectionTimeoutMs` | `number` | Browser connection deadline, default `60000` milliseconds |
| `getSession` | `() => Promise<TerminalSession>` | Obtain fresh temporary credentials |
| `onOutput` | `(data: Uint8Array) => void` | Receive terminal output |
| `onStateChange` | `(state: TerminalState) => void` | Receive connection state |
| `onExit` | `(code: number \| undefined) => void` | Receive process exit |
| `onError` | `(error: Error) => void` | Receive connection or protocol errors |

Only `getSession` is required. States are `idle`, `connecting`, `ready`, `closed`, and `disposed`.

## Controller methods

| Method | Result | Behavior |
| - | - | - |
| `connect()` | `Promise<void>` | Request credentials and connect until readiness |
| `reconnect()` | `Promise<void>` | Replace the connection with fresh credentials |
| `write(text)` | `void` | Send UTF-8 input after readiness |
| `resize(cols, rows)` | `void` | Set terminal dimensions |
| `dispose()` | `void` | Close the connection and release listeners |

The helper retains the latest dimensions until readiness. It prevents stale session requests from reopening a disposed terminal.

The helper does not automatically reconnect, replay input, or end a deployment.

Handle rejections from `connect()` and `reconnect()`, even with an `onError` callback. Replacement and disposal reject a pending connection promise.

After readiness, a socket close reports `closed` through `onStateChange`. It does not call `onError` for an ordinary close.

A disposed controller cannot reconnect. Create another controller for a new terminal view.

`write()` discards input before readiness or after closure. `resize()` clamps whole-number dimensions to 1 through 500 and rejects non-finite numbers.

## xterm integration

This example assumes `screen` is an open xterm instance. `getSession` is your application callback:

```ts theme={null}
import { createTerminalClient } from '@cybr/labs-sdk/terminal'

const terminal = createTerminalClient({
  getSession,
  onOutput: (data) => screen.write(data),
  onError: (error) => showConnectionError(error.message)
})

const input = screen.onData((text) => terminal.write(text))
const resize = screen.onResize(({ cols, rows }) => terminal.resize(cols, rows))
terminal.resize(screen.cols, screen.rows)
try {
  await terminal.connect()
} catch {
  // onError reports connection failures. Disposal can also reject this promise.
}

function closeView() {
  input.dispose()
  resize.dispose()
  terminal.dispose()
  screen.dispose()
}
```

The UI can use the state callback to disable input before readiness. Reconnect controls call `terminal.reconnect()`.

The [terminal guide](/guides/terminals) explains session ownership and expiration.
