@lizard-build/sdk 0.1.40 → 0.1.42
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 +58 -258
- package/dist/index.d.mts +87 -56
- package/dist/index.d.ts +87 -56
- package/dist/index.js +83 -47
- package/dist/index.mjs +83 -47
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -114,7 +114,7 @@ declare class AddonsAPI {
|
|
|
114
114
|
memoryMb?: number;
|
|
115
115
|
storageGb?: number;
|
|
116
116
|
}): Promise<Addon>;
|
|
117
|
-
/** Restart an addon
|
|
117
|
+
/** Restart an addon. */
|
|
118
118
|
redeploy(projectId: string, addonId: string): Promise<void>;
|
|
119
119
|
rename(projectId: string, addonId: string, name: string): Promise<unknown>;
|
|
120
120
|
secrets(projectId: string, addonId: string): Promise<Array<{
|
|
@@ -395,7 +395,7 @@ interface ProcessInfo {
|
|
|
395
395
|
/** Signals accepted by {@link Process.kill}. */
|
|
396
396
|
type ProcessSignal = 'SIGTERM' | 'SIGKILL' | 'SIGINT' | 'SIGHUP' | 'SIGQUIT' | 'SIGUSR1' | 'SIGUSR2';
|
|
397
397
|
/**
|
|
398
|
-
* The result of a process execution inside a Lizard
|
|
398
|
+
* The result of a process execution inside a Lizard sandbox.
|
|
399
399
|
*/
|
|
400
400
|
interface ProcessResult {
|
|
401
401
|
stdout: string;
|
|
@@ -418,7 +418,7 @@ interface ProcessOpts {
|
|
|
418
418
|
onPid?: (pid: number) => void;
|
|
419
419
|
}
|
|
420
420
|
/**
|
|
421
|
-
* Runs processes inside a Lizard sandbox
|
|
421
|
+
* Runs processes inside a Lizard sandbox.
|
|
422
422
|
*
|
|
423
423
|
* Access via `sandbox.process`.
|
|
424
424
|
*/
|
|
@@ -427,12 +427,12 @@ declare class Process {
|
|
|
427
427
|
private readonly config;
|
|
428
428
|
constructor(sandboxId: string, config: ConnectionConfig);
|
|
429
429
|
/**
|
|
430
|
-
* Execute a command inside the
|
|
430
|
+
* Execute a command inside the sandbox and wait for it to complete.
|
|
431
431
|
*
|
|
432
432
|
* The command runs in a shell inside the Lizard sandbox and returns
|
|
433
433
|
* stdout, stderr, and the exit code when it finishes.
|
|
434
434
|
*
|
|
435
|
-
* @param cmd Shell command to run inside the
|
|
435
|
+
* @param cmd Shell command to run inside the sandbox.
|
|
436
436
|
* @param opts Optional execution options — environment variables, working
|
|
437
437
|
* directory, user, and timeout.
|
|
438
438
|
*
|
|
@@ -511,7 +511,7 @@ interface FileInfo {
|
|
|
511
511
|
modTime?: number;
|
|
512
512
|
}
|
|
513
513
|
/**
|
|
514
|
-
* Read and write files inside a Lizard sandbox
|
|
514
|
+
* Read and write files inside a Lizard sandbox.
|
|
515
515
|
*
|
|
516
516
|
* Access via `sandbox.fs`.
|
|
517
517
|
*/
|
|
@@ -520,23 +520,24 @@ declare class Fs {
|
|
|
520
520
|
private readonly config;
|
|
521
521
|
constructor(sandboxId: string, config: ConnectionConfig);
|
|
522
522
|
/**
|
|
523
|
-
* Write a file into the
|
|
523
|
+
* Write a file into the sandbox filesystem.
|
|
524
524
|
*
|
|
525
525
|
* Creates parent directories automatically if they don't exist.
|
|
526
|
+
* Byte input must contain valid UTF-8; arbitrary binary uploads are unsupported.
|
|
526
527
|
*
|
|
527
528
|
* @example
|
|
528
529
|
* ```ts
|
|
529
530
|
* await sandbox.fs.write('/app/index.js', 'console.log("hello")')
|
|
530
531
|
* ```
|
|
531
532
|
*
|
|
532
|
-
* @example Write
|
|
533
|
+
* @example Write UTF-8 bytes:
|
|
533
534
|
* ```ts
|
|
534
|
-
* await sandbox.fs.write('/app/
|
|
535
|
+
* await sandbox.fs.write('/app/notes.txt', new TextEncoder().encode('hello'))
|
|
535
536
|
* ```
|
|
536
537
|
*/
|
|
537
538
|
write(path: string, data: string | Uint8Array, opts?: FsOpts): Promise<void>;
|
|
538
539
|
/**
|
|
539
|
-
* Read a file from the
|
|
540
|
+
* Read a file from the sandbox filesystem.
|
|
540
541
|
*
|
|
541
542
|
* @returns The file contents as a UTF-8 string.
|
|
542
543
|
*
|
|
@@ -546,22 +547,23 @@ declare class Fs {
|
|
|
546
547
|
* ```
|
|
547
548
|
*/
|
|
548
549
|
read(path: string, opts?: FsOpts): Promise<string>;
|
|
550
|
+
/** Read a file as bytes. */
|
|
551
|
+
readBytes(path: string, opts?: FsOpts): Promise<Uint8Array>;
|
|
549
552
|
/**
|
|
550
|
-
* List files and directories at the given path inside the
|
|
553
|
+
* List files and directories at the given path inside the sandbox.
|
|
551
554
|
*
|
|
552
555
|
* @example
|
|
553
556
|
* ```ts
|
|
554
557
|
* const entries = await sandbox.fs.list('/app')
|
|
555
558
|
* ```
|
|
556
559
|
*/
|
|
557
|
-
readBytes(path: string, opts?: FsOpts): Promise<Uint8Array>;
|
|
558
560
|
list(path: string, opts?: FsOpts): Promise<FileInfo[]>;
|
|
559
561
|
/**
|
|
560
|
-
* Remove a file or directory from the
|
|
562
|
+
* Remove a file or directory from the sandbox filesystem.
|
|
561
563
|
*/
|
|
562
564
|
remove(path: string, opts?: FsOpts): Promise<void>;
|
|
563
565
|
/**
|
|
564
|
-
* Create a directory (and any missing parents) inside the
|
|
566
|
+
* Create a directory (and any missing parents) inside the sandbox.
|
|
565
567
|
*/
|
|
566
568
|
makeDir(path: string, opts?: FsOpts): Promise<void>;
|
|
567
569
|
/**
|
|
@@ -730,10 +732,9 @@ declare class SandboxClient {
|
|
|
730
732
|
}
|
|
731
733
|
|
|
732
734
|
/**
|
|
733
|
-
* A
|
|
735
|
+
* A Linux sandbox running on Kubernetes.
|
|
734
736
|
*
|
|
735
|
-
*
|
|
736
|
-
* process namespace, restored from a pre-warmed template snapshot.
|
|
737
|
+
* Run commands, read and write files, and expose HTTP ports in a sandbox.
|
|
737
738
|
*
|
|
738
739
|
* Sandboxes are **ephemeral**: killing one, or letting it hit its timeout, discards
|
|
739
740
|
* everything written inside it. State that has to outlive a sandbox belongs on a
|
|
@@ -745,10 +746,14 @@ declare class SandboxClient {
|
|
|
745
746
|
* import { Sandbox } from '@lizard-build/sdk'
|
|
746
747
|
*
|
|
747
748
|
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
749
|
+
* try {
|
|
750
|
+
* await sandbox.fs.write('/tmp/hello.txt', 'hello world')
|
|
751
|
+
* const result = await sandbox.process.exec('cat /tmp/hello.txt')
|
|
752
|
+
* if (result.exitCode !== 0) throw new Error(result.stderr)
|
|
753
|
+
* console.log(result.stdout)
|
|
754
|
+
* } finally {
|
|
755
|
+
* await sandbox.kill()
|
|
756
|
+
* }
|
|
752
757
|
* ```
|
|
753
758
|
*
|
|
754
759
|
* @example Carry work across sandboxes with a volume:
|
|
@@ -769,11 +774,11 @@ declare class Sandbox extends SandboxClient {
|
|
|
769
774
|
protected static readonly defaultTemplate: string;
|
|
770
775
|
protected static readonly defaultTimeoutMs: number;
|
|
771
776
|
/**
|
|
772
|
-
* Unique identifier of this sandbox
|
|
777
|
+
* Unique identifier of this sandbox.
|
|
773
778
|
*/
|
|
774
779
|
readonly sandboxId: string;
|
|
775
780
|
/**
|
|
776
|
-
* Read and write files inside the
|
|
781
|
+
* Read and write files inside the sandbox filesystem.
|
|
777
782
|
*
|
|
778
783
|
* @example
|
|
779
784
|
* ```ts
|
|
@@ -783,7 +788,7 @@ declare class Sandbox extends SandboxClient {
|
|
|
783
788
|
*/
|
|
784
789
|
readonly fs: Fs;
|
|
785
790
|
/**
|
|
786
|
-
* Execute processes inside the
|
|
791
|
+
* Execute processes inside the sandbox.
|
|
787
792
|
*
|
|
788
793
|
* @example
|
|
789
794
|
* ```ts
|
|
@@ -807,16 +812,15 @@ declare class Sandbox extends SandboxClient {
|
|
|
807
812
|
/**
|
|
808
813
|
* Create a new Lizard sandbox from the specified template.
|
|
809
814
|
*
|
|
810
|
-
*
|
|
811
|
-
*
|
|
812
|
-
* `lizard push`.
|
|
815
|
+
* Template availability and installed tools depend on the platform and region.
|
|
816
|
+
* Use `base` for shell commands or `CodeSandbox` for stateful code execution.
|
|
813
817
|
*
|
|
814
818
|
* @param template Name of the sandbox template to boot from.
|
|
815
819
|
*
|
|
816
820
|
* @example
|
|
817
821
|
* ```ts
|
|
818
822
|
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
819
|
-
* const
|
|
823
|
+
* const pythonSandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project', timeoutMs: 10 * 60 * 1000 })
|
|
820
824
|
* ```
|
|
821
825
|
*/
|
|
822
826
|
static create(template: string, opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -826,11 +830,7 @@ declare class Sandbox extends SandboxClient {
|
|
|
826
830
|
* Verifies the sandbox exists and is reachable, then returns a handle to it.
|
|
827
831
|
* Throws `NotFoundError` if it has been killed or has expired.
|
|
828
832
|
*
|
|
829
|
-
*
|
|
830
|
-
* reconnecting to might be paused. Sandboxes are pods now and pause/resume is a
|
|
831
|
-
* `501` on every one of them, so that call turned every `connect()` into an
|
|
832
|
-
* error against a perfectly healthy sandbox. Connecting does not need to change
|
|
833
|
-
* a sandbox's state, so it no longer tries to.
|
|
833
|
+
* Connecting reads sandbox metadata without changing its state.
|
|
834
834
|
*
|
|
835
835
|
* @example
|
|
836
836
|
* ```ts
|
|
@@ -852,25 +852,21 @@ declare class Sandbox extends SandboxClient {
|
|
|
852
852
|
/**
|
|
853
853
|
* Kill the sandbox and release its resources immediately.
|
|
854
854
|
*
|
|
855
|
-
* @returns `true` if the
|
|
855
|
+
* @returns `true` if the sandbox was terminated, `false` if it was already gone.
|
|
856
856
|
*/
|
|
857
857
|
kill(opts?: ConnectionOpts): Promise<boolean>;
|
|
858
858
|
/**
|
|
859
|
-
*
|
|
859
|
+
* Request sandbox pause. The Kubernetes backend returns HTTP 501.
|
|
860
860
|
*
|
|
861
|
-
* @deprecated
|
|
862
|
-
*
|
|
863
|
-
* checkpoint of the pod, which is not built. To park work across a gap, put it on a
|
|
864
|
-
* {@link Volume} and create a fresh sandbox on that volume later; the volume is the
|
|
865
|
-
* part that is meant to outlive a sandbox.
|
|
861
|
+
* @deprecated Unsupported on Kubernetes. Save files to a {@link Volume}
|
|
862
|
+
* and attach it to a new sandbox instead.
|
|
866
863
|
*/
|
|
867
864
|
pause(opts?: ConnectionOpts): Promise<boolean>;
|
|
868
865
|
/**
|
|
869
|
-
*
|
|
866
|
+
* Request sandbox resume. The Kubernetes backend returns HTTP 501.
|
|
870
867
|
*
|
|
871
|
-
* @deprecated
|
|
872
|
-
*
|
|
873
|
-
* calls this, so reconnecting to a running sandbox works without it.
|
|
868
|
+
* @deprecated Unsupported on Kubernetes. Use {@link Sandbox.connect} to
|
|
869
|
+
* reconnect to a running sandbox.
|
|
874
870
|
*/
|
|
875
871
|
resume(opts?: ConnectionOpts): Promise<boolean>;
|
|
876
872
|
/**
|
|
@@ -884,23 +880,25 @@ declare class Sandbox extends SandboxClient {
|
|
|
884
880
|
*/
|
|
885
881
|
setTimeout(timeoutMs: number, opts?: ConnectionOpts): Promise<void>;
|
|
886
882
|
/**
|
|
887
|
-
*
|
|
883
|
+
* Register a public HTTPS route and return its hostname without a scheme.
|
|
888
884
|
*
|
|
889
|
-
* Useful for accessing HTTP servers started inside the
|
|
885
|
+
* Useful for accessing HTTP servers started inside the sandbox from your
|
|
890
886
|
* agent or tests without additional tunneling.
|
|
891
887
|
*
|
|
892
888
|
* @example
|
|
893
889
|
* ```ts
|
|
894
|
-
*
|
|
895
|
-
* const
|
|
896
|
-
*
|
|
890
|
+
* // Start an HTTP server on port 3000 before exposing it.
|
|
891
|
+
* const hostname = await sandbox.getHost(3000)
|
|
892
|
+
* console.log(`https://${hostname}`)
|
|
897
893
|
* ```
|
|
898
894
|
*/
|
|
899
895
|
getHost(port: number, opts?: ConnectionOpts): Promise<string>;
|
|
896
|
+
/** Fork is unsupported on Kubernetes; the backend returns HTTP 501. */
|
|
900
897
|
fork(opts?: {
|
|
901
898
|
count?: number;
|
|
902
899
|
timeoutMs?: number;
|
|
903
900
|
}): Promise<unknown>;
|
|
901
|
+
/** Snapshot creation is unsupported on Kubernetes; the backend returns HTTP 501. */
|
|
904
902
|
snapshot(name?: string): Promise<unknown>;
|
|
905
903
|
unexpose(port: number): Promise<void>;
|
|
906
904
|
logs(opts?: {
|
|
@@ -908,6 +906,7 @@ declare class Sandbox extends SandboxClient {
|
|
|
908
906
|
signal?: AbortSignal;
|
|
909
907
|
}): AsyncGenerator<StreamEvent, any, any>;
|
|
910
908
|
static snapshots(projectId: string, opts?: ConnectionOpts): Promise<unknown[]>;
|
|
909
|
+
/** Snapshot restore is unsupported on Kubernetes; the backend returns HTTP 501. */
|
|
911
910
|
static restore(snapshotId: string, opts?: ConnectionOpts & {
|
|
912
911
|
timeoutMs?: number;
|
|
913
912
|
}): Promise<Sandbox>;
|
|
@@ -1353,6 +1352,12 @@ interface VolumeInfo {
|
|
|
1353
1352
|
status: string;
|
|
1354
1353
|
attachedTo?: string | null;
|
|
1355
1354
|
createdAt: number;
|
|
1355
|
+
/**
|
|
1356
|
+
* Whether `sizeGb` is actually enforced as a hard limit on the volume's node.
|
|
1357
|
+
* Returned by {@link Volume.resize}; `false` means the size was recorded but the
|
|
1358
|
+
* node cannot enforce it, so writes past it are not refused.
|
|
1359
|
+
*/
|
|
1360
|
+
sizeEnforced?: boolean;
|
|
1356
1361
|
}
|
|
1357
1362
|
interface CreateVolumeOpts extends ConnectionOpts {
|
|
1358
1363
|
/** Whole GB, default 5. New volumes allow 1–50 GB unless the server config sets another maximum. Existing volumes are never resized. */
|
|
@@ -1400,8 +1405,8 @@ declare class Volume {
|
|
|
1400
1405
|
* exist yet. This is the reason a volume's name is its key: an agent that wants
|
|
1401
1406
|
* "the scratch disk for this task" no longer has to store an id between runs.
|
|
1402
1407
|
*
|
|
1403
|
-
* An existing volume is returned as-is — `sizeGb` applies only to a fresh create
|
|
1404
|
-
*
|
|
1408
|
+
* An existing volume is returned as-is — `sizeGb` applies only to a fresh create,
|
|
1409
|
+
* so an existing volume keeps its size. Call {@link Volume.resize} to change it.
|
|
1405
1410
|
*/
|
|
1406
1411
|
static getOrCreate(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
1407
1412
|
/** Look a volume up by name or by id. */
|
|
@@ -1409,7 +1414,26 @@ declare class Volume {
|
|
|
1409
1414
|
static list(projectId: string, opts?: ConnectionOpts): Promise<VolumeInfo[]>;
|
|
1410
1415
|
/** Delete a volume by name or by id, without constructing one first. */
|
|
1411
1416
|
static delete(projectId: string, nameOrId: string, opts?: ConnectionOpts): Promise<void>;
|
|
1417
|
+
/**
|
|
1418
|
+
* Resize a volume, by name or by id, to `sizeGb`.
|
|
1419
|
+
*
|
|
1420
|
+
* The change is in place and online: the size is a quota, so no data is copied,
|
|
1421
|
+
* it completes in well under a second, and a sandbox that has the volume mounted
|
|
1422
|
+
* keeps running and sees the new size immediately. Both growing and shrinking are
|
|
1423
|
+
* allowed, but a shrink must leave at least 10% of the new size free — otherwise
|
|
1424
|
+
* it throws `ConflictError` with `code: 'volume_too_full_to_shrink'`.
|
|
1425
|
+
*
|
|
1426
|
+
* Other failures carry a `code` too: `invalid_volume_size`, `volume_not_resizable`,
|
|
1427
|
+
* `volume_resize_in_progress`, `volume_not_provisioned`,
|
|
1428
|
+
* `volume_capacity_unavailable`, and `volume_resize_timeout` (a `TimeoutError`;
|
|
1429
|
+
* the size is left unchanged).
|
|
1430
|
+
*
|
|
1431
|
+
* @returns The volume's updated info, including `sizeEnforced`.
|
|
1432
|
+
*/
|
|
1433
|
+
static resize(projectId: string, nameOrId: string, sizeGb: number, opts?: ConnectionOpts): Promise<VolumeInfo>;
|
|
1412
1434
|
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
1435
|
+
/** Resize this volume in place — see the static {@link Volume.resize}. */
|
|
1436
|
+
resize(projectId: string, sizeGb: number): Promise<VolumeInfo>;
|
|
1413
1437
|
delete(projectId: string): Promise<void>;
|
|
1414
1438
|
}
|
|
1415
1439
|
|
|
@@ -1509,6 +1533,7 @@ declare class Lizard {
|
|
|
1509
1533
|
getOrCreate: (name: string, opts?: CreateVolumeOpts) => Promise<Volume>;
|
|
1510
1534
|
get: (nameOrId: string, opts?: ConnectionOpts) => Promise<Volume>;
|
|
1511
1535
|
list: (opts?: ConnectionOpts) => Promise<VolumeInfo[]>;
|
|
1536
|
+
resize: (nameOrId: string, sizeGb: number, opts?: ConnectionOpts) => Promise<VolumeInfo>;
|
|
1512
1537
|
delete: (nameOrId: string, opts?: ConnectionOpts) => Promise<void>;
|
|
1513
1538
|
};
|
|
1514
1539
|
/**
|
|
@@ -1558,6 +1583,13 @@ interface Account {
|
|
|
1558
1583
|
declare function resolveProjectId(ref: string, config: ConnectionConfig): Promise<string>;
|
|
1559
1584
|
|
|
1560
1585
|
declare class LizardError extends Error {
|
|
1586
|
+
/** HTTP status of the failed API call, when the error came from one. */
|
|
1587
|
+
status?: number;
|
|
1588
|
+
/**
|
|
1589
|
+
* The server's machine-readable error code, when it sent one — e.g.
|
|
1590
|
+
* `'volume_too_full_to_shrink'`. Branch on this rather than on `message`.
|
|
1591
|
+
*/
|
|
1592
|
+
code?: string;
|
|
1561
1593
|
constructor(message: string);
|
|
1562
1594
|
}
|
|
1563
1595
|
/** Config was saved, but one or more deploy/restart actions failed. Never retry blindly. */
|
|
@@ -1602,7 +1634,7 @@ type OutputItem = {
|
|
|
1602
1634
|
message: string;
|
|
1603
1635
|
traceback: string;
|
|
1604
1636
|
};
|
|
1605
|
-
/** Error
|
|
1637
|
+
/** Error returned in Execution.error when executed code raises an exception. */
|
|
1606
1638
|
declare class ExecutionError extends Error {
|
|
1607
1639
|
readonly name: string;
|
|
1608
1640
|
readonly traceback: string;
|
|
@@ -1637,7 +1669,7 @@ interface RunCodeOpts {
|
|
|
1637
1669
|
context?: CodeContext;
|
|
1638
1670
|
/** Extra environment variables available to the code. */
|
|
1639
1671
|
envs?: Record<string, string>;
|
|
1640
|
-
/**
|
|
1672
|
+
/** Client timeout in milliseconds. No client timer is set when omitted. */
|
|
1641
1673
|
timeoutMs?: number;
|
|
1642
1674
|
onStdout?: (data: string) => void;
|
|
1643
1675
|
onStderr?: (data: string) => void;
|
|
@@ -1659,7 +1691,7 @@ interface CreateContextOpts {
|
|
|
1659
1691
|
*
|
|
1660
1692
|
* @example
|
|
1661
1693
|
* ```ts
|
|
1662
|
-
* import { CodeSandbox } from 'lizard/
|
|
1694
|
+
* import { CodeSandbox } from '@lizard-build/sdk'
|
|
1663
1695
|
*
|
|
1664
1696
|
* const sandbox = await CodeSandbox.create({ project: 'my-project' })
|
|
1665
1697
|
*
|
|
@@ -1690,8 +1722,7 @@ declare class CodeSandbox extends Sandbox {
|
|
|
1690
1722
|
*
|
|
1691
1723
|
* @returns Execution result with stdout, stderr, results, and any error.
|
|
1692
1724
|
*
|
|
1693
|
-
*
|
|
1694
|
-
* default context exists — which cannot happen in normal usage.
|
|
1725
|
+
* Code errors appear in `execution.error`; request failures throw.
|
|
1695
1726
|
*
|
|
1696
1727
|
* @example
|
|
1697
1728
|
* ```ts
|