ExDaytona.Pty (ex_daytona v0.2.0)

Copy Markdown View Source

Interactive PTY (pseudo-terminal) sessions inside a sandbox.

A PTY is a real terminal: interactive programs (shells, REPLs, editors, anything that needs a TTY) run in it, and I/O flows over a websocket.

{:ok, pty} = ExDaytona.Pty.create(sandbox, cols: 120, rows: 30)
{:ok, ws} = ExDaytona.Pty.connect(pty)

:ok = ExDaytona.Pty.send_input(ws, "echo hello\n")

receive do
  {:ex_daytona_ws, ^ws, {:binary, output}} -> IO.write(output)
end

:ok = ExDaytona.Pty.resize(pty, 200, 50)
:ok = ExDaytona.Pty.disconnect(ws)
:ok = ExDaytona.Pty.delete(pty)

Terminal output arrives at the connecting process as {:ex_daytona_ws, ws_pid, {:binary, data}} messages (see ExDaytona.WebSocket for the full message shapes).

Summary

Types

t()

A PTY session bound to its sandbox.

Functions

Open the PTY's websocket. Terminal output is delivered to the calling process (override with :owner) as {:ex_daytona_ws, ws, {:binary, data}} messages; {:ex_daytona_ws, ws, {:closed, reason}} signals the end.

Create a PTY session.

Kill the PTY session. Returns :ok.

Close the websocket connection (the PTY session keeps running — use delete/1 to kill it).

The PTY's current state as an ExDaytona.Model.PtySessionInfo.

List the sandbox's PTY sessions as ExDaytona.Model.PtySessionInfo structs.

Resize the terminal.

Write input to the terminal (what a user would type). ws is the connection from connect/2.

Types

t()

@type t() :: %ExDaytona.Pty{id: String.t(), sandbox: ExDaytona.Sandbox.t()}

A PTY session bound to its sandbox.

Functions

connect(pty, opts \\ [])

@spec connect(
  t(),
  keyword()
) :: {:ok, pid()} | {:error, ExDaytona.Error.t()}

Open the PTY's websocket. Terminal output is delivered to the calling process (override with :owner) as {:ex_daytona_ws, ws, {:binary, data}} messages; {:ex_daytona_ws, ws, {:closed, reason}} signals the end.

Options are passed to ExDaytona.WebSocket.connect/3 (:owner, :connect_timeout).

create(sandbox, opts \\ [])

@spec create(
  ExDaytona.Sandbox.t(),
  keyword()
) :: {:ok, t()} | {:error, ExDaytona.Error.t()}

Create a PTY session.

Options

  • :id — session id (default: a generated "ex-daytona-pty-" id)
  • :cols / :rows — terminal size (server defaults apply when omitted)
  • :cwd — working directory
  • :env — environment variables (map)
  • :lazy_start — don't start the shell until the first connect

delete(pty)

@spec delete(t()) :: :ok | {:error, ExDaytona.Error.t()}

Kill the PTY session. Returns :ok.

disconnect(ws)

@spec disconnect(pid() | ExDaytona.Transport.WSHandle.t()) :: :ok

Close the websocket connection (the PTY session keeps running — use delete/1 to kill it).

info(pty)

@spec info(t()) ::
  {:ok, ExDaytona.Model.PtySessionInfo.t()} | {:error, ExDaytona.Error.t()}

The PTY's current state as an ExDaytona.Model.PtySessionInfo.

list(sandbox)

@spec list(ExDaytona.Sandbox.t()) ::
  {:ok, [ExDaytona.Model.PtySessionInfo.t()]} | {:error, ExDaytona.Error.t()}

List the sandbox's PTY sessions as ExDaytona.Model.PtySessionInfo structs.

resize(pty, cols, rows)

@spec resize(t(), pos_integer(), pos_integer()) ::
  {:ok, ExDaytona.Model.PtySessionInfo.t()} | {:error, ExDaytona.Error.t()}

Resize the terminal.

send_input(ws, data)

@spec send_input(pid() | ExDaytona.Transport.WSHandle.t(), iodata()) ::
  :ok | {:error, ExDaytona.Error.t()}

Write input to the terminal (what a user would type). ws is the connection from connect/2.