Sprites (Sprites v0.1.0)

View Source

Elixir SDK for Sprites - remote code container runtime.

Mirrors Elixir's native process APIs (System.cmd/3, Port operations).

Quick Start

# Create a client
client = Sprites.new(token, base_url: "https://api.sprites.dev")

# Get a sprite handle
sprite = Sprites.sprite(client, "my-sprite")

# System.cmd-like interface (blocking)
{output, exit_code} = Sprites.cmd(sprite, "echo", ["hello"])

# Port-like interface (async, message-based)
{:ok, command} = Sprites.spawn(sprite, "echo", ["hello"])

receive do
  {:stdout, ^command, data} -> IO.write(data)
  {:exit, ^command, code} -> IO.puts("Exited with: #{code}")
end

Creating and Destroying Sprites

{:ok, sprite} = Sprites.create(client, "new-sprite")
:ok = Sprites.destroy(sprite)

Summary

Functions

Spawns and attaches to an existing session.

Waits for a command to complete.

Closes stdin of a running command (sends EOF).

Executes a command synchronously, similar to System.cmd/3.

Creates a new sprite via the API.

Creates a new checkpoint for a sprite.

Destroys a sprite.

Creates a filesystem handle for a sprite.

Gets a specific checkpoint by ID.

Gets the current network policy for a sprite.

Gets detailed information about a sprite.

Lists all sprites.

Lists all checkpoints for a sprite.

Lists all active sessions for a sprite.

Creates a new Sprites client.

Creates a proxy session for a single port.

Creates proxy sessions for multiple port mappings.

Resizes the TTY of a running command.

Restores a sprite from a checkpoint.

Spawns an async command, similar to Port.open/2.

Returns a sprite handle for the given name.

Returns a Stream that emits command output.

Updates the network policy for a sprite.

Updates URL settings for a sprite.

Triggers an upgrade for a sprite.

Writes data to stdin of a running command.

Types

client()

@type client() :: Sprites.Client.t()

command()

@type command() :: Sprites.Command.t()

sprite()

@type sprite() :: Sprites.Sprite.t()

Functions

attach_session(sprite, session_id, opts \\ [])

@spec attach_session(sprite(), String.t(), keyword()) ::
  {:ok, command()} | {:error, term()}

Spawns and attaches to an existing session.

Examples

{:ok, cmd} = Sprites.attach_session(sprite, "session-id")

await(command, timeout \\ :infinity)

@spec await(command(), timeout()) :: {:ok, non_neg_integer()} | {:error, term()}

Waits for a command to complete.

Returns {:ok, exit_code} when the command exits.

Examples

{:ok, 0} = Sprites.await(command)
{:ok, code} = Sprites.await(command, 30_000)

close_stdin(command)

@spec close_stdin(command()) :: :ok

Closes stdin of a running command (sends EOF).

Examples

Sprites.close_stdin(command)

cmd(sprite, command, args \\ [], opts \\ [])

@spec cmd(sprite(), String.t(), [String.t()], keyword()) ::
  {binary(), non_neg_integer()}

Executes a command synchronously, similar to System.cmd/3.

Returns {output, exit_code} where output is a binary containing the combined stdout (and optionally stderr).

Options

  • :env - Environment variables as a list of {key, value} tuples
  • :dir - Working directory
  • :timeout - Command timeout in milliseconds
  • :stderr_to_stdout - Redirect stderr to stdout (default: false)
  • :tty - Allocate a TTY (default: false)
  • :tty_rows - TTY rows (default: 24)
  • :tty_cols - TTY columns (default: 80)

Examples

{output, 0} = Sprites.cmd(sprite, "echo", ["hello"])
{output, code} = Sprites.cmd(sprite, "ls", ["-la"], dir: "/app")

create(client, name, opts \\ [])

@spec create(client(), String.t(), keyword()) :: {:ok, sprite()} | {:error, term()}

Creates a new sprite via the API.

Options

  • :config - Sprite configuration map

Examples

