Skip to content

Latest commit

 

History

History
183 lines (131 loc) · 8.07 KB

File metadata and controls

183 lines (131 loc) · 8.07 KB

xshellz-go API reference (v0.2.0)

Everything public in github.com/xshellz/xshellz-go. All calls take a context.Context; cancellation aborts the HTTP request or kills the remote SSH command. Also rendered on pkg.go.dev.

Words used below:

  • Control plane — the xShellz REST API (https://api.xshellz.com/v1), authenticated with your personal access token.
  • Data plane — a direct SSH connection to the box (as root), authenticated with a per-sandbox ed25519 key that never leaves your machine.

Package functions

Create(ctx, opts *CreateOptions) (*Sandbox, error)

Spawns a new sandbox and returns a live handle. Synchronous — the box is running when it returns. Generates a fresh in-memory ed25519 keypair; keep sbx.PrivateKeyPEM() if you want to Connect from another process later.

  • CreateOptions{Name, APIKey, APIURL} — all optional; nil is valid.
  • Errors: ErrNoAPIKey, ErrQuota (concurrent box limit), ErrAuth.

GetOrCreate(ctx, name string, opts *GetOrCreateOptions) (*Sandbox, error)

Returns a handle to the box with exactly this name, creating it if needed — the "permanent named box" entrypoint (see the README recipe).

  • Not found → creates the box and (keystore on, the default) persists the private key to <KeystoreDir>/<sanitized-name>.pem (0600).
  • Found → resolves the key (PrivateKeyPEM option wins, else keystore file), attaches, and calls Start first if the box is stopped.
  • GetOrCreateOptions{APIKey, APIURL, PrivateKeyPEM, KeystoreDir, DisableKeystore}.
  • The returned handle is already detached, so Close leaves the box alive (a permanent box should outlive your program). Call Kill to destroy it.
  • Errors: ErrNoAPIKey, ErrAuth, ErrQuota, ErrMissingKey (box exists, no key found — the message says which file was expected).

Connect(ctx, uuid string, privateKeyPEM []byte, opts *ConnectOptions) (*Sandbox, error)

Attaches to an existing sandbox by UUID with an explicit PEM private key. Errors: ErrNoAPIKey, ErrNotFound, key parse errors.

List(ctx, opts *ConnectOptions) ([]SandboxInfo, error)

All the account's sandboxes (running, stopped, provisioning).

GetBoxfile(ctx, opts *ConnectOptions) (string, error) / SetBoxfile(ctx, manifest string, opts *ConnectOptions) (string, error)

Account-level xshellz.box provisioning template (GET/PUT /v1/shells/agent/boxfile). Applied when a new box is created — seeded to ~/xshellz.box and used to preinstall packages. GetBoxfile returns "" when nothing is saved; SetBoxfile returns the stored manifest, and an empty manifest clears the template (sent as JSON null). Manifest max size: 16 KB.

DefaultKeystoreDir() (string, error)

~/.xshellz/keys resolved via os.UserHomeDir.

SupportedLanguages() []string

Sorted languages RunCode accepts: bash, node, php, python, ruby.

Sandbox — execution

(*Sandbox) Run(ctx, cmd string, opts *RunOptions) (*RunResult, error)

Runs cmd over SSH and waits. A non-zero exit code is data (RunResult.ExitCode), not an error; errors mean transport failure, context cancellation, or ErrNotRunning.

  • RunOptions{Cwd, Env, Stdout, Stderr} — with Cwd/Env the command is wrapped as cd CWD && env K=V ... sh -c 'CMD'; Stdout/Stderr stream live in addition to being captured.
  • RunResult{Stdout, Stderr string; ExitCode int}.

(*Sandbox) RunCode(ctx, language, code string, opts *RunOptions) (*RunResult, error)

Writes code to a unique temp file (/tmp/xshellz-code-<rand>.<ext>), runs the interpreter (pythonpython3, node, bash, ruby, php), always deletes the temp file, and returns the same RunResult as Run. Unknown language → ErrUnsupportedLanguage (message lists the supported set).

(*Sandbox) Spawn(ctx, cmd string, opts *SpawnOptions) (*JobHandle, error)

Starts cmd detached (nohup bash -c, output to ~/.xshellz/jobs/<id>.log) and returns a JobHandle. SpawnOptions.Name prefixes the job id (sanitized). The job survives your program exiting but not the box stopping/restarting.

(*Sandbox) Jobs(ctx) ([]Job, error)

Lists spawned jobs: Job{ID string; PID int; LogPath string; Running bool}. Log files persist after a job exits — delete them on the box when done.

JobHandle

Fields: ID string, PID int, LogPath string.

Method What it does
IsRunning(ctx) (bool, error) kill -0 probe of the job's pid
Logs(ctx, tailLines int) (string, error) last tailLines log lines (≤0 → 100), combined stdout+stderr
Stop(ctx) error SIGTERM, then SIGKILL after ~5s if still alive; no-op if already dead

Sandbox — files

Method What it does
WriteFile(ctx, remotePath string, data []byte) error bytes → box (parent dirs created)
ReadFile(ctx, remotePath string) ([]byte, error) box → bytes
Upload(ctx, localPath, remotePath string) error local file → box
Download(ctx, remotePath, localPath string) error box → local file (mode 0644)

Binary-safe (rides cat over SSH exec); whole files buffer in memory. All return ErrNotRunning on a stopped box; a failing remote command surfaces its stderr in the error.

Sandbox — introspection

(*Sandbox) Stats(ctx) (*SandboxStats, error)

GET /v1/shells/agent/{uuid}/stats. Wire fields (snake_case) map 1:1:

Field Wire Meaning
MemUsedMB / MemLimitMB / MemAllowedMB mem_used_mb memory current / cgroup limit / plan ceiling (MB)
CPUPercent / CPUAllowedVCPUs / CPUThrottledPeriods cpu_percent CPU now (100 = 1 vCPU) / plan ceiling / throttle count
PidsCurrent / PidsAllowed pids_current processes now / plan ceiling
DiskUsedMB / DiskAllowedMB disk_used_mb disk now / plan ceiling (MB)
NetRxMB / NetTxMB net_rx_mb network totals (MB)
BlkReadMB / BlkWriteMB blk_read_mb block IO totals (MB)

(*Sandbox) Procs(ctx) (*SandboxProcs, error)

GET /v1/shells/agent/{uuid}/procsSandboxProcs{Procs []ProcessInfo; Sessions int; Agents []string; DiskUsedMB, DiskAllowedMB int} with ProcessInfo{PID int; Comm string; CPU, Mem float64} (top processes, active SSH sessions, detected coding agents).

(*Sandbox) TerminalURL(ctx) (string, error)

GET /v1/shells/agent/{uuid}/terminal → a signed browser-terminal URL. The embedded HMAC token expires after ~1 hour; mint fresh, don't store.

Sandbox — lifecycle & identity

Method What it does
Start(ctx) error resume an idle-stopped box (POST .../start); refreshes info, redials SSH lazily
Restart(ctx) error reboot a running box (POST .../restart); /home preserved, processes/jobs are not
Detach() make Close keep the box (drop SSH only)
Close(ctx) error drop SSH + destroy the box (DELETE) unless detached; idempotent
Kill(ctx) error drop SSH + destroy the box unconditionally (even if detached, e.g. a GetOrCreate box); idempotent, swallows 404
UUID() string sandbox id
Status() string last-known status: StatusCreating / StatusRunning / StatusStopped (not auto-refreshed)
SSHHost() string / SSHPort() int / SSHCommand() string public SSH endpoint / copy-paste one-liner
Info() SandboxInfo full control-plane view (uuid, name, status, ssh endpoint, always-on, trial hours, isolation, timestamps)
PrivateKeyPEM() []byte the box's PEM private key (persist to reattach later)

Errors

Sentinels (errors.Is): ErrNoAPIKey, ErrAuth, ErrQuota, ErrNotFound, ErrNotRunning, ErrMissingKey, ErrUnsupportedLanguage.

API failures additionally match errors.As(err, &apiErr) with

type APIError struct {
    StatusCode int    // HTTP status
    Code       string // machine code when present (e.g. "verification_required")
    Message    string // human-readable API message
    Body       string // raw response body
}

Constants

  • DefaultAPIURL = https://api.xshellz.com/v1
  • StatusCreating, StatusRunning, StatusStopped