@lizard-build/sdk 0.1.34 → 0.1.36
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 +93 -27
- package/dist/index.d.mts +422 -101
- package/dist/index.d.ts +422 -101
- package/dist/index.js +279 -113
- package/dist/index.mjs +268 -113
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -271,6 +271,11 @@ interface SandboxInfo {
|
|
|
271
271
|
template: string;
|
|
272
272
|
startedAt: string;
|
|
273
273
|
endAt: string;
|
|
274
|
+
/** Region the sandbox runs in — the volume's region when one is attached. */
|
|
275
|
+
region?: string;
|
|
276
|
+
status?: string;
|
|
277
|
+
cpus?: number;
|
|
278
|
+
memoryMb?: number;
|
|
274
279
|
metadata?: Record<string, string>;
|
|
275
280
|
}
|
|
276
281
|
interface SandboxOpts extends ConnectionOpts {
|
|
@@ -287,6 +292,17 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
287
292
|
metadata?: Record<string, string>;
|
|
288
293
|
envs?: Record<string, string>;
|
|
289
294
|
timeoutMs?: number;
|
|
295
|
+
/**
|
|
296
|
+
* Region to run the sandbox in, e.g. `'us-east-1'`.
|
|
297
|
+
*
|
|
298
|
+
* Leave it unset when attaching a volume: a volume is node-local, so the server
|
|
299
|
+
* places the sandbox in the volume's own region. Setting it to a region the volume
|
|
300
|
+
* is not in is rejected with a 400 rather than silently moved — that combination
|
|
301
|
+
* cannot be satisfied.
|
|
302
|
+
*
|
|
303
|
+
* Defaults to the platform's default sandbox region.
|
|
304
|
+
*/
|
|
305
|
+
region?: string;
|
|
290
306
|
/** Attach a persistent volume by id, mounted at `/data`. */
|
|
291
307
|
volumeId?: string;
|
|
292
308
|
/**
|
|
@@ -295,6 +311,27 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
295
311
|
* Requires the sandbox's project to be given as an exact `projectId`.
|
|
296
312
|
*/
|
|
297
313
|
volumeName?: string;
|
|
314
|
+
/**
|
|
315
|
+
* A `liz_` API key to write into the sandbox, so `lizard` works inside it. The CLI is
|
|
316
|
+
* preinstalled in every template; this is what authenticates it.
|
|
317
|
+
*
|
|
318
|
+
* The key must belong to the caller — the server verifies that and silently skips the
|
|
319
|
+
* injection otherwise.
|
|
320
|
+
*
|
|
321
|
+
* SECURITY: anything running in the sandbox can read this key, and sandboxes run
|
|
322
|
+
* untrusted code. Pass a WORKSPACE-SCOPED key rather than a full-access one. Scopes are
|
|
323
|
+
* enforced end to end, so a scoped key that escapes is bounded to that one workspace.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```ts
|
|
327
|
+
* const sandbox = await Sandbox.create('codex', {
|
|
328
|
+
* projectId: 'proj_123',
|
|
329
|
+
* lizardToken: process.env.LIZARD_WORKSPACE_KEY, // scoped to one workspace
|
|
330
|
+
* })
|
|
331
|
+
* await sandbox.process.exec('lizard volume list')
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
lizardToken?: string;
|
|
298
335
|
}
|
|
299
336
|
/**
|
|
300
337
|
* Low-level HTTP client for the Lizard sandbox API.
|
|
@@ -317,13 +354,15 @@ declare class SandboxClient {
|
|
|
317
354
|
}
|
|
318
355
|
|
|
319
356
|
/**
|
|
320
|
-
* A Lizard sandbox — an isolated
|
|
357
|
+
* A Lizard sandbox — an isolated Linux environment that starts in under a second.
|
|
358
|
+
*
|
|
359
|
+
* Each sandbox is a full Linux environment with its own filesystem, network, and
|
|
360
|
+
* process namespace, restored from a pre-warmed template snapshot.
|
|
321
361
|
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* execution.
|
|
362
|
+
* Sandboxes are **ephemeral**: killing one, or letting it hit its timeout, discards
|
|
363
|
+
* everything written inside it. State that has to outlive a sandbox belongs on a
|
|
364
|
+
* {@link Volume}, which is a separate disk you mount at `/data` and re-attach to a
|
|
365
|
+
* later sandbox.
|
|
327
366
|
*
|
|
328
367
|
* @example Basic usage:
|
|
329
368
|
* ```ts
|
|
@@ -336,16 +375,18 @@ declare class SandboxClient {
|
|
|
336
375
|
* await sandbox.kill()
|
|
337
376
|
* ```
|
|
338
377
|
*
|
|
339
|
-
* @example
|
|
378
|
+
* @example Carry work across sandboxes with a volume:
|
|
340
379
|
* ```ts
|
|
341
|
-
* const
|
|
342
|
-
* await sandbox.process.exec('pip install numpy')
|
|
343
|
-
* const id = sandbox.sandboxId
|
|
344
|
-
* await sandbox.pause()
|
|
380
|
+
* const vol = await Volume.getOrCreate(projectId, 'agent-scratch', { sizeGb: 10 })
|
|
345
381
|
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
* await
|
|
382
|
+
* const first = await Sandbox.create('codex', { projectId, volumeName: 'agent-scratch' })
|
|
383
|
+
* await first.process.exec('echo "notes" > /data/notes.txt')
|
|
384
|
+
* await first.kill()
|
|
385
|
+
*
|
|
386
|
+
* // A different sandbox, the same disk. No region to thread through: the sandbox
|
|
387
|
+
* // is placed wherever the volume already lives.
|
|
388
|
+
* const second = await Sandbox.create('codex', { projectId, volumeName: 'agent-scratch' })
|
|
389
|
+
* console.log(await second.fs.read('/data/notes.txt')) // "notes"
|
|
349
390
|
* ```
|
|
350
391
|
*/
|
|
351
392
|
declare class Sandbox extends SandboxClient {
|
|
@@ -406,8 +447,14 @@ declare class Sandbox extends SandboxClient {
|
|
|
406
447
|
/**
|
|
407
448
|
* Connect to an existing sandbox by its ID.
|
|
408
449
|
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
450
|
+
* Verifies the sandbox exists and is reachable, then returns a handle to it.
|
|
451
|
+
* Throws `NotFoundError` if it has been killed or has expired.
|
|
452
|
+
*
|
|
453
|
+
* This used to call `resume` first, on the assumption that a sandbox you are
|
|
454
|
+
* reconnecting to might be paused. Sandboxes are pods now and pause/resume is a
|
|
455
|
+
* `501` on every one of them, so that call turned every `connect()` into an
|
|
456
|
+
* error against a perfectly healthy sandbox. Connecting does not need to change
|
|
457
|
+
* a sandbox's state, so it no longer tries to.
|
|
411
458
|
*
|
|
412
459
|
* @example
|
|
413
460
|
* ```ts
|
|
@@ -431,35 +478,21 @@ declare class Sandbox extends SandboxClient {
|
|
|
431
478
|
*/
|
|
432
479
|
kill(opts?: ConnectionOpts): Promise<boolean>;
|
|
433
480
|
/**
|
|
434
|
-
* Pause the sandbox
|
|
481
|
+
* Pause the sandbox by freezing it in place.
|
|
435
482
|
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
* expiry forward by however long the sandbox was paused — so a pause/resume cycle
|
|
442
|
-
* costs no runtime — but that adjustment only happens on `resume()`. A sandbox left
|
|
443
|
-
* paused past its original `expiresAt` is deleted there, within a minute, and
|
|
444
|
-
* `resume()` then returns `false`.
|
|
445
|
-
*
|
|
446
|
-
* In other words: pause and come back *before* the original deadline and you lose
|
|
447
|
-
* nothing; leave it paused across the deadline and it is gone. Pass `timeoutMs: 0`
|
|
448
|
-
* at create time to opt out of expiry entirely, which is the only way to park a
|
|
449
|
-
* sandbox indefinitely.
|
|
450
|
-
*
|
|
451
|
-
* @returns `true` if paused successfully.
|
|
483
|
+
* @deprecated Not implemented for the current runtime — always throws
|
|
484
|
+
* `LizardError` with HTTP 501. Sandboxes run as pods, and the equivalent is a CRIU
|
|
485
|
+
* checkpoint of the pod, which is not built. To park work across a gap, put it on a
|
|
486
|
+
* {@link Volume} and create a fresh sandbox on that volume later; the volume is the
|
|
487
|
+
* part that is meant to outlive a sandbox.
|
|
452
488
|
*/
|
|
453
489
|
pause(opts?: ConnectionOpts): Promise<boolean>;
|
|
454
490
|
/**
|
|
455
|
-
* Resume a paused sandbox
|
|
456
|
-
*
|
|
457
|
-
* The expiry is pushed forward by the time spent paused, so the timeout measures
|
|
458
|
-
* running time rather than wall-clock — provided the original deadline had not
|
|
459
|
-
* already passed while paused. See {@link pause}.
|
|
491
|
+
* Resume a paused sandbox.
|
|
460
492
|
*
|
|
461
|
-
* @
|
|
462
|
-
*
|
|
493
|
+
* @deprecated Not implemented for the current runtime — always throws
|
|
494
|
+
* `LizardError` with HTTP 501. See {@link pause}. `Sandbox.connect()` no longer
|
|
495
|
+
* calls this, so reconnecting to a running sandbox works without it.
|
|
463
496
|
*/
|
|
464
497
|
resume(opts?: ConnectionOpts): Promise<boolean>;
|
|
465
498
|
/**
|
|
@@ -851,6 +884,304 @@ declare class MetricsAPI {
|
|
|
851
884
|
all(id: string, range?: MetricRange): Promise<ServiceMetrics>;
|
|
852
885
|
}
|
|
853
886
|
|
|
887
|
+
interface Workspace {
|
|
888
|
+
id: string;
|
|
889
|
+
name: string;
|
|
890
|
+
slug: string;
|
|
891
|
+
/** `owner` | `admin` | `member` — the calling account's role in this workspace. */
|
|
892
|
+
role?: string;
|
|
893
|
+
/** True for the account's own workspace, which cannot be deleted. */
|
|
894
|
+
isPersonal?: boolean;
|
|
895
|
+
projectCount?: number;
|
|
896
|
+
plan?: string;
|
|
897
|
+
createdAt?: number | string;
|
|
898
|
+
}
|
|
899
|
+
interface CreateWorkspaceOpts {
|
|
900
|
+
name: string;
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* Workspaces — the top of the ownership tree: a workspace holds projects, a project
|
|
904
|
+
* holds services, sandboxes and volumes.
|
|
905
|
+
*
|
|
906
|
+
* This is the missing first step of per-user provisioning. Handing each of your users
|
|
907
|
+
* their own workspace, plus an API key scoped to it, is what keeps them isolated from
|
|
908
|
+
* one another while all of it bills to your account:
|
|
909
|
+
*
|
|
910
|
+
* ```ts
|
|
911
|
+
* const ws = await lizard.workspaces.create({ name: `user-${userId}` })
|
|
912
|
+
* const prj = await lizard.projects.create({ workspaceId: ws.id, name: 'default' })
|
|
913
|
+
* const key = await lizard.apiKeys.create({ name: `user-${userId}`, workspaces: [ws.id] })
|
|
914
|
+
* // hand key.key to that user — it reaches nothing outside ws
|
|
915
|
+
* ```
|
|
916
|
+
*
|
|
917
|
+
* @see {@link ApiKeysAPI} for the scoping half of that flow.
|
|
918
|
+
*/
|
|
919
|
+
declare class WorkspacesAPI {
|
|
920
|
+
private readonly client;
|
|
921
|
+
constructor(client: PlatformClient);
|
|
922
|
+
/**
|
|
923
|
+
* List workspaces the calling credential can see.
|
|
924
|
+
*
|
|
925
|
+
* A scoped API key sees only what it is scoped to: a workspace-scoped key returns
|
|
926
|
+
* that one workspace, and a project-scoped key returns the workspace containing its
|
|
927
|
+
* project. A full key returns every workspace the account belongs to.
|
|
928
|
+
*/
|
|
929
|
+
list(): Promise<Workspace[]>;
|
|
930
|
+
/** Create a workspace. The caller becomes its owner. */
|
|
931
|
+
create(opts: CreateWorkspaceOpts): Promise<Workspace>;
|
|
932
|
+
/**
|
|
933
|
+
* Delete a workspace.
|
|
934
|
+
*
|
|
935
|
+
* Empty-only by default — the server refuses while any project or sandbox remains,
|
|
936
|
+
* so this cannot quietly destroy a user's work. Pass `{ force: true }` to delete a
|
|
937
|
+
* workspace and everything in it; that is irreversible.
|
|
938
|
+
*/
|
|
939
|
+
delete(id: string, opts?: {
|
|
940
|
+
force?: boolean;
|
|
941
|
+
}): Promise<void>;
|
|
942
|
+
/**
|
|
943
|
+
* Find a workspace by name, slug, or id, or `null` if there is no such workspace.
|
|
944
|
+
* Matching is exact; id wins, then slug, then name.
|
|
945
|
+
*/
|
|
946
|
+
find(nameOrSlugOrId: string): Promise<Workspace | null>;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
interface ApiKeyScope {
|
|
950
|
+
type: 'workspace' | 'project';
|
|
951
|
+
id: string;
|
|
952
|
+
/** Present on read; the server resolves the scoped resource's name for display. */
|
|
953
|
+
name?: string;
|
|
954
|
+
}
|
|
955
|
+
interface ApiKey {
|
|
956
|
+
id: string;
|
|
957
|
+
name: string;
|
|
958
|
+
/** A masked fragment, e.g. `liz_abc…xyz`. The full key is only ever returned once. */
|
|
959
|
+
keyPreview?: string;
|
|
960
|
+
scopes: ApiKeyScope[];
|
|
961
|
+
createdAt?: number | string | null;
|
|
962
|
+
lastUsedAt?: number | string | null;
|
|
963
|
+
}
|
|
964
|
+
interface CreatedApiKey extends ApiKey {
|
|
965
|
+
/**
|
|
966
|
+
* The full `liz_` secret. **Returned exactly once, by this create call** — it is
|
|
967
|
+
* stored hashed and no later request can read it back. Hand it to its owner or
|
|
968
|
+
* persist it here, or it is gone.
|
|
969
|
+
*/
|
|
970
|
+
key: string;
|
|
971
|
+
}
|
|
972
|
+
interface CreateApiKeyOpts {
|
|
973
|
+
name: string;
|
|
974
|
+
/** Workspace ids this key may reach. */
|
|
975
|
+
workspaces?: string[];
|
|
976
|
+
/** Project ids this key may reach. */
|
|
977
|
+
projects?: string[];
|
|
978
|
+
/** Raw scope list, if you would rather build it yourself than use the two above. */
|
|
979
|
+
scopes?: ApiKeyScope[];
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* API keys, including the scoped keys that make per-user isolation possible.
|
|
983
|
+
*
|
|
984
|
+
* **A key with no scope has full access** to every workspace and project the creating
|
|
985
|
+
* account can reach. Pass `workspaces` or `projects` to bound it. Scopes are enforced
|
|
986
|
+
* server-side on every route, so a scoped key that leaks — out of a sandbox, a log, a
|
|
987
|
+
* user's machine — reaches only what it was scoped to.
|
|
988
|
+
*
|
|
989
|
+
* A scoped key cannot mint a broader key: that check is server-side and exact, so
|
|
990
|
+
* handing a user a workspace-scoped key is not a step away from full access.
|
|
991
|
+
*
|
|
992
|
+
* @example Give each of your users their own isolated workspace
|
|
993
|
+
* ```ts
|
|
994
|
+
* const ws = await lizard.workspaces.create({ name: `user-${userId}` })
|
|
995
|
+
* const prj = await lizard.projects.create({ workspaceId: ws.id, name: 'default' })
|
|
996
|
+
* const key = await lizard.apiKeys.create({ name: `user-${userId}`, workspaces: [ws.id] })
|
|
997
|
+
*
|
|
998
|
+
* // key.key is visible only here. Store it now.
|
|
999
|
+
* await db.users.update(userId, { lizardKey: key.key })
|
|
1000
|
+
* ```
|
|
1001
|
+
*
|
|
1002
|
+
* @example Let a sandbox use the CLI as that user, and nothing more
|
|
1003
|
+
* ```ts
|
|
1004
|
+
* const sandbox = await Sandbox.create('codex', {
|
|
1005
|
+
* projectId: prj.id,
|
|
1006
|
+
* lizardToken: key.key, // scoped — safe to expose to code in the sandbox
|
|
1007
|
+
* })
|
|
1008
|
+
* await sandbox.process.exec('lizard volume list')
|
|
1009
|
+
* ```
|
|
1010
|
+
*/
|
|
1011
|
+
declare class ApiKeysAPI {
|
|
1012
|
+
private readonly client;
|
|
1013
|
+
constructor(client: PlatformClient);
|
|
1014
|
+
/** List the account's API keys. Previews only — full keys are never returned here. */
|
|
1015
|
+
list(): Promise<ApiKey[]>;
|
|
1016
|
+
/**
|
|
1017
|
+
* Create an API key.
|
|
1018
|
+
*
|
|
1019
|
+
* The response is the only place the full key appears. Omitting every scope creates
|
|
1020
|
+
* a full-access key; the server rejects an attempt to create one from a key that is
|
|
1021
|
+
* itself scoped.
|
|
1022
|
+
*/
|
|
1023
|
+
create(opts: CreateApiKeyOpts): Promise<CreatedApiKey>;
|
|
1024
|
+
/** Revoke a key by id. It stops working immediately, everywhere. */
|
|
1025
|
+
delete(id: string): Promise<void>;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
interface Region {
|
|
1029
|
+
id: string;
|
|
1030
|
+
name?: string;
|
|
1031
|
+
label?: string;
|
|
1032
|
+
country?: string;
|
|
1033
|
+
city?: string;
|
|
1034
|
+
/** False for a region that exists but is not accepting new workloads. */
|
|
1035
|
+
available?: boolean;
|
|
1036
|
+
isDefault?: boolean;
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* The regions workloads can be placed in.
|
|
1040
|
+
*
|
|
1041
|
+
* Region ids are what `Sandbox.create({ region })` and `Volume.create({ region })`
|
|
1042
|
+
* take, so this is how you discover a valid value rather than hardcoding one.
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* const regions = await lizard.regions.list()
|
|
1047
|
+
* console.log(regions.map(r => r.id)) // ['eu-west-lim-a', 'us-east-1', ...]
|
|
1048
|
+
* ```
|
|
1049
|
+
*/
|
|
1050
|
+
declare class RegionsAPI {
|
|
1051
|
+
private readonly client;
|
|
1052
|
+
constructor(client: PlatformClient);
|
|
1053
|
+
/** List every region, including ones not currently accepting workloads. */
|
|
1054
|
+
list(): Promise<Region[]>;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
interface Balance {
|
|
1058
|
+
plan: string;
|
|
1059
|
+
status: 'active' | 'grace' | 'frozen' | string;
|
|
1060
|
+
/** Current balance in cents. Negative means the account is in debt. */
|
|
1061
|
+
balanceCents: number;
|
|
1062
|
+
overdraftLimitCents: number | null;
|
|
1063
|
+
availableCents: number | null;
|
|
1064
|
+
/** Current burn rate in cents per hour, across every running workload. */
|
|
1065
|
+
hourlyRateCents: number;
|
|
1066
|
+
/** Hours of runway left at the current rate, or `null` when nothing is running. */
|
|
1067
|
+
runwayHours: number | null;
|
|
1068
|
+
expiringCents: number;
|
|
1069
|
+
expiringAt: number | null;
|
|
1070
|
+
neverFreeze?: boolean;
|
|
1071
|
+
invoicedMonthly?: boolean;
|
|
1072
|
+
email?: string | null;
|
|
1073
|
+
}
|
|
1074
|
+
interface Transaction {
|
|
1075
|
+
id: string;
|
|
1076
|
+
kind: string;
|
|
1077
|
+
amountCents: number;
|
|
1078
|
+
balanceAfterCents?: number;
|
|
1079
|
+
description?: string;
|
|
1080
|
+
createdAt: number;
|
|
1081
|
+
}
|
|
1082
|
+
interface TransactionPage {
|
|
1083
|
+
items: Transaction[];
|
|
1084
|
+
nextCursor: string | null;
|
|
1085
|
+
}
|
|
1086
|
+
interface ListTransactionsOpts {
|
|
1087
|
+
/** 1-100, default 20. */
|
|
1088
|
+
limit?: number;
|
|
1089
|
+
/** `nextCursor` from a previous page. */
|
|
1090
|
+
cursor?: string;
|
|
1091
|
+
/** Include the daily usage-deduction rows, which are otherwise omitted as noise. */
|
|
1092
|
+
includeUsage?: boolean;
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Account balance and usage.
|
|
1096
|
+
*
|
|
1097
|
+
* Billing is **account-scoped, not workspace-scoped**: every workspace you create for
|
|
1098
|
+
* a user bills to the account that owns the key. That is what makes per-user
|
|
1099
|
+
* workspaces a safe pattern — your users get isolation, you keep one bill — and also
|
|
1100
|
+
* what makes {@link Balance.runwayHours} worth watching before you provision more.
|
|
1101
|
+
*/
|
|
1102
|
+
declare class BillingAPI {
|
|
1103
|
+
private readonly client;
|
|
1104
|
+
constructor(client: PlatformClient);
|
|
1105
|
+
/** Current balance, status, burn rate, and runway. */
|
|
1106
|
+
balance(): Promise<Balance>;
|
|
1107
|
+
/** A page of balance transactions, newest first. */
|
|
1108
|
+
transactions(opts?: ListTransactionsOpts): Promise<TransactionPage>;
|
|
1109
|
+
/** Cost summary for the current billing period, broken down by resource. */
|
|
1110
|
+
summary(): Promise<unknown>;
|
|
1111
|
+
/** Live (not-yet-invoiced) usage accumulating right now. */
|
|
1112
|
+
live(): Promise<unknown>;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
interface VolumeInfo {
|
|
1116
|
+
id: string;
|
|
1117
|
+
projectId: string;
|
|
1118
|
+
name: string;
|
|
1119
|
+
sizeGb: number;
|
|
1120
|
+
sizeMb?: number;
|
|
1121
|
+
/** Region the volume's node lives in. A sandbox mounting it runs here too. */
|
|
1122
|
+
region?: string;
|
|
1123
|
+
status: string;
|
|
1124
|
+
attachedTo?: string | null;
|
|
1125
|
+
createdAt: number;
|
|
1126
|
+
}
|
|
1127
|
+
interface CreateVolumeOpts extends ConnectionOpts {
|
|
1128
|
+
sizeGb?: number;
|
|
1129
|
+
/**
|
|
1130
|
+
* Region to place the volume in, e.g. `'us-east-1'`. A volume is node-local, so
|
|
1131
|
+
* this also fixes where any sandbox mounting it must run — `Sandbox.create` takes
|
|
1132
|
+
* the volume's region automatically when you don't name one, so you normally set
|
|
1133
|
+
* the region here or nowhere.
|
|
1134
|
+
*
|
|
1135
|
+
* Defaults to the platform's default region.
|
|
1136
|
+
*/
|
|
1137
|
+
region?: string;
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* A persistent volume that outlives sandboxes.
|
|
1141
|
+
*
|
|
1142
|
+
* A volume's **name** is its key inside a project: names are unique per project, and
|
|
1143
|
+
* every method here accepts either a name or the generated id wherever a volume is
|
|
1144
|
+
* addressed. Prefer the name — it is the thing you chose and can reconstruct, while
|
|
1145
|
+
* the id only exists after the first create.
|
|
1146
|
+
*
|
|
1147
|
+
* Names are slugs: lowercase letters, digits and dashes, starting and ending with a
|
|
1148
|
+
* letter or digit, up to 64 characters.
|
|
1149
|
+
*
|
|
1150
|
+
* Mount one to a sandbox via `Sandbox.create({ volumeName: 'my-data' })`.
|
|
1151
|
+
*/
|
|
1152
|
+
declare class Volume {
|
|
1153
|
+
/** The volume's generated id. Stable, but you rarely need it — address by name. */
|
|
1154
|
+
readonly volumeId: string;
|
|
1155
|
+
/** The volume's name: unique within its project, and usable anywhere `volumeId` is. */
|
|
1156
|
+
readonly name?: string;
|
|
1157
|
+
private readonly config;
|
|
1158
|
+
constructor(opts: {
|
|
1159
|
+
volumeId: string;
|
|
1160
|
+
name?: string;
|
|
1161
|
+
} & ConnectionOpts);
|
|
1162
|
+
/**
|
|
1163
|
+
* Create a volume. Throws `ConflictError` (409) if the project already has one with
|
|
1164
|
+
* this name — use {@link getOrCreate} when you want "make sure this exists" instead.
|
|
1165
|
+
*/
|
|
1166
|
+
static create(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
1167
|
+
/**
|
|
1168
|
+
* Return the project's volume with this name, creating it first if it does not
|
|
1169
|
+
* exist yet. This is the reason a volume's name is its key: an agent that wants
|
|
1170
|
+
* "the scratch disk for this task" no longer has to store an id between runs.
|
|
1171
|
+
*
|
|
1172
|
+
* An existing volume is returned as-is — `sizeGb` applies only to a fresh create
|
|
1173
|
+
* and never resizes one that is already there.
|
|
1174
|
+
*/
|
|
1175
|
+
static getOrCreate(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
1176
|
+
/** Look a volume up by name or by id. */
|
|
1177
|
+
static get(projectId: string, nameOrId: string, opts?: ConnectionOpts): Promise<Volume>;
|
|
1178
|
+
static list(projectId: string, opts?: ConnectionOpts): Promise<VolumeInfo[]>;
|
|
1179
|
+
/** Delete a volume by name or by id, without constructing one first. */
|
|
1180
|
+
static delete(projectId: string, nameOrId: string, opts?: ConnectionOpts): Promise<void>;
|
|
1181
|
+
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
1182
|
+
delete(projectId: string): Promise<void>;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
854
1185
|
interface LizardOpts extends ConnectionOpts {
|
|
855
1186
|
/**
|
|
856
1187
|
* The project every sandbox created through this client belongs to — its ID,
|
|
@@ -892,6 +1223,14 @@ declare class Lizard {
|
|
|
892
1223
|
private readonly config;
|
|
893
1224
|
private readonly projectRef;
|
|
894
1225
|
private _platform;
|
|
1226
|
+
/** Create, list and delete workspaces — the top of the ownership tree. */
|
|
1227
|
+
readonly workspaces: WorkspacesAPI;
|
|
1228
|
+
/** Mint and revoke API keys, including keys scoped to one workspace or project. */
|
|
1229
|
+
readonly apiKeys: ApiKeysAPI;
|
|
1230
|
+
/** List the regions workloads can be placed in. */
|
|
1231
|
+
readonly regions: RegionsAPI;
|
|
1232
|
+
/** Account balance, burn rate and transactions. */
|
|
1233
|
+
readonly billing: BillingAPI;
|
|
895
1234
|
/** Manage projects. */
|
|
896
1235
|
readonly projects: ProjectsAPI;
|
|
897
1236
|
/** Deploy and manage services. */
|
|
@@ -913,10 +1252,51 @@ declare class Lizard {
|
|
|
913
1252
|
* @requires `project` to be set in the constructor.
|
|
914
1253
|
*/
|
|
915
1254
|
create(template?: string, opts?: Omit<SandboxOpts, 'project' | 'projectId'>): Promise<Sandbox>;
|
|
916
|
-
/** Connect to an existing sandbox by ID
|
|
1255
|
+
/** Connect to an existing sandbox by ID. Throws `NotFoundError` if it is gone. */
|
|
917
1256
|
connect(sandboxId: string, opts?: ConnectionOpts): Promise<Sandbox>;
|
|
918
1257
|
/** List running sandboxes for the authenticated account. */
|
|
919
1258
|
list(opts?: ConnectionOpts): Promise<SandboxInfo[]>;
|
|
1259
|
+
/**
|
|
1260
|
+
* Persistent volumes in this client's project.
|
|
1261
|
+
*
|
|
1262
|
+
* The same calls as the static {@link Volume} methods, minus the `projectId`
|
|
1263
|
+
* argument — the client already knows it.
|
|
1264
|
+
*
|
|
1265
|
+
* @requires `project` to be set in the constructor.
|
|
1266
|
+
*
|
|
1267
|
+
* @example
|
|
1268
|
+
* ```ts
|
|
1269
|
+
* const lizard = new Lizard({ project: 'my-project' })
|
|
1270
|
+
* const vol = await lizard.volumes.getOrCreate('scratch', { sizeGb: 10 })
|
|
1271
|
+
* const sb = await lizard.create('codex', { volumeName: 'scratch' })
|
|
1272
|
+
* ```
|
|
1273
|
+
*/
|
|
1274
|
+
readonly volumes: {
|
|
1275
|
+
create: (name: string, opts?: CreateVolumeOpts) => Promise<Volume>;
|
|
1276
|
+
getOrCreate: (name: string, opts?: CreateVolumeOpts) => Promise<Volume>;
|
|
1277
|
+
get: (nameOrId: string, opts?: ConnectionOpts) => Promise<Volume>;
|
|
1278
|
+
list: (opts?: ConnectionOpts) => Promise<VolumeInfo[]>;
|
|
1279
|
+
delete: (nameOrId: string, opts?: ConnectionOpts) => Promise<void>;
|
|
1280
|
+
};
|
|
1281
|
+
/**
|
|
1282
|
+
* The account this credential belongs to — the SDK's `lizard whoami`.
|
|
1283
|
+
*
|
|
1284
|
+
* Works for a scoped key as well as a full one: the identity is the account that
|
|
1285
|
+
* created the key, which is what the key's usage bills to.
|
|
1286
|
+
*/
|
|
1287
|
+
whoami(): Promise<Account>;
|
|
1288
|
+
/** The underlying HTTP client, for endpoints this SDK does not wrap yet. */
|
|
1289
|
+
get platform(): PlatformClient;
|
|
1290
|
+
}
|
|
1291
|
+
/** The account behind a credential — see {@link Lizard.whoami}. */
|
|
1292
|
+
interface Account {
|
|
1293
|
+
id: string;
|
|
1294
|
+
username: string;
|
|
1295
|
+
email?: string | null;
|
|
1296
|
+
avatarUrl?: string | null;
|
|
1297
|
+
plan?: string;
|
|
1298
|
+
billingStatus?: string;
|
|
1299
|
+
balanceCents?: number;
|
|
920
1300
|
}
|
|
921
1301
|
|
|
922
1302
|
/**
|
|
@@ -1099,63 +1479,4 @@ declare class CodeSandbox extends Sandbox {
|
|
|
1099
1479
|
static connect(sandboxId: string, opts?: ConnectionOpts): Promise<CodeSandbox>;
|
|
1100
1480
|
}
|
|
1101
1481
|
|
|
1102
|
-
|
|
1103
|
-
id: string;
|
|
1104
|
-
projectId: string;
|
|
1105
|
-
name: string;
|
|
1106
|
-
sizeGb: number;
|
|
1107
|
-
sizeMb?: number;
|
|
1108
|
-
status: string;
|
|
1109
|
-
attachedTo?: string | null;
|
|
1110
|
-
createdAt: number;
|
|
1111
|
-
}
|
|
1112
|
-
interface CreateVolumeOpts extends ConnectionOpts {
|
|
1113
|
-
sizeGb?: number;
|
|
1114
|
-
}
|
|
1115
|
-
/**
|
|
1116
|
-
* A persistent volume that outlives sandboxes.
|
|
1117
|
-
*
|
|
1118
|
-
* A volume's **name** is its key inside a project: names are unique per project, and
|
|
1119
|
-
* every method here accepts either a name or the generated id wherever a volume is
|
|
1120
|
-
* addressed. Prefer the name — it is the thing you chose and can reconstruct, while
|
|
1121
|
-
* the id only exists after the first create.
|
|
1122
|
-
*
|
|
1123
|
-
* Names are slugs: lowercase letters, digits and dashes, starting and ending with a
|
|
1124
|
-
* letter or digit, up to 64 characters.
|
|
1125
|
-
*
|
|
1126
|
-
* Mount one to a sandbox via `Sandbox.create({ volumeName: 'my-data' })`.
|
|
1127
|
-
*/
|
|
1128
|
-
declare class Volume {
|
|
1129
|
-
/** The volume's generated id. Stable, but you rarely need it — address by name. */
|
|
1130
|
-
readonly volumeId: string;
|
|
1131
|
-
/** The volume's name: unique within its project, and usable anywhere `volumeId` is. */
|
|
1132
|
-
readonly name?: string;
|
|
1133
|
-
private readonly config;
|
|
1134
|
-
constructor(opts: {
|
|
1135
|
-
volumeId: string;
|
|
1136
|
-
name?: string;
|
|
1137
|
-
} & ConnectionOpts);
|
|
1138
|
-
/**
|
|
1139
|
-
* Create a volume. Throws `ConflictError` (409) if the project already has one with
|
|
1140
|
-
* this name — use {@link getOrCreate} when you want "make sure this exists" instead.
|
|
1141
|
-
*/
|
|
1142
|
-
static create(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
1143
|
-
/**
|
|
1144
|
-
* Return the project's volume with this name, creating it first if it does not
|
|
1145
|
-
* exist yet. This is the reason a volume's name is its key: an agent that wants
|
|
1146
|
-
* "the scratch disk for this task" no longer has to store an id between runs.
|
|
1147
|
-
*
|
|
1148
|
-
* An existing volume is returned as-is — `sizeGb` applies only to a fresh create
|
|
1149
|
-
* and never resizes one that is already there.
|
|
1150
|
-
*/
|
|
1151
|
-
static getOrCreate(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
1152
|
-
/** Look a volume up by name or by id. */
|
|
1153
|
-
static get(projectId: string, nameOrId: string, opts?: ConnectionOpts): Promise<Volume>;
|
|
1154
|
-
static list(projectId: string, opts?: ConnectionOpts): Promise<VolumeInfo[]>;
|
|
1155
|
-
/** Delete a volume by name or by id, without constructing one first. */
|
|
1156
|
-
static delete(projectId: string, nameOrId: string, opts?: ConnectionOpts): Promise<void>;
|
|
1157
|
-
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
1158
|
-
delete(projectId: string): Promise<void>;
|
|
1159
|
-
}
|
|
1160
|
-
|
|
1161
|
-
export { type Addon, type AddonType, AuthenticationError, type CodeContext, CodeSandbox, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type DeployEvent, DeployHandle, type DomainInfo, Execution, ExecutionError, type FileInfo, type FsOpts, Lizard, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, NotFoundError, type ProcessOpts, type ProcessResult, type Project, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type ScaleOpts, type Secret, type Service, type ServiceMetrics, type SetSecretOpts, TimeoutError, Volume, type VolumeInfo, resolveProjectId };
|
|
1482
|
+
export { type Account, type Addon, type AddonType, AddonsAPI, type ApiKey, type ApiKeyScope, ApiKeysAPI, AuthenticationError, type Balance, BillingAPI, type CodeContext, CodeSandbox, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateApiKeyOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type CreateWorkspaceOpts, type CreatedApiKey, type DeployEvent, DeployHandle, type DomainInfo, DomainsAPI, Execution, ExecutionError, type FileInfo, type FsOpts, type ListTransactionsOpts, Lizard, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, MetricsAPI, NotFoundError, PlatformClient, type ProcessOpts, type ProcessResult, type Project, ProjectsAPI, type Region, RegionsAPI, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type ScaleOpts, type Secret, SecretsAPI, type Service, type ServiceMetrics, ServicesAPI, type SetSecretOpts, TimeoutError, type Transaction, type TransactionPage, Volume, type VolumeInfo, type Workspace, WorkspacesAPI, resolveProjectId };
|