{:ok, sprite} = Sprites.create(client, "my-sprite")

create_checkpoint(sprite, opts \\ [])

@spec create_checkpoint(
  sprite(),
  keyword()
) :: {:ok, Enumerable.t()} | {:error, term()}

Creates a new checkpoint for a sprite.

Returns a stream of messages. The stream should be consumed to completion.

Options

  • :comment - Optional comment for the checkpoint

Examples

{:ok, messages} = Sprites.create_checkpoint(sprite, comment: "Before changes")
Enum.each(messages, fn msg -> IO.inspect(msg) end)

destroy(sprite)

@spec destroy(sprite()) :: :ok | {:error, term()}

Destroys a sprite.

Examples

:ok = Sprites.destroy(sprite)

filesystem(sprite, working_dir \\ "/")

@spec filesystem(sprite(), String.t()) :: Sprites.Filesystem.t()

Creates a filesystem handle for a sprite.

The filesystem handle provides file operations similar to Elixir's File module.

Examples

fs = Sprites.filesystem(sprite, "/app")
{:ok, content} = Sprites.Filesystem.read(fs, "config.json")
:ok = Sprites.Filesystem.write(fs, "output.txt", "data")

get_checkpoint(sprite, checkpoint_id)

@spec get_checkpoint(sprite(), String.t()) ::
  {:ok, Sprites.Checkpoint.t()} | {:error, term()}

Gets a specific checkpoint by ID.

Examples

{:ok, checkpoint} = Sprites.get_checkpoint(sprite, "checkpoint-id")

get_network_policy(sprite)

@spec get_network_policy(sprite()) :: {:ok, Sprites.Policy.t()} | {:error, term()}

Gets the current network policy for a sprite.

Examples

{:ok, policy} = Sprites.get_network_policy(sprite)
IO.inspect(policy.rules)

get_sprite(client, name)

@spec get_sprite(client(), String.t()) :: {:ok, map()} | {:error, term()}

Gets detailed information about a sprite.

Examples

{:ok, info} = Sprites.get_sprite(client, "my-sprite")

list(client, opts \\ [])

@spec list(
  client(),
  keyword()
) :: {:ok, [map()]} | {:error, term()}

Lists all sprites.

Options

  • :prefix - Filter by name prefix

Examples

{:ok, sprites} = Sprites.list(client)
{:ok, sprites} = Sprites.list(client, prefix: "test-")

list_checkpoints(sprite, opts \\ [])

@spec list_checkpoints(
  sprite(),
  keyword()
) :: {:ok, [Sprites.Checkpoint.t()]} | {:error, term()}

Lists all checkpoints for a sprite.

Options

  • :history - History filter string (optional)

Examples

{:ok, checkpoints} = Sprites.list_checkpoints(sprite)

list_sessions(sprite)

@spec list_sessions(sprite()) :: {:ok, [Sprites.Session.t()]} | {:error, term()}

Lists all active sessions for a sprite.

Examples

{:ok, sessions} = Sprites.list_sessions(sprite)

new(token, opts \\ [])

@spec new(
  String.t(),
  keyword()
) :: client()

Creates a new Sprites client.

Options

  • :base_url - API base URL (default: "https://api.sprites.dev")
  • :timeout - HTTP timeout in milliseconds (default: 30_000)
  • :control_mode - Enable control mode for multiplexed exec over a single WebSocket per sprite (default: false)

Examples

client = Sprites.new("my-token")
client = Sprites.new("my-token", base_url: "https://custom.api.dev")
client = Sprites.new("my-token", control_mode: true)

proxy_port(sprite, local_port, remote_port)

@spec proxy_port(sprite(), non_neg_integer(), non_neg_integer()) ::
  {:ok, pid()} | {:error, term()}

Creates a proxy session for a single port.

Returns a session PID that manages the proxy. Use Sprites.Proxy.Session.stop/1 to close the proxy.

Examples

{:ok, session} = Sprites.proxy_port(sprite, 3000, 3000)
# Local port 3000 now forwards to remote port 3000
Sprites.Proxy.Session.stop(session)

