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

# Desktop And PTY

> Automate desktop sessions and interactive terminals.

Desktop APIs require a desktop-capable template. PTY sessions are available for
interactive terminal workflows in running machines.
Idle PTY streams remain connected while the machine is running. A WebSocket
close without a `pty_exited` message is surfaced as a transport disconnect.

## Desktop

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
from nullspace import Machine

with Machine.create(template="desktop") as machine:
    width, height = machine.desktop.screen_size()
    display = machine.desktop.display_info()
    machine.desktop.type("hello")
    png = machine.desktop.screenshot()
    jpeg = machine.desktop.screenshot_compressed(format="jpeg", quality=70)
    print(width, height, display.virtual_screen.width, len(png), len(jpeg))
```

## Managed viewer

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
stream = machine.desktop.stream.start()
print(stream.viewer_url)
machine.desktop.set_clipboard_text("copied")
print(machine.desktop.get_clipboard_text())
machine.desktop.stream.stop()
```

## Input, windows, and recordings

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
machine.desktop.move(100, 100)
machine.desktop.left_click()
machine.desktop.right_click(200, 200)
machine.desktop.hotkey("ctrl+l")
machine.desktop.open("https://example.com")

for window in machine.desktop.list_windows():
    print(window.id, window.title)

recording = machine.desktop.start_recording(name="demo")
finished = machine.desktop.stop_recording(recording.id)
machine.desktop.download_recording(finished.id, local_path="./desktop.mp4")
```

## PTY

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
session = machine.pty.create_session(cols=100, rows=30)
chunks = []
session.send_input("pwd\nexit\n")
session.wait(on_data=lambda chunk: chunks.append(chunk.decode("utf-8")), timeout=5)
print("".join(chunks))
```

PTY sessions expose a string `session_id` for reconnect and management helpers.
`id` is an alias for `session_id`. Numeric `pid` reconnect remains available
for legacy scripts.

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
session = machine.pty.create_session(cwd="/workspace")
session_id = session.session_id
session.disconnect()

reattached = machine.pty.connect(
    session_id=session_id,
    on_data=lambda chunk: print(chunk.decode("utf-8"), end=""),
)
reattached.send_input("echo reattached\n")
```

Manage existing PTY sessions by `session_id`:

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
sessions = machine.pty.list_sessions()
session_id = sessions[0].session_id
info = machine.pty.get_session_info(session_id)
machine.pty.resize_session(session_id, 140, 40)
machine.pty.kill_session(session_id)
```

Concept: [Create](../../concepts/create). API reference:
[screenshot](../../api-reference), [startDesktopStream](../../api-reference),
[websocketUpgrade](../../api-reference), [listPtySessions](../../api-reference),
and [killPtySession](../../api-reference).
