@solarisdk/sdk
v0.1.3
Published
Official Solari SDK — one unified client (`SolariClient`) plus the `solari` CLI for managed desktops and ephemeral sandboxes. Re-exports @solarisdk/desktop, @solarisdk/sandbox, and @solarisdk/core.
Maintainers
Readme
@solarisdk/sdk
The official Solari SDK for TypeScript — one unified client for managed,
hardware-isolated desktops (a live VNC stream + a computer-use action API)
and fast, ephemeral sandboxes (headless compute), plus the solari CLI.
SDK ──HTTPS──▶ Gateway (create / get / destroy sessions)
SDK ──WSS────▶ Gateway (control channel: computer-use JSON-RPC)
──WSS────▶ (stream channel: RFB/VNC bytes, embed in a viewer)Packages
Install the unified client, or just the product you need — they share a runtime
(@solarisdk/core) and identical handles, so you can mix and match:
| Package | Install when you want | Main export |
|---|---|---|
| @solarisdk/sdk | both products + the solari CLI | SolariClient |
| @solarisdk/desktop | desktops only | DesktopClient |
| @solarisdk/sandbox | sandboxes only | SandboxClient |
| @solarisdk/core | (installed automatically) shared runtime | handles, types, errors |
npm install @solarisdk/sdkWorks in Node (uses the ws package) and in browsers (uses the native
WebSocket). The control channel requires fetch (built into Node 18+ and all
browsers).
Language bindings
The same gateway wire protocol is spoken by first-party bindings in several
languages. TypeScript and Python are at full parity (computer-use, pty, volumes,
viewer); Go, Rust, and C++ ship the core surface — create/connect a session
plus the commands, files, code.run, and git namespaces — with more to
follow. The wire contract they all implement lives in PROTOCOL.md.
| Language | Location | Package / module | Surface |
|---|---|---|---|
| TypeScript | sdk/ | @solarisdk/sdk | full |
| Python | sdk/python | solari_desktop | full |
| Go | sdk/go | go.getsolari.com/solari-sandbox | core |
| Rust | sdk/rust | solari-sdk | core |
| C++ | sdk/cpp | solari:: (C++17, CMake) | core |
Each binding is idiomatic for its language (Go is context-first with typed error
values; Rust is async/tokio with a Result<T, SolariError> API; C++ is a
blocking API over libcurl + IXWebSocket + nlohmann/json) and carries its own
offline test suite. See each directory's README.md for a quickstart.
Usage
import { SolariClient } from "@solarisdk/sdk";
const pt = new SolariClient({
apiKey: process.env.SOLARI_API_KEY!,
baseUrl: "https://api.getsolari.com",
});
// A GUI desktop, assigned from the warm pool — typically sub-second.
const desktop = await pt.desktops.create({
template: "default",
resolution: "1280x720",
timeoutMs: 1_800_000, // rolling idle window: auto-pause after 30 min idle
});
console.log(desktop.streamUrl); // embed in a VNC viewer to watch it live
await desktop.connect(); // open the control channel, then drive it
const shot = await desktop.screenshot({ format: "png" }); // Uint8Array
await desktop.mouse.click(640, 360, { humanize: true });
await desktop.fs.write("/tmp/note.txt", "hello");
await desktop.pause(); // snapshot RAM+disk, free the slot
await desktop.resume();
await pt.desktops.destroy(desktop.sessionId);
// A headless sandbox for fast code execution.
const sandbox = await pt.sandboxes.create({ template: "base" });
const out = await sandbox.exec("python3", { args: ["-c", "print(2 + 2)"] });
console.log(out.exitCode, out.stdout);
await sandbox.kill();pt.desktops is a DesktopClient, pt.sandboxes is a SandboxClient. If you
only need one, import it directly from its own package (@solarisdk/desktop /
@solarisdk/sandbox) — the classes and handles are identical.
DesktopClient
| Method | Description |
|---|---|
| new DesktopClient({ apiKey, baseUrl, fetch?, callTimeoutMs? }) | Construct a client. |
| create(opts?) → Desktop | POST /desktops. Opts: template, cpu (1–16 vCPUs, default 2), memMb (2048–65536 MiB, default 2048), ttlSeconds, timeoutMs (rolling idle window), resolution, metadata, record, lifecycle. cpu/memMb grow the warm clone on assign (ACPI vCPU hot-add + virtio-mem); size is preserved across pause/resume. |
| get(sessionId) | GET /desktops/:id → { sessionId, status, expiresAt }. |
| destroy(sessionId) | DELETE /desktops/:id → { ok: true } (idempotent). |
| attach(session) → Desktop | Re-create a handle from saved session URLs. |
Gateway errors are mapped to typed errors: AuthError (401), PlanError
(402), ConcurrencyLimitError (429), NoCapacityError (503), and a generic
GatewayError otherwise — all subclasses of SolariError.
Desktop handle (Desktop)
Properties: sessionId, streamUrl, controlUrl, expiresAt, connected.
connect() opens the control WebSocket; close() tears it down. Each action
sends a { id, method, params } JSON-RPC frame and awaits the matching
{ id, ok, result } reply, correlated by id, with a per-call timeout
(TimeoutError). A failed RPC throws ActionError.
Computer-use actions
| Surface | Methods |
|---|---|
| desktop.exec(cmd, { args?, cwd?, timeoutMs? }) | → { exitCode, stdout, stderr } |
| desktop.fs | read(path)→Uint8Array, readText(path)→string, write(path, data, mode?), list(path)→entries[] |
| desktop.mouse | move(x,y,{humanize?}), click(x,y,{button?,humanize?}), down/up(x,y,button?), scroll(x,y,{...}) |
| desktop.keyboard | type(text), press(keys), down(keys), up(keys) |
| desktop.screenshot({ format?, quality? }) | → Uint8Array |
| desktop.display | set(w, h) |
| desktop.clipboard | get()→string, set(text) |
| desktop.process | list()→ProcessInfo[], kill(pid) |
| desktop.health() | → { ready, display, vnc } |
Lifecycle & preview
Since the 2026-07 desktop/sandbox VM consolidation, a desktop is backed by the
same unified session record as a sandbox, so the handle carries the full
lifecycle surface (routed to /sandboxes/:id/*):
| Method | Description |
|---|---|
| desktop.pause() / desktop.resume() | Pause (snapshot RAM+disk, free the slot) / resume (re-acquires a slot; may throw ConcurrencyLimitError if the org is at cap). |
| desktop.setTimeout(timeoutMs) | Extend the rolling idle keep-alive → { expiresAt }. |
| desktop.metrics() / desktop.snapshot(name?) / desktop.revert(id) | Metrics + in-place snapshot/restore. |
| desktop.previewUrl(port) | Public preview URL { url, token? } for an in-guest port. |
See examples/quickstart.ts for an end-to-end script.
Build
This package is an npm workspaces monorepo: @solarisdk/core,
@solarisdk/desktop, and @solarisdk/sandbox live under packages/, and this
umbrella (@solarisdk/sdk — SolariClient + solari CLI) builds from
src/ at the repo root.
npm install
npm run build # core → desktop → sandbox → umbrella (tsc → dist/, ESM + .d.ts)
npm run typecheck # tsc --noEmit (umbrella)
npm test # offline suites incl. TS↔Python parity