Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/superfly/sprites-go/llms.txt

Use this file to discover all available pages before exploring further.

The Sprites Go SDK exposes a Cmd type that mirrors the standard library’s exec.Cmd, so running a command on a remote Sprite feels exactly like running one locally. You create a Cmd from a Sprite handle, configure any fields you need, then call one of the execution methods.

Creating a command

Use sprite.Command to create a Cmd for a given program and its arguments. The first argument is the program name; any additional arguments are passed through as-is.
cmd := sprite.Command("ls", "-la", "/tmp")

With context

Use sprite.CommandContext when you need cancellation or a timeout. The SDK kills the remote process if the context is cancelled before the command finishes.
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

cmd := sprite.CommandContext(ctx, "long-running-command")
Passing a nil context to CommandContext panics. Always pass a valid context, such as context.Background().

Execution methods

cmd.Run()

Run starts the command and blocks until it exits. It is the simplest way to execute a command when you don’t need to capture output.
cmd := sprite.Command("echo", "hello", "world")
if err := cmd.Run(); err != nil {
    log.Fatal(err)
}

cmd.Output()

Output runs the command and returns its standard output as a byte slice. Standard error is discarded unless you set cmd.Stderr explicitly.
output, err := sprite.Command("date").Output()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Current date: %s", output)

cmd.CombinedOutput()

CombinedOutput runs the command and returns stdout and stderr merged into a single byte slice, in the order the remote process writes them.
combined, err := cmd.CombinedOutput()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Output: %s", combined)

cmd.Start() and cmd.Wait()

Use Start and Wait separately when you need to interact with the process while it runs — for example, to write to stdin, read from a pipe, or send a signal mid-flight.
cmd := sprite.Command("bash", "-c", "sleep 5 && echo done")

if err := cmd.Start(); err != nil {
    log.Fatal(err)
}

// Do other work here while the command runs...

if err := cmd.Wait(); err != nil {
    log.Fatal(err)
}
Calling Wait before Start returns ErrNotStarted. Always call Start first.

Configuring the environment

Environment variables

Set cmd.Env to a slice of "key=value" strings. If Env is nil, the remote process inherits the Sprite’s default environment.
cmd := sprite.Command("bash", "-c", "echo Hello $USER from $HOSTNAME")
cmd.Env = []string{"USER=sprite", "HOSTNAME=remote"}

output, err := cmd.Output()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Greeting: %s", output)

Working directory

Set cmd.Dir to run the process in a specific directory on the Sprite. An empty string uses the Sprite’s default directory.
cmd := sprite.Command("env")
cmd.Env = []string{"FOO=bar", "BAZ=qux"}
cmd.Dir = "/tmp"

output, err := cmd.Output()

Signals

After Start, you can send a POSIX signal to the remote process with cmd.Signal. The SDK uses the existing WebSocket connection when the server supports it, and falls back to an HTTP request otherwise. Valid signal names: INT, TERM, HUP, KILL, QUIT, USR1, USR2.
cmd := sprite.Command("sleep", "60")
if err := cmd.Start(); err != nil {
    log.Fatal(err)
}

// Send SIGTERM after 5 seconds
time.Sleep(5 * time.Second)
if err := cmd.Signal("TERM"); err != nil {
    log.Printf("signal error: %v", err)
}

err := cmd.Wait()
Use KILL only as a last resort — it cannot be caught or ignored by the remote process and gives it no chance to clean up.

Exit codes

cmd.ExitCode() returns the numeric exit code once the process has finished, or -1 if it is still running or was terminated abnormally.
cmd := sprite.Command("false")
err := cmd.Run()

if err != nil {
    if exitErr, ok := err.(*sprites.ExitError); ok {
        fmt.Printf("Command exited with code: %d\n", exitErr.ExitCode())
    } else {
        log.Fatal(err)
    }
}

// Also available on the Cmd directly after Wait:
code := cmd.ExitCode()
fmt.Println("Exit code:", code)

Connection mode

cmd.ConnectionMode() reports how the SDK connected for this command. It returns "control" when the SDK multiplexed over a shared control WebSocket, "direct" when it opened a dedicated WebSocket, or an empty string before Start is called.
if err := cmd.Start(); err != nil {
    log.Fatal(err)
}
fmt.Println("Connection mode:", cmd.ConnectionMode()) // "control" or "direct"

Context cancellation

When the context passed to CommandContext is cancelled or times out, the SDK kills the remote process. Combine this with Start/Wait for fine-grained control.
1

Create a context with timeout

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
2

Create and start the command

cmd := sprite.CommandContext(ctx, "grep", "-i", "error")
cmd.Stdin = strings.NewReader("Line 1\nError on line 2\nLine 3\nAnother ERROR\n")

output, err := cmd.Output()
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Grep results:\n%s", output)
3

Handle cancellation errors

If the context expires, Run, Output, or Wait returns an error wrapping the context’s Err(). Check for it explicitly if you need to distinguish timeouts from process failures.
if err != nil {
    if ctx.Err() != nil {
        log.Printf("command timed out: %v", ctx.Err())
    } else {
        log.Printf("command failed: %v", err)
    }
}

Build docs developers (and LLMs) love