Sandbox
Create, list, inspect, and manage sandboxes with @tektona/sdk.
tek.sandbox manages sandboxes. create, get, and list return a Sandbox
instance bound to the client; per-sandbox actions are also available as methods
on that instance.
Create
The request body is the generated create type (snake_case fields). org and
project are optional here — omit them to inherit the client's default scope
(new Tektona({ org, project })). resources are in GiB (and CPU cores):
const tek = new Tektona({ apiKey, org: 'my-org', project: 'my-project' });
const sandbox = await tek.sandbox.create({
image: 'ghcr.io/tektona-ai/desktop-x11:0.4.3',
egress_network_policy: 'tektona/open',
// org / project inherited from the client scope above (pass them to override)
// resources: { cpu: 2, memory: 4, disk: 20 }, // cores, GiB, GiB
// env: { FOO: 'bar' },
// public: true,
});create returns the rich Sandbox instance (its instance fields stay camelCase:
id, state, image, project, org, resources, egressNetworkPolicy,
public). Pass a request timeout via the optional second argument:
create(body, { timeoutMs }).
List
list is scoped to an org (from the client default or per-call org), optionally
narrowed to a project. It returns one Page:
const page = await tek.sandbox.list({ limit: 50 }); // org from client scope
const mine = await tek.sandbox.list({ scope: 'mine' });
for await (const sb of tek.sandbox.listAll()) console.log(sb.id);Get
const sandbox = await tek.sandbox.get('01J5K9M2XR');Delete
await tek.sandbox.delete('01J5K9M2XR'); // idempotent: a missing sandbox resolves cleanlyPreview URLs
Expose a sandbox port publicly, optionally bounded by a TTL:
const preview = await sandbox.preview.create(8080, { ttl: '1h' });
if (preview.kind === 'public') {
console.log(preview.url);
} else {
console.log(preview.url, preview.token, preview.expiresAt);
}
await sandbox.preview.revoke(preview.token); // idempotentttl accepts a Go-style duration ('1h', '15m') or milliseconds; it must be
between 60 seconds and 24 hours. Out-of-range values throw InvalidArgumentError
before the network call.
Lifecycle
Every method below is available both as tek.sandbox.<op>(id, …) and as an
instance method on a Sandbox.
await sandbox.pause({ mode: 'hibernate' }); // or 'suspend'; -> { id, state }
await sandbox.resume();
await sandbox.reboot(); // orderly cold reboot; recent writes are flushed first
const fork = await sandbox.fork({ mode: 'full' }); // 'filesystem' | 'full'
// -> { id, state, cache_key, image_ref }
const resize = await sandbox.resize({ cpu: 4, memory: 8, force: true });
// -> { id, before, after, appliesImmediately, note }resize applies immediately when possible, otherwise on the next start/resume
(appliesImmediately: false). force is required to downsize memory.
Access & desktop
SSH, VNC, and desktop control are grouped into sub-namespaces on the instance:
const ssh = await sandbox.ssh.access();
// -> { url, token, ssh_host, ssh_port, ssh_ports? }
const vnc = await sandbox.vnc.access({ start_desktop: true });
// -> { url, token, expires_at }
await sandbox.desktop.start(); // -> { status }
await sandbox.desktop.stop(); // -> { status }
const pngBase64 = await sandbox.desktop.screenshot(); // base64-encoded PNGObservability
const page = await sandbox.listTransitions({ limit: 20 }); // -> Page<TransitionResponse>
for await (const t of sandbox.listAllTransitions()) console.log(t.to_state);
const ports = await sandbox.listPorts(); // [{ port, process, protocol }]
const rules = await sandbox.listEgressInjectionRules(); // [{ domain_pattern, path_match?, secret_refs }]
const lifecycle = await sandbox.getLifecycleConfig();
// -> { auto_delete_after, auto_pause_after, auto_pause_mode, auto_resume }
await sandbox.updateLifecycleConfig({ auto_pause_after: '15m', auto_resume: true });Lifecycle durations are Go-style strings; pass an empty string to disable a timer.
Sharing
await sandbox.share({ share_type: 'use' }); // 'use' | 'manage' -> { id, share_type }
await sandbox.unshare(); // back to private
await sandbox.transfer({ to: 'user@example.com', reason: 'handover' });
// -> { id, owner_user_id }