proxy_ports(sprite, mappings)

@spec proxy_ports(sprite(), [Sprites.Proxy.PortMapping.t()]) ::
  {:ok, [pid()]} | {:error, term()}

Creates proxy sessions for multiple port mappings.

Examples

mappings = [
  %Sprites.Proxy.PortMapping{local_port: 3000, remote_port: 3000},
  %Sprites.Proxy.PortMapping{local_port: 8080, remote_port: 80}
]
{:ok, sessions} = Sprites.proxy_ports(sprite, mappings)

resize(command, rows, cols)

@spec resize(command(), pos_integer(), pos_integer()) :: :ok

Resizes the TTY of a running command.

Only works if the command was started with tty: true.

Examples

Sprites.resize(command, 40, 120)

restore_checkpoint(sprite, checkpoint_id)

@spec restore_checkpoint(sprite(), String.t()) ::
  {:ok, Enumerable.t()} | {:error, term()}

Restores a sprite from a checkpoint.

Returns a stream of messages. The stream should be consumed to completion.

Examples

{:ok, messages} = Sprites.restore_checkpoint(sprite, "checkpoint-id")
Enum.each(messages, fn msg -> IO.inspect(msg) end)

spawn(sprite, command, args \\ [], opts \\ [])

@spec spawn(sprite(), String.t(), [String.t()], keyword()) ::
  {:ok, command()} | {:error, term()}

Spawns an async command, similar to Port.open/2.

Returns {:ok, command} where command is a handle for the running process. Messages are sent to the calling process (or the process specified via :owner):

  • {:stdout, command, data} - stdout data
  • {:stderr, command, data} - stderr data
  • {:exit, command, exit_code} - command exited
  • {:error, command, reason} - error occurred

Options

  • :owner - Process to receive messages (default: self())
  • :env - Environment variables as a list of {key, value} tuples
  • :dir - Working directory
  • :tty - Allocate a TTY (default: false)
  • :tty_rows - TTY rows (default: 24)
  • :tty_cols - TTY columns (default: 80)

Examples

{:ok, cmd} = Sprites.spawn(sprite, "bash", ["-i"], tty: true)

receive do
  {:stdout, ^cmd, data} -> IO.write(data)
  {:exit, ^cmd, code} -> IO.puts("Done: #{code}")
end

sprite(client, name)

@spec sprite(client(), String.t()) :: sprite()

Returns a sprite handle for the given name.

This does not create or verify the sprite exists - it just returns a handle that can be used for operations.

Examples

sprite = Sprites.sprite(client, "my-sprite")

stream(sprite, command, args \\ [], opts \\ [])

@spec stream(sprite(), String.t(), [String.t()], keyword()) :: Enumerable.t()

Returns a Stream that emits command output.

Useful for processing command output lazily.

Examples

sprite
|> Sprites.stream("tail", ["-f", "/var/log/app.log"])
|> Stream.each(&IO.write/1)
|> Stream.run()

update_network_policy(sprite, policy)

@spec update_network_policy(sprite(), Sprites.Policy.t()) :: :ok | {:error, term()}

Updates the network policy for a sprite.

Examples

policy = %Sprites.Policy{
  rules: [
    %Sprites.Policy.Rule{domain: "example.com", action: "allow"}
  ]
}
:ok = Sprites.update_network_policy(sprite, policy)

update_url_settings(sprite, settings)

@spec update_url_settings(sprite(), map()) :: :ok | {:error, term()}

Updates URL settings for a sprite.

Examples

:ok = Sprites.update_url_settings(sprite, %{auth: "bearer"})

upgrade(sprite)

@spec upgrade(sprite()) :: :ok | {:error, term()}

Triggers an upgrade for a sprite.

Examples

:ok = Sprites.upgrade(sprite)

write(command, data)

@spec write(command(), iodata()) :: :ok | {:error, term()}

Writes data to stdin of a running command.

Examples

Sprites.write(command, "hello\n")