@lizard-build/sdk 0.1.59 → 0.1.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/index.d.mts +57 -36
- package/dist/index.d.ts +57 -36
- package/dist/index.js +31 -18
- package/dist/index.mjs +31 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ if (result.exitCode !== 0) throw new Error(result.stderr)
|
|
|
61
61
|
|
|
62
62
|
## Desktop (computer use)
|
|
63
63
|
|
|
64
|
-
The `desktop` template runs
|
|
64
|
+
The `desktop` template runs an Openbox desktop with Chromium, streamed to a browser over WebRTC (with noVNC as the fallback). You can watch it, and an agent can drive it:
|
|
65
65
|
|
|
66
66
|
```ts
|
|
67
67
|
import { Sandbox } from '@lizard-build/sdk'
|
|
@@ -108,13 +108,14 @@ const sandbox = await CodeSandbox.create({ projectId: 'proj_123' });
|
|
|
108
108
|
try {
|
|
109
109
|
await sandbox.runCode('x = 21');
|
|
110
110
|
const run = await sandbox.runCode('x * 2');
|
|
111
|
-
|
|
111
|
+
const out = run.results[0];
|
|
112
|
+
if (out?.type === 'result') console.log(out.data); // "42"
|
|
112
113
|
} finally {
|
|
113
114
|
await sandbox.kill();
|
|
114
115
|
}
|
|
115
116
|
```
|
|
116
117
|
|
|
117
|
-
`language: 'bash'`
|
|
118
|
+
`language: 'bash'` and `language: 'javascript'` (the `interpreter` template ships Node 22) run each call as a fresh process with no shared state.
|
|
118
119
|
|
|
119
120
|
## Configuration
|
|
120
121
|
|
|
@@ -124,7 +125,7 @@ Pass `timeoutMs` to `create()` to set the sandbox lifetime. The default is five
|
|
|
124
125
|
|
|
125
126
|
## Runtime limits
|
|
126
127
|
|
|
127
|
-
Each sandbox is a Firecracker microVM with its own kernel. Use volumes mounted at `/workspace` to keep files after a sandbox ends. `pause()`/`resume()` keep memory and running processes; `snapshot()` is ready in about 2 s and `Sandbox.restore()` starts a copy in about 0.4 s; `fork()` clones a running sandbox. File watching and sandbox log streaming are not available on Firecracker sandboxes yet
|
|
128
|
+
Each sandbox is a Firecracker microVM with its own kernel. Use volumes mounted at `/workspace` to keep files after a sandbox ends. `pause()`/`resume()` keep memory and running processes; `snapshot()` is ready in about 2 s and `Sandbox.restore()` starts a copy in about 0.4 s; `fork()` clones a running sandbox. File watching and sandbox log streaming are not available on Firecracker sandboxes yet. Volumes can grow but not shrink, and a sandbox with a volume attached cannot be forked. See the [snapshot guide](../../docs/sandboxes.md#pause-resume-snapshots-and-fork).
|
|
128
129
|
|
|
129
130
|
`getHost()` returns a hostname without `https://`; the port is private, so send `sandbox.accessToken` as the `X-Lizard-Access-Token` header (or use `exposePort()`, which also returns a browser `url` carrying the token). File writes accept text or bytes (binary is sent exactly); `readBytes()` supports binary downloads.
|
|
130
131
|
|
package/dist/index.d.mts
CHANGED
|
@@ -145,7 +145,10 @@ declare class ProjectsAPI {
|
|
|
145
145
|
}): Promise<Project[]>;
|
|
146
146
|
/** Get a project by ID. */
|
|
147
147
|
get(id: string): Promise<Project>;
|
|
148
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Create a new project. A scoped key can create one only in a workspace it
|
|
150
|
+
* covers; anywhere else it gets HTTP 403 with `code: 'PROJECT_OUT_OF_SCOPE'`.
|
|
151
|
+
*/
|
|
149
152
|
create(opts: CreateProjectOpts): Promise<Project>;
|
|
150
153
|
/** Update a project's name. */
|
|
151
154
|
update(id: string, opts: {
|
|
@@ -671,7 +674,7 @@ declare class Watcher {
|
|
|
671
674
|
* State of a sandbox's desktop, and the URLs that stream it.
|
|
672
675
|
*
|
|
673
676
|
* **Both URLs are credentials.** The port is published on a public hostname, and each
|
|
674
|
-
* URL carries the stream token and a
|
|
677
|
+
* URL carries the stream token and a password. Anyone holding `url` can see and
|
|
675
678
|
* control the desktop; anyone holding `viewOnlyUrl` can watch it. Do not log them or
|
|
676
679
|
* put them anywhere you would not put an API key.
|
|
677
680
|
*/
|
|
@@ -680,9 +683,9 @@ interface DesktopInfo {
|
|
|
680
683
|
/** Screen width in pixels, or `null` when the desktop has never been started. */
|
|
681
684
|
width: number | null;
|
|
682
685
|
height: number | null;
|
|
683
|
-
/**
|
|
686
|
+
/** Viewer page with full control (mouse and keyboard): WebRTC, with noVNC as the fallback. Treat like a credential. */
|
|
684
687
|
url: string;
|
|
685
|
-
/**
|
|
688
|
+
/** Viewer page that can only watch; enforced by the stream server in the sandbox, not the page. */
|
|
686
689
|
viewOnlyUrl: string;
|
|
687
690
|
}
|
|
688
691
|
interface DesktopStartOpts {
|
|
@@ -702,8 +705,9 @@ interface ClickOpts {
|
|
|
702
705
|
/**
|
|
703
706
|
* A graphical desktop in the sandbox, for computer-use agents and for people to watch.
|
|
704
707
|
*
|
|
705
|
-
* Only the `desktop` template has one (Xvfb +
|
|
706
|
-
*
|
|
708
|
+
* Only the `desktop` template has one (Xvfb + Openbox + Chromium on `DISPLAY=:1`,
|
|
709
|
+
* streamed over WebRTC with noVNC as the fallback); on any other template the calls
|
|
710
|
+
* fail with `code === 'DESKTOP_NOT_SUPPORTED'`.
|
|
707
711
|
*
|
|
708
712
|
* Input and screenshots run inside the sandbox with `xdotool` and `scrot`. Every
|
|
709
713
|
* argument goes to the sandbox as an argv array and is never parsed by a shell, so
|
|
@@ -792,9 +796,9 @@ interface SandboxInfo {
|
|
|
792
796
|
/** The sandbox runtime: `'firecracker'` (a microVM), `'container'`, or `null` when unknown. */
|
|
793
797
|
runtime?: 'firecracker' | 'container' | null;
|
|
794
798
|
pauseError?: string | null;
|
|
795
|
-
/** Machine size (`'small' | 'medium' | 'large'`); may be `null` for a sandbox
|
|
799
|
+
/** Machine size (`'small' | 'medium' | 'large'`); may be `null` for a sandbox billed by measured usage, such as one restored from a container snapshot. */
|
|
796
800
|
size?: 'small' | 'medium' | 'large' | null;
|
|
797
|
-
/** Flat hourly price in USD for `size`, billed per second while running; may be `null` when billed by measured usage (
|
|
801
|
+
/** Flat hourly price in USD for `size`, billed per second while running; may be `null` when billed by measured usage (a container snapshot). */
|
|
798
802
|
pricePerHour?: number | null;
|
|
799
803
|
cpus?: number;
|
|
800
804
|
memoryMb?: number;
|
|
@@ -826,8 +830,8 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
826
830
|
projectId?: string;
|
|
827
831
|
template?: string;
|
|
828
832
|
/**
|
|
829
|
-
* Create from a private saved snapshot. The sandbox runs
|
|
830
|
-
*
|
|
833
|
+
* Create from a private saved snapshot. The sandbox runs at the source sandbox's
|
|
834
|
+
* size and is billed flat at that size; `size` is ignored.
|
|
831
835
|
*/
|
|
832
836
|
snapshotId?: string;
|
|
833
837
|
/**
|
|
@@ -1154,9 +1158,10 @@ declare class Sandbox extends SandboxClient {
|
|
|
1154
1158
|
*/
|
|
1155
1159
|
exposePort(port: number, opts?: ConnectionOpts): Promise<ExposedPort>;
|
|
1156
1160
|
/**
|
|
1157
|
-
* Clone this running sandbox `count` times (1-
|
|
1161
|
+
* Clone this running sandbox `count` times (1-100). Each fork is a copy of the
|
|
1158
1162
|
* microVM at this instant -- memory, running processes and files -- and is
|
|
1159
|
-
* billed like its source. The source keeps running.
|
|
1163
|
+
* billed like its source. The source keeps running. Each copy counts as a
|
|
1164
|
+
* sandbox start, so the account's running-sandbox limit is the real cap.
|
|
1160
1165
|
*
|
|
1161
1166
|
* Returns one entry per requested fork, in order: `{ sandbox, info }`, or
|
|
1162
1167
|
* `{ error }` for a copy that could not be made (e.g. the account's sandbox
|
|
@@ -1420,14 +1425,22 @@ declare class WorkspacesAPI {
|
|
|
1420
1425
|
* project. A full key returns every workspace the account belongs to.
|
|
1421
1426
|
*/
|
|
1422
1427
|
list(): Promise<Workspace[]>;
|
|
1423
|
-
/**
|
|
1428
|
+
/**
|
|
1429
|
+
* Create a workspace. The caller becomes its owner.
|
|
1430
|
+
*
|
|
1431
|
+
* Needs a key with no scopes: a scoped key gets HTTP 403 with
|
|
1432
|
+
* `code: 'ACCOUNT_SCOPE_REQUIRED'`.
|
|
1433
|
+
*/
|
|
1424
1434
|
create(opts: CreateWorkspaceOpts): Promise<Workspace>;
|
|
1425
1435
|
/**
|
|
1426
1436
|
* Delete a workspace.
|
|
1427
1437
|
*
|
|
1428
|
-
* Empty-only by default — the server refuses while any project or
|
|
1429
|
-
* so this cannot quietly destroy a user's work.
|
|
1430
|
-
* workspace
|
|
1438
|
+
* Empty-only by default — the server refuses while any project, sandbox or volume
|
|
1439
|
+
* remains, so this cannot quietly destroy a user's work. `{ force: true }` deletes
|
|
1440
|
+
* the workspace with its apps, addons and projects; that is irreversible. It does not
|
|
1441
|
+
* delete sandboxes, sandbox volumes or snapshots: a running sandbox keeps running with
|
|
1442
|
+
* no workspace left to find it in. Kill the workspace's sandboxes and delete its
|
|
1443
|
+
* volumes and snapshots first.
|
|
1431
1444
|
*/
|
|
1432
1445
|
delete(id: string, opts?: {
|
|
1433
1446
|
force?: boolean;
|
|
@@ -1842,9 +1855,9 @@ declare class Volume {
|
|
|
1842
1855
|
/**
|
|
1843
1856
|
* Resize a volume, by name or by id, to `sizeGb`.
|
|
1844
1857
|
*
|
|
1845
|
-
*
|
|
1846
|
-
*
|
|
1847
|
-
*
|
|
1858
|
+
* A Firecracker volume (the default) can only grow. The change is in place and
|
|
1859
|
+
* online: a sandbox with the volume attached keeps running and sees the new size.
|
|
1860
|
+
* A smaller size throws `LizardError` (400) with `code: 'volume_shrink_unsupported'`.
|
|
1848
1861
|
*
|
|
1849
1862
|
* On a container volume the change is in place and online: the size is a quota,
|
|
1850
1863
|
* so no data is copied and a mounted sandbox sees the new size immediately. Both
|
|
@@ -1852,16 +1865,17 @@ declare class Volume {
|
|
|
1852
1865
|
* new size free — otherwise it throws `ConflictError` with
|
|
1853
1866
|
* `code: 'volume_too_full_to_shrink'`.
|
|
1854
1867
|
*
|
|
1855
|
-
* Other failures carry a `code` too: `invalid_volume_size`, `
|
|
1868
|
+
* Other failures carry a `code` too: `invalid_volume_size`, `volume_too_large`,
|
|
1869
|
+
* `volume_not_resizable` (an app's volume, not a sandbox volume),
|
|
1856
1870
|
* `volume_resize_in_progress`, `volume_not_provisioned`,
|
|
1857
1871
|
* `volume_capacity_unavailable`, and `volume_resize_timeout` (a `TimeoutError`;
|
|
1858
1872
|
* the size is left unchanged).
|
|
1859
1873
|
*
|
|
1860
|
-
* @returns The volume's updated info, including `sizeEnforced
|
|
1874
|
+
* @returns The volume's updated info, including `sizeEnforced` for a container volume.
|
|
1861
1875
|
*/
|
|
1862
1876
|
static resize(projectId: string, nameOrId: string, sizeGb: number, opts?: ConnectionOpts): Promise<VolumeInfo>;
|
|
1863
1877
|
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
1864
|
-
/** Resize this volume — see the static {@link Volume.resize} (
|
|
1878
|
+
/** Resize this volume — see the static {@link Volume.resize} (a Firecracker volume can only grow). */
|
|
1865
1879
|
resize(projectId: string, sizeGb: number): Promise<VolumeInfo>;
|
|
1866
1880
|
delete(projectId: string): Promise<void>;
|
|
1867
1881
|
}
|
|
@@ -1968,11 +1982,11 @@ declare class Lizard {
|
|
|
1968
1982
|
/**
|
|
1969
1983
|
* The account this credential belongs to — the SDK's `lizard whoami`.
|
|
1970
1984
|
*
|
|
1971
|
-
* A **scoped** key
|
|
1972
|
-
*
|
|
1973
|
-
*
|
|
1974
|
-
*
|
|
1975
|
-
*
|
|
1985
|
+
* A **scoped** key never learns whose account it is: it gets only `scoped: true` and
|
|
1986
|
+
* its `scopes`, each project or workspace with its name. No id, username, avatar,
|
|
1987
|
+
* email, balance or plan -- a scoped key is meant to be handed to someone who is not
|
|
1988
|
+
* the account's member, or injected into a sandbox. An unscoped key or a session
|
|
1989
|
+
* sees the full account.
|
|
1976
1990
|
*
|
|
1977
1991
|
* Reading back `scopes` is the cheapest way to answer "what can this key reach".
|
|
1978
1992
|
*/
|
|
@@ -1981,21 +1995,27 @@ declare class Lizard {
|
|
|
1981
1995
|
get platform(): PlatformClient;
|
|
1982
1996
|
}
|
|
1983
1997
|
/**
|
|
1984
|
-
* The account behind a credential
|
|
1998
|
+
* The account behind a credential -- see {@link Lizard.whoami}.
|
|
1985
1999
|
*
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
2000
|
+
* A scoped key gets only `scoped: true` and `scopes`; every other field is present only
|
|
2001
|
+
* for an unscoped key or a session.
|
|
1988
2002
|
*/
|
|
1989
2003
|
interface Account {
|
|
1990
|
-
|
|
1991
|
-
|
|
2004
|
+
/** Absent for a scoped key. */
|
|
2005
|
+
id?: string;
|
|
2006
|
+
/** Absent for a scoped key. */
|
|
2007
|
+
username?: string;
|
|
1992
2008
|
avatarUrl?: string | null;
|
|
1993
|
-
/** True when the calling key is scoped, meaning the account fields
|
|
2009
|
+
/** True when the calling key is scoped, meaning the account fields are absent. */
|
|
1994
2010
|
scoped?: boolean;
|
|
1995
|
-
/** What the calling key may reach. Present when `scoped` is true. */
|
|
2011
|
+
/** What the calling key may reach, by name. Present when `scoped` is true. */
|
|
1996
2012
|
scopes?: Array<{
|
|
1997
2013
|
type: 'workspace' | 'project';
|
|
1998
2014
|
id: string;
|
|
2015
|
+
name?: string | null;
|
|
2016
|
+
/** For a project scope: the workspace it belongs to. */
|
|
2017
|
+
workspaceId?: string | null;
|
|
2018
|
+
workspaceName?: string | null;
|
|
1999
2019
|
}>;
|
|
2000
2020
|
email?: string | null;
|
|
2001
2021
|
plan?: string;
|
|
@@ -2154,7 +2174,7 @@ interface CreateContextOpts {
|
|
|
2154
2174
|
* Limits, honestly:
|
|
2155
2175
|
* - `javascript` (node) and `bash` run each call as a fresh process: no state
|
|
2156
2176
|
* carries over and `results` stays empty. `node` must be installed in the
|
|
2157
|
-
* template; the `interpreter` template
|
|
2177
|
+
* template; the `interpreter` template ships Node 22.
|
|
2158
2178
|
* - On a template without Jupyter (e.g. `base`), Python also runs as a fresh
|
|
2159
2179
|
* process per call.
|
|
2160
2180
|
* - `stdout`/`stderr` are delivered in the chunks the kernel or process
|
|
@@ -2168,7 +2188,8 @@ interface CreateContextOpts {
|
|
|
2168
2188
|
* const sandbox = await CodeSandbox.create({ project: 'my-project' })
|
|
2169
2189
|
* await sandbox.runCode('x = 21')
|
|
2170
2190
|
* const run = await sandbox.runCode('x * 2')
|
|
2171
|
-
*
|
|
2191
|
+
* const out = run.results[0]
|
|
2192
|
+
* if (out?.type === 'result') console.log(out.data) // "42"
|
|
2172
2193
|
* await sandbox.kill()
|
|
2173
2194
|
* ```
|
|
2174
2195
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -145,7 +145,10 @@ declare class ProjectsAPI {
|
|
|
145
145
|
}): Promise<Project[]>;
|
|
146
146
|
/** Get a project by ID. */
|
|
147
147
|
get(id: string): Promise<Project>;
|
|
148
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Create a new project. A scoped key can create one only in a workspace it
|
|
150
|
+
* covers; anywhere else it gets HTTP 403 with `code: 'PROJECT_OUT_OF_SCOPE'`.
|
|
151
|
+
*/
|
|
149
152
|
create(opts: CreateProjectOpts): Promise<Project>;
|
|
150
153
|
/** Update a project's name. */
|
|
151
154
|
update(id: string, opts: {
|
|
@@ -671,7 +674,7 @@ declare class Watcher {
|
|
|
671
674
|
* State of a sandbox's desktop, and the URLs that stream it.
|
|
672
675
|
*
|
|
673
676
|
* **Both URLs are credentials.** The port is published on a public hostname, and each
|
|
674
|
-
* URL carries the stream token and a
|
|
677
|
+
* URL carries the stream token and a password. Anyone holding `url` can see and
|
|
675
678
|
* control the desktop; anyone holding `viewOnlyUrl` can watch it. Do not log them or
|
|
676
679
|
* put them anywhere you would not put an API key.
|
|
677
680
|
*/
|
|
@@ -680,9 +683,9 @@ interface DesktopInfo {
|
|
|
680
683
|
/** Screen width in pixels, or `null` when the desktop has never been started. */
|
|
681
684
|
width: number | null;
|
|
682
685
|
height: number | null;
|
|
683
|
-
/**
|
|
686
|
+
/** Viewer page with full control (mouse and keyboard): WebRTC, with noVNC as the fallback. Treat like a credential. */
|
|
684
687
|
url: string;
|
|
685
|
-
/**
|
|
688
|
+
/** Viewer page that can only watch; enforced by the stream server in the sandbox, not the page. */
|
|
686
689
|
viewOnlyUrl: string;
|
|
687
690
|
}
|
|
688
691
|
interface DesktopStartOpts {
|
|
@@ -702,8 +705,9 @@ interface ClickOpts {
|
|
|
702
705
|
/**
|
|
703
706
|
* A graphical desktop in the sandbox, for computer-use agents and for people to watch.
|
|
704
707
|
*
|
|
705
|
-
* Only the `desktop` template has one (Xvfb +
|
|
706
|
-
*
|
|
708
|
+
* Only the `desktop` template has one (Xvfb + Openbox + Chromium on `DISPLAY=:1`,
|
|
709
|
+
* streamed over WebRTC with noVNC as the fallback); on any other template the calls
|
|
710
|
+
* fail with `code === 'DESKTOP_NOT_SUPPORTED'`.
|
|
707
711
|
*
|
|
708
712
|
* Input and screenshots run inside the sandbox with `xdotool` and `scrot`. Every
|
|
709
713
|
* argument goes to the sandbox as an argv array and is never parsed by a shell, so
|
|
@@ -792,9 +796,9 @@ interface SandboxInfo {
|
|
|
792
796
|
/** The sandbox runtime: `'firecracker'` (a microVM), `'container'`, or `null` when unknown. */
|
|
793
797
|
runtime?: 'firecracker' | 'container' | null;
|
|
794
798
|
pauseError?: string | null;
|
|
795
|
-
/** Machine size (`'small' | 'medium' | 'large'`); may be `null` for a sandbox
|
|
799
|
+
/** Machine size (`'small' | 'medium' | 'large'`); may be `null` for a sandbox billed by measured usage, such as one restored from a container snapshot. */
|
|
796
800
|
size?: 'small' | 'medium' | 'large' | null;
|
|
797
|
-
/** Flat hourly price in USD for `size`, billed per second while running; may be `null` when billed by measured usage (
|
|
801
|
+
/** Flat hourly price in USD for `size`, billed per second while running; may be `null` when billed by measured usage (a container snapshot). */
|
|
798
802
|
pricePerHour?: number | null;
|
|
799
803
|
cpus?: number;
|
|
800
804
|
memoryMb?: number;
|
|
@@ -826,8 +830,8 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
826
830
|
projectId?: string;
|
|
827
831
|
template?: string;
|
|
828
832
|
/**
|
|
829
|
-
* Create from a private saved snapshot. The sandbox runs
|
|
830
|
-
*
|
|
833
|
+
* Create from a private saved snapshot. The sandbox runs at the source sandbox's
|
|
834
|
+
* size and is billed flat at that size; `size` is ignored.
|
|
831
835
|
*/
|
|
832
836
|
snapshotId?: string;
|
|
833
837
|
/**
|
|
@@ -1154,9 +1158,10 @@ declare class Sandbox extends SandboxClient {
|
|
|
1154
1158
|
*/
|
|
1155
1159
|
exposePort(port: number, opts?: ConnectionOpts): Promise<ExposedPort>;
|
|
1156
1160
|
/**
|
|
1157
|
-
* Clone this running sandbox `count` times (1-
|
|
1161
|
+
* Clone this running sandbox `count` times (1-100). Each fork is a copy of the
|
|
1158
1162
|
* microVM at this instant -- memory, running processes and files -- and is
|
|
1159
|
-
* billed like its source. The source keeps running.
|
|
1163
|
+
* billed like its source. The source keeps running. Each copy counts as a
|
|
1164
|
+
* sandbox start, so the account's running-sandbox limit is the real cap.
|
|
1160
1165
|
*
|
|
1161
1166
|
* Returns one entry per requested fork, in order: `{ sandbox, info }`, or
|
|
1162
1167
|
* `{ error }` for a copy that could not be made (e.g. the account's sandbox
|
|
@@ -1420,14 +1425,22 @@ declare class WorkspacesAPI {
|
|
|
1420
1425
|
* project. A full key returns every workspace the account belongs to.
|
|
1421
1426
|
*/
|
|
1422
1427
|
list(): Promise<Workspace[]>;
|
|
1423
|
-
/**
|
|
1428
|
+
/**
|
|
1429
|
+
* Create a workspace. The caller becomes its owner.
|
|
1430
|
+
*
|
|
1431
|
+
* Needs a key with no scopes: a scoped key gets HTTP 403 with
|
|
1432
|
+
* `code: 'ACCOUNT_SCOPE_REQUIRED'`.
|
|
1433
|
+
*/
|
|
1424
1434
|
create(opts: CreateWorkspaceOpts): Promise<Workspace>;
|
|
1425
1435
|
/**
|
|
1426
1436
|
* Delete a workspace.
|
|
1427
1437
|
*
|
|
1428
|
-
* Empty-only by default — the server refuses while any project or
|
|
1429
|
-
* so this cannot quietly destroy a user's work.
|
|
1430
|
-
* workspace
|
|
1438
|
+
* Empty-only by default — the server refuses while any project, sandbox or volume
|
|
1439
|
+
* remains, so this cannot quietly destroy a user's work. `{ force: true }` deletes
|
|
1440
|
+
* the workspace with its apps, addons and projects; that is irreversible. It does not
|
|
1441
|
+
* delete sandboxes, sandbox volumes or snapshots: a running sandbox keeps running with
|
|
1442
|
+
* no workspace left to find it in. Kill the workspace's sandboxes and delete its
|
|
1443
|
+
* volumes and snapshots first.
|
|
1431
1444
|
*/
|
|
1432
1445
|
delete(id: string, opts?: {
|
|
1433
1446
|
force?: boolean;
|
|
@@ -1842,9 +1855,9 @@ declare class Volume {
|
|
|
1842
1855
|
/**
|
|
1843
1856
|
* Resize a volume, by name or by id, to `sizeGb`.
|
|
1844
1857
|
*
|
|
1845
|
-
*
|
|
1846
|
-
*
|
|
1847
|
-
*
|
|
1858
|
+
* A Firecracker volume (the default) can only grow. The change is in place and
|
|
1859
|
+
* online: a sandbox with the volume attached keeps running and sees the new size.
|
|
1860
|
+
* A smaller size throws `LizardError` (400) with `code: 'volume_shrink_unsupported'`.
|
|
1848
1861
|
*
|
|
1849
1862
|
* On a container volume the change is in place and online: the size is a quota,
|
|
1850
1863
|
* so no data is copied and a mounted sandbox sees the new size immediately. Both
|
|
@@ -1852,16 +1865,17 @@ declare class Volume {
|
|
|
1852
1865
|
* new size free — otherwise it throws `ConflictError` with
|
|
1853
1866
|
* `code: 'volume_too_full_to_shrink'`.
|
|
1854
1867
|
*
|
|
1855
|
-
* Other failures carry a `code` too: `invalid_volume_size`, `
|
|
1868
|
+
* Other failures carry a `code` too: `invalid_volume_size`, `volume_too_large`,
|
|
1869
|
+
* `volume_not_resizable` (an app's volume, not a sandbox volume),
|
|
1856
1870
|
* `volume_resize_in_progress`, `volume_not_provisioned`,
|
|
1857
1871
|
* `volume_capacity_unavailable`, and `volume_resize_timeout` (a `TimeoutError`;
|
|
1858
1872
|
* the size is left unchanged).
|
|
1859
1873
|
*
|
|
1860
|
-
* @returns The volume's updated info, including `sizeEnforced
|
|
1874
|
+
* @returns The volume's updated info, including `sizeEnforced` for a container volume.
|
|
1861
1875
|
*/
|
|
1862
1876
|
static resize(projectId: string, nameOrId: string, sizeGb: number, opts?: ConnectionOpts): Promise<VolumeInfo>;
|
|
1863
1877
|
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
1864
|
-
/** Resize this volume — see the static {@link Volume.resize} (
|
|
1878
|
+
/** Resize this volume — see the static {@link Volume.resize} (a Firecracker volume can only grow). */
|
|
1865
1879
|
resize(projectId: string, sizeGb: number): Promise<VolumeInfo>;
|
|
1866
1880
|
delete(projectId: string): Promise<void>;
|
|
1867
1881
|
}
|
|
@@ -1968,11 +1982,11 @@ declare class Lizard {
|
|
|
1968
1982
|
/**
|
|
1969
1983
|
* The account this credential belongs to — the SDK's `lizard whoami`.
|
|
1970
1984
|
*
|
|
1971
|
-
* A **scoped** key
|
|
1972
|
-
*
|
|
1973
|
-
*
|
|
1974
|
-
*
|
|
1975
|
-
*
|
|
1985
|
+
* A **scoped** key never learns whose account it is: it gets only `scoped: true` and
|
|
1986
|
+
* its `scopes`, each project or workspace with its name. No id, username, avatar,
|
|
1987
|
+
* email, balance or plan -- a scoped key is meant to be handed to someone who is not
|
|
1988
|
+
* the account's member, or injected into a sandbox. An unscoped key or a session
|
|
1989
|
+
* sees the full account.
|
|
1976
1990
|
*
|
|
1977
1991
|
* Reading back `scopes` is the cheapest way to answer "what can this key reach".
|
|
1978
1992
|
*/
|
|
@@ -1981,21 +1995,27 @@ declare class Lizard {
|
|
|
1981
1995
|
get platform(): PlatformClient;
|
|
1982
1996
|
}
|
|
1983
1997
|
/**
|
|
1984
|
-
* The account behind a credential
|
|
1998
|
+
* The account behind a credential -- see {@link Lizard.whoami}.
|
|
1985
1999
|
*
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
2000
|
+
* A scoped key gets only `scoped: true` and `scopes`; every other field is present only
|
|
2001
|
+
* for an unscoped key or a session.
|
|
1988
2002
|
*/
|
|
1989
2003
|
interface Account {
|
|
1990
|
-
|
|
1991
|
-
|
|
2004
|
+
/** Absent for a scoped key. */
|
|
2005
|
+
id?: string;
|
|
2006
|
+
/** Absent for a scoped key. */
|
|
2007
|
+
username?: string;
|
|
1992
2008
|
avatarUrl?: string | null;
|
|
1993
|
-
/** True when the calling key is scoped, meaning the account fields
|
|
2009
|
+
/** True when the calling key is scoped, meaning the account fields are absent. */
|
|
1994
2010
|
scoped?: boolean;
|
|
1995
|
-
/** What the calling key may reach. Present when `scoped` is true. */
|
|
2011
|
+
/** What the calling key may reach, by name. Present when `scoped` is true. */
|
|
1996
2012
|
scopes?: Array<{
|
|
1997
2013
|
type: 'workspace' | 'project';
|
|
1998
2014
|
id: string;
|
|
2015
|
+
name?: string | null;
|
|
2016
|
+
/** For a project scope: the workspace it belongs to. */
|
|
2017
|
+
workspaceId?: string | null;
|
|
2018
|
+
workspaceName?: string | null;
|
|
1999
2019
|
}>;
|
|
2000
2020
|
email?: string | null;
|
|
2001
2021
|
plan?: string;
|
|
@@ -2154,7 +2174,7 @@ interface CreateContextOpts {
|
|
|
2154
2174
|
* Limits, honestly:
|
|
2155
2175
|
* - `javascript` (node) and `bash` run each call as a fresh process: no state
|
|
2156
2176
|
* carries over and `results` stays empty. `node` must be installed in the
|
|
2157
|
-
* template; the `interpreter` template
|
|
2177
|
+
* template; the `interpreter` template ships Node 22.
|
|
2158
2178
|
* - On a template without Jupyter (e.g. `base`), Python also runs as a fresh
|
|
2159
2179
|
* process per call.
|
|
2160
2180
|
* - `stdout`/`stderr` are delivered in the chunks the kernel or process
|
|
@@ -2168,7 +2188,8 @@ interface CreateContextOpts {
|
|
|
2168
2188
|
* const sandbox = await CodeSandbox.create({ project: 'my-project' })
|
|
2169
2189
|
* await sandbox.runCode('x = 21')
|
|
2170
2190
|
* const run = await sandbox.runCode('x * 2')
|
|
2171
|
-
*
|
|
2191
|
+
* const out = run.results[0]
|
|
2192
|
+
* if (out?.type === 'result') console.log(out.data) // "42"
|
|
2172
2193
|
* await sandbox.kill()
|
|
2173
2194
|
* ```
|
|
2174
2195
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1258,9 +1258,10 @@ var Sandbox = class extends SandboxClient {
|
|
|
1258
1258
|
return exposed;
|
|
1259
1259
|
}
|
|
1260
1260
|
/**
|
|
1261
|
-
* Clone this running sandbox `count` times (1-
|
|
1261
|
+
* Clone this running sandbox `count` times (1-100). Each fork is a copy of the
|
|
1262
1262
|
* microVM at this instant -- memory, running processes and files -- and is
|
|
1263
|
-
* billed like its source. The source keeps running.
|
|
1263
|
+
* billed like its source. The source keeps running. Each copy counts as a
|
|
1264
|
+
* sandbox start, so the account's running-sandbox limit is the real cap.
|
|
1264
1265
|
*
|
|
1265
1266
|
* Returns one entry per requested fork, in order: `{ sandbox, info }`, or
|
|
1266
1267
|
* `{ error }` for a copy that could not be made (e.g. the account's sandbox
|
|
@@ -1381,7 +1382,10 @@ var ProjectsAPI = class {
|
|
|
1381
1382
|
get(id) {
|
|
1382
1383
|
return this.client.get(`/api/projects/${id}`);
|
|
1383
1384
|
}
|
|
1384
|
-
/**
|
|
1385
|
+
/**
|
|
1386
|
+
* Create a new project. A scoped key can create one only in a workspace it
|
|
1387
|
+
* covers; anywhere else it gets HTTP 403 with `code: 'PROJECT_OUT_OF_SCOPE'`.
|
|
1388
|
+
*/
|
|
1385
1389
|
create(opts) {
|
|
1386
1390
|
return this.client.post("/api/projects", opts);
|
|
1387
1391
|
}
|
|
@@ -1650,16 +1654,24 @@ var WorkspacesAPI = class {
|
|
|
1650
1654
|
list() {
|
|
1651
1655
|
return this.client.get("/api/workspaces");
|
|
1652
1656
|
}
|
|
1653
|
-
/**
|
|
1657
|
+
/**
|
|
1658
|
+
* Create a workspace. The caller becomes its owner.
|
|
1659
|
+
*
|
|
1660
|
+
* Needs a key with no scopes: a scoped key gets HTTP 403 with
|
|
1661
|
+
* `code: 'ACCOUNT_SCOPE_REQUIRED'`.
|
|
1662
|
+
*/
|
|
1654
1663
|
create(opts) {
|
|
1655
1664
|
return this.client.post("/api/workspaces", opts);
|
|
1656
1665
|
}
|
|
1657
1666
|
/**
|
|
1658
1667
|
* Delete a workspace.
|
|
1659
1668
|
*
|
|
1660
|
-
* Empty-only by default — the server refuses while any project or
|
|
1661
|
-
* so this cannot quietly destroy a user's work.
|
|
1662
|
-
* workspace
|
|
1669
|
+
* Empty-only by default — the server refuses while any project, sandbox or volume
|
|
1670
|
+
* remains, so this cannot quietly destroy a user's work. `{ force: true }` deletes
|
|
1671
|
+
* the workspace with its apps, addons and projects; that is irreversible. It does not
|
|
1672
|
+
* delete sandboxes, sandbox volumes or snapshots: a running sandbox keeps running with
|
|
1673
|
+
* no workspace left to find it in. Kill the workspace's sandboxes and delete its
|
|
1674
|
+
* volumes and snapshots first.
|
|
1663
1675
|
*/
|
|
1664
1676
|
delete(id, opts) {
|
|
1665
1677
|
const qs = opts?.force ? "" : "?requireEmpty=true";
|
|
@@ -1853,9 +1865,9 @@ var Volume = class _Volume {
|
|
|
1853
1865
|
/**
|
|
1854
1866
|
* Resize a volume, by name or by id, to `sizeGb`.
|
|
1855
1867
|
*
|
|
1856
|
-
*
|
|
1857
|
-
*
|
|
1858
|
-
*
|
|
1868
|
+
* A Firecracker volume (the default) can only grow. The change is in place and
|
|
1869
|
+
* online: a sandbox with the volume attached keeps running and sees the new size.
|
|
1870
|
+
* A smaller size throws `LizardError` (400) with `code: 'volume_shrink_unsupported'`.
|
|
1859
1871
|
*
|
|
1860
1872
|
* On a container volume the change is in place and online: the size is a quota,
|
|
1861
1873
|
* so no data is copied and a mounted sandbox sees the new size immediately. Both
|
|
@@ -1863,12 +1875,13 @@ var Volume = class _Volume {
|
|
|
1863
1875
|
* new size free — otherwise it throws `ConflictError` with
|
|
1864
1876
|
* `code: 'volume_too_full_to_shrink'`.
|
|
1865
1877
|
*
|
|
1866
|
-
* Other failures carry a `code` too: `invalid_volume_size`, `
|
|
1878
|
+
* Other failures carry a `code` too: `invalid_volume_size`, `volume_too_large`,
|
|
1879
|
+
* `volume_not_resizable` (an app's volume, not a sandbox volume),
|
|
1867
1880
|
* `volume_resize_in_progress`, `volume_not_provisioned`,
|
|
1868
1881
|
* `volume_capacity_unavailable`, and `volume_resize_timeout` (a `TimeoutError`;
|
|
1869
1882
|
* the size is left unchanged).
|
|
1870
1883
|
*
|
|
1871
|
-
* @returns The volume's updated info, including `sizeEnforced
|
|
1884
|
+
* @returns The volume's updated info, including `sizeEnforced` for a container volume.
|
|
1872
1885
|
*/
|
|
1873
1886
|
static async resize(projectId, nameOrId, sizeGb, opts) {
|
|
1874
1887
|
const config = new ConnectionConfig(opts);
|
|
@@ -1887,7 +1900,7 @@ var Volume = class _Volume {
|
|
|
1887
1900
|
if (!res.ok) await handleApiError(res);
|
|
1888
1901
|
return res.json();
|
|
1889
1902
|
}
|
|
1890
|
-
/** Resize this volume — see the static {@link Volume.resize} (
|
|
1903
|
+
/** Resize this volume — see the static {@link Volume.resize} (a Firecracker volume can only grow). */
|
|
1891
1904
|
async resize(projectId, sizeGb) {
|
|
1892
1905
|
return _Volume.resize(projectId, this.volumeId, sizeGb, {
|
|
1893
1906
|
apiKey: this.config.apiKey,
|
|
@@ -1977,11 +1990,11 @@ var Lizard = class {
|
|
|
1977
1990
|
/**
|
|
1978
1991
|
* The account this credential belongs to — the SDK's `lizard whoami`.
|
|
1979
1992
|
*
|
|
1980
|
-
* A **scoped** key
|
|
1981
|
-
*
|
|
1982
|
-
*
|
|
1983
|
-
*
|
|
1984
|
-
*
|
|
1993
|
+
* A **scoped** key never learns whose account it is: it gets only `scoped: true` and
|
|
1994
|
+
* its `scopes`, each project or workspace with its name. No id, username, avatar,
|
|
1995
|
+
* email, balance or plan -- a scoped key is meant to be handed to someone who is not
|
|
1996
|
+
* the account's member, or injected into a sandbox. An unscoped key or a session
|
|
1997
|
+
* sees the full account.
|
|
1985
1998
|
*
|
|
1986
1999
|
* Reading back `scopes` is the cheapest way to answer "what can this key reach".
|
|
1987
2000
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1205,9 +1205,10 @@ var Sandbox = class extends SandboxClient {
|
|
|
1205
1205
|
return exposed;
|
|
1206
1206
|
}
|
|
1207
1207
|
/**
|
|
1208
|
-
* Clone this running sandbox `count` times (1-
|
|
1208
|
+
* Clone this running sandbox `count` times (1-100). Each fork is a copy of the
|
|
1209
1209
|
* microVM at this instant -- memory, running processes and files -- and is
|
|
1210
|
-
* billed like its source. The source keeps running.
|
|
1210
|
+
* billed like its source. The source keeps running. Each copy counts as a
|
|
1211
|
+
* sandbox start, so the account's running-sandbox limit is the real cap.
|
|
1211
1212
|
*
|
|
1212
1213
|
* Returns one entry per requested fork, in order: `{ sandbox, info }`, or
|
|
1213
1214
|
* `{ error }` for a copy that could not be made (e.g. the account's sandbox
|
|
@@ -1328,7 +1329,10 @@ var ProjectsAPI = class {
|
|
|
1328
1329
|
get(id) {
|
|
1329
1330
|
return this.client.get(`/api/projects/${id}`);
|
|
1330
1331
|
}
|
|
1331
|
-
/**
|
|
1332
|
+
/**
|
|
1333
|
+
* Create a new project. A scoped key can create one only in a workspace it
|
|
1334
|
+
* covers; anywhere else it gets HTTP 403 with `code: 'PROJECT_OUT_OF_SCOPE'`.
|
|
1335
|
+
*/
|
|
1332
1336
|
create(opts) {
|
|
1333
1337
|
return this.client.post("/api/projects", opts);
|
|
1334
1338
|
}
|
|
@@ -1597,16 +1601,24 @@ var WorkspacesAPI = class {
|
|
|
1597
1601
|
list() {
|
|
1598
1602
|
return this.client.get("/api/workspaces");
|
|
1599
1603
|
}
|
|
1600
|
-
/**
|
|
1604
|
+
/**
|
|
1605
|
+
* Create a workspace. The caller becomes its owner.
|
|
1606
|
+
*
|
|
1607
|
+
* Needs a key with no scopes: a scoped key gets HTTP 403 with
|
|
1608
|
+
* `code: 'ACCOUNT_SCOPE_REQUIRED'`.
|
|
1609
|
+
*/
|
|
1601
1610
|
create(opts) {
|
|
1602
1611
|
return this.client.post("/api/workspaces", opts);
|
|
1603
1612
|
}
|
|
1604
1613
|
/**
|
|
1605
1614
|
* Delete a workspace.
|
|
1606
1615
|
*
|
|
1607
|
-
* Empty-only by default — the server refuses while any project or
|
|
1608
|
-
* so this cannot quietly destroy a user's work.
|
|
1609
|
-
* workspace
|
|
1616
|
+
* Empty-only by default — the server refuses while any project, sandbox or volume
|
|
1617
|
+
* remains, so this cannot quietly destroy a user's work. `{ force: true }` deletes
|
|
1618
|
+
* the workspace with its apps, addons and projects; that is irreversible. It does not
|
|
1619
|
+
* delete sandboxes, sandbox volumes or snapshots: a running sandbox keeps running with
|
|
1620
|
+
* no workspace left to find it in. Kill the workspace's sandboxes and delete its
|
|
1621
|
+
* volumes and snapshots first.
|
|
1610
1622
|
*/
|
|
1611
1623
|
delete(id, opts) {
|
|
1612
1624
|
const qs = opts?.force ? "" : "?requireEmpty=true";
|
|
@@ -1800,9 +1812,9 @@ var Volume = class _Volume {
|
|
|
1800
1812
|
/**
|
|
1801
1813
|
* Resize a volume, by name or by id, to `sizeGb`.
|
|
1802
1814
|
*
|
|
1803
|
-
*
|
|
1804
|
-
*
|
|
1805
|
-
*
|
|
1815
|
+
* A Firecracker volume (the default) can only grow. The change is in place and
|
|
1816
|
+
* online: a sandbox with the volume attached keeps running and sees the new size.
|
|
1817
|
+
* A smaller size throws `LizardError` (400) with `code: 'volume_shrink_unsupported'`.
|
|
1806
1818
|
*
|
|
1807
1819
|
* On a container volume the change is in place and online: the size is a quota,
|
|
1808
1820
|
* so no data is copied and a mounted sandbox sees the new size immediately. Both
|
|
@@ -1810,12 +1822,13 @@ var Volume = class _Volume {
|
|
|
1810
1822
|
* new size free — otherwise it throws `ConflictError` with
|
|
1811
1823
|
* `code: 'volume_too_full_to_shrink'`.
|
|
1812
1824
|
*
|
|
1813
|
-
* Other failures carry a `code` too: `invalid_volume_size`, `
|
|
1825
|
+
* Other failures carry a `code` too: `invalid_volume_size`, `volume_too_large`,
|
|
1826
|
+
* `volume_not_resizable` (an app's volume, not a sandbox volume),
|
|
1814
1827
|
* `volume_resize_in_progress`, `volume_not_provisioned`,
|
|
1815
1828
|
* `volume_capacity_unavailable`, and `volume_resize_timeout` (a `TimeoutError`;
|
|
1816
1829
|
* the size is left unchanged).
|
|
1817
1830
|
*
|
|
1818
|
-
* @returns The volume's updated info, including `sizeEnforced
|
|
1831
|
+
* @returns The volume's updated info, including `sizeEnforced` for a container volume.
|
|
1819
1832
|
*/
|
|
1820
1833
|
static async resize(projectId, nameOrId, sizeGb, opts) {
|
|
1821
1834
|
const config = new ConnectionConfig(opts);
|
|
@@ -1834,7 +1847,7 @@ var Volume = class _Volume {
|
|
|
1834
1847
|
if (!res.ok) await handleApiError(res);
|
|
1835
1848
|
return res.json();
|
|
1836
1849
|
}
|
|
1837
|
-
/** Resize this volume — see the static {@link Volume.resize} (
|
|
1850
|
+
/** Resize this volume — see the static {@link Volume.resize} (a Firecracker volume can only grow). */
|
|
1838
1851
|
async resize(projectId, sizeGb) {
|
|
1839
1852
|
return _Volume.resize(projectId, this.volumeId, sizeGb, {
|
|
1840
1853
|
apiKey: this.config.apiKey,
|
|
@@ -1924,11 +1937,11 @@ var Lizard = class {
|
|
|
1924
1937
|
/**
|
|
1925
1938
|
* The account this credential belongs to — the SDK's `lizard whoami`.
|
|
1926
1939
|
*
|
|
1927
|
-
* A **scoped** key
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1930
|
-
*
|
|
1931
|
-
*
|
|
1940
|
+
* A **scoped** key never learns whose account it is: it gets only `scoped: true` and
|
|
1941
|
+
* its `scopes`, each project or workspace with its name. No id, username, avatar,
|
|
1942
|
+
* email, balance or plan -- a scoped key is meant to be handed to someone who is not
|
|
1943
|
+
* the account's member, or injected into a sandbox. An unscoped key or a session
|
|
1944
|
+
* sees the full account.
|
|
1932
1945
|
*
|
|
1933
1946
|
* Reading back `scopes` is the cheapest way to answer "what can this key reach".
|
|
1934
1947
|
*/
|
package/package.json
CHANGED