@lizard-build/sdk 0.1.20 → 0.1.21
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 +32 -14
- package/dist/index.d.mts +71 -10
- package/dist/index.d.ts +71 -10
- package/dist/index.js +81 -8
- package/dist/index.mjs +78 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,10 +19,15 @@ pip install lizard-sdk
|
|
|
19
19
|
### JavaScript / TypeScript
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import {
|
|
22
|
+
import { Lizard } from '@lizard-build/sdk'
|
|
23
|
+
|
|
24
|
+
// A client is pinned to one project — sandboxes are billed per project, so a
|
|
25
|
+
// project is required. It can be the project's ID, slug, or name.
|
|
26
|
+
// apiKey defaults to the LIZARD_API_KEY env var.
|
|
27
|
+
const lizard = new Lizard({ project: 'my-project' })
|
|
23
28
|
|
|
24
29
|
// Boot a microVM from the 'base' template (Debian + Node.js 20)
|
|
25
|
-
const sandbox = await
|
|
30
|
+
const sandbox = await lizard.create('base')
|
|
26
31
|
|
|
27
32
|
// Write a file directly into the microVM filesystem
|
|
28
33
|
await sandbox.fs.write('/app/server.js', `
|
|
@@ -44,10 +49,14 @@ await sandbox.kill()
|
|
|
44
49
|
### Python
|
|
45
50
|
|
|
46
51
|
```python
|
|
47
|
-
from lizard import
|
|
52
|
+
from lizard import Lizard
|
|
53
|
+
|
|
54
|
+
# A client is pinned to one project — sandboxes are billed per project, so a
|
|
55
|
+
# project is required (its ID, slug, or name). api_key defaults to LIZARD_API_KEY.
|
|
56
|
+
lizard = Lizard(project="my-project")
|
|
48
57
|
|
|
49
58
|
# Boot a Python microVM from the 'code-interpreter-v1' template
|
|
50
|
-
sandbox =
|
|
59
|
+
sandbox = lizard.create("code-interpreter-v1")
|
|
51
60
|
|
|
52
61
|
# Write a script into the microVM filesystem
|
|
53
62
|
sandbox.fs.write("/app/main.py", """
|
|
@@ -76,29 +85,28 @@ sandbox.kill()
|
|
|
76
85
|
Sandboxes can be snapshotted mid-execution and resumed exactly where they left off — including installed packages, in-memory state, and running processes. This makes Lizard sandboxes well-suited for long-running AI agent workflows where you want to checkpoint and continue across separate invocations.
|
|
77
86
|
|
|
78
87
|
```ts
|
|
79
|
-
// Boot and set up the environment once
|
|
80
|
-
const sandbox = await
|
|
88
|
+
// Boot and set up the environment once (reusing the `lizard` client from above)
|
|
89
|
+
const sandbox = await lizard.create('code-interpreter-v1')
|
|
81
90
|
await sandbox.process.exec('pip install numpy pandas scikit-learn')
|
|
82
91
|
const id = sandbox.sandboxId
|
|
83
92
|
await sandbox.pause()
|
|
84
93
|
|
|
85
94
|
// Later — resume instantly from the snapshot (no reinstall needed)
|
|
86
|
-
const resumed = await
|
|
95
|
+
const resumed = await lizard.connect(id)
|
|
87
96
|
const result = await resumed.process.exec('python -c "import sklearn; print(sklearn.__version__)"')
|
|
88
97
|
console.log(result.stdout)
|
|
89
98
|
await resumed.kill()
|
|
90
99
|
```
|
|
91
100
|
|
|
92
101
|
```python
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
sandbox = Sandbox.create("code-interpreter-v1")
|
|
102
|
+
# reusing the `lizard` client from above
|
|
103
|
+
sandbox = lizard.create("code-interpreter-v1")
|
|
96
104
|
sandbox.process.exec_("pip install numpy pandas scikit-learn")
|
|
97
105
|
sandbox_id = sandbox.sandbox_id
|
|
98
106
|
sandbox.pause()
|
|
99
107
|
|
|
100
108
|
# Resume later — environment is exactly as left
|
|
101
|
-
resumed =
|
|
109
|
+
resumed = lizard.connect(sandbox_id)
|
|
102
110
|
result = resumed.process.exec_("python -c 'import sklearn; print(sklearn.__version__)'")
|
|
103
111
|
print(result.stdout)
|
|
104
112
|
resumed.kill()
|
|
@@ -106,13 +114,23 @@ resumed.kill()
|
|
|
106
114
|
|
|
107
115
|
## API
|
|
108
116
|
|
|
117
|
+
### `new Lizard({ project, apiKey?, apiUrl?, timeoutMs? })`
|
|
118
|
+
|
|
119
|
+
Create a client pinned to a project. Every sandbox is billed per project, so `project` is required — pass its ID, slug, or name (resolved to an ID on first use and cached). `apiKey` defaults to the `LIZARD_API_KEY` env var.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const lizard = new Lizard({ project: 'my-project' })
|
|
123
|
+
const sandbox = await lizard.create('base')
|
|
124
|
+
const sandbox = await lizard.create('code-interpreter-v1', { timeoutMs: 10 * 60 * 1000 })
|
|
125
|
+
```
|
|
126
|
+
|
|
109
127
|
### `Sandbox.create(template?, opts?)`
|
|
110
128
|
|
|
111
|
-
Boot a new Lizard microVM. Built-in templates: `base` (Debian + Node.js 20) and `code-interpreter-v1` (Python 3.11 + Node.js 20). Custom templates can be pushed via `lizard push`.
|
|
129
|
+
Boot a new Lizard microVM. Built-in templates: `base` (Debian + Node.js 20) and `code-interpreter-v1` (Python 3.11 + Node.js 20). Custom templates can be pushed via `lizard push`. A project is required — pass `project` (ID, slug, or name) or an exact `projectId` in `opts`, or use a `Lizard` client, which pins one for you.
|
|
112
130
|
|
|
113
131
|
```ts
|
|
114
|
-
const sandbox = await Sandbox.create('base')
|
|
115
|
-
const sandbox = await Sandbox.create('code-interpreter-v1', { timeoutMs: 10 * 60 * 1000 })
|
|
132
|
+
const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
133
|
+
const sandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project', timeoutMs: 10 * 60 * 1000 })
|
|
116
134
|
```
|
|
117
135
|
|
|
118
136
|
### `Sandbox.connect(sandboxId, opts?)`
|
package/dist/index.d.mts
CHANGED
|
@@ -138,10 +138,14 @@ interface SandboxInfo {
|
|
|
138
138
|
}
|
|
139
139
|
interface SandboxOpts extends ConnectionOpts {
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
* attributed to a project so its CPU, RAM, egress, and
|
|
141
|
+
* The project this sandbox belongs to — its ID, slug, or name. Required:
|
|
142
|
+
* a sandbox must be attributed to a project so its CPU, RAM, egress, and
|
|
143
|
+
* storage are billed. Prefer the {@link Lizard} client, which pins a project
|
|
144
|
+
* for you. Ignored when {@link SandboxOpts.projectId} is set.
|
|
143
145
|
*/
|
|
144
|
-
|
|
146
|
+
project?: string;
|
|
147
|
+
/** Exact project ID — skips resolving {@link SandboxOpts.project}. */
|
|
148
|
+
projectId?: string;
|
|
145
149
|
template?: string;
|
|
146
150
|
metadata?: Record<string, string>;
|
|
147
151
|
envs?: Record<string, string>;
|
|
@@ -180,7 +184,7 @@ declare class SandboxClient {
|
|
|
180
184
|
* ```ts
|
|
181
185
|
* import { Sandbox } from 'lizard'
|
|
182
186
|
*
|
|
183
|
-
* const sandbox = await Sandbox.create('base', {
|
|
187
|
+
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
184
188
|
* await sandbox.fs.write('/app/index.js', 'console.log("hello world")')
|
|
185
189
|
* const result = await sandbox.process.exec('node /app/index.js')
|
|
186
190
|
* console.log(result.stdout) // "hello world"
|
|
@@ -189,7 +193,7 @@ declare class SandboxClient {
|
|
|
189
193
|
*
|
|
190
194
|
* @example Pause and resume a long-running session:
|
|
191
195
|
* ```ts
|
|
192
|
-
* const sandbox = await Sandbox.create('code-interpreter-v1', {
|
|
196
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project' })
|
|
193
197
|
* await sandbox.process.exec('pip install numpy')
|
|
194
198
|
* const id = sandbox.sandboxId
|
|
195
199
|
* await sandbox.pause()
|
|
@@ -234,7 +238,7 @@ declare class Sandbox extends SandboxClient {
|
|
|
234
238
|
*
|
|
235
239
|
* @example
|
|
236
240
|
* ```ts
|
|
237
|
-
* const sandbox = await Sandbox.create({
|
|
241
|
+
* const sandbox = await Sandbox.create({ project: 'my-project' })
|
|
238
242
|
* ```
|
|
239
243
|
*/
|
|
240
244
|
static create(opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -249,8 +253,8 @@ declare class Sandbox extends SandboxClient {
|
|
|
249
253
|
*
|
|
250
254
|
* @example
|
|
251
255
|
* ```ts
|
|
252
|
-
* const sandbox = await Sandbox.create('base', {
|
|
253
|
-
* const sandbox = await Sandbox.create('code-interpreter-v1', {
|
|
256
|
+
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
257
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project', timeoutMs: 10 * 60 * 1000 })
|
|
254
258
|
* ```
|
|
255
259
|
*/
|
|
256
260
|
static create(template: string, opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -323,6 +327,63 @@ declare class Sandbox extends SandboxClient {
|
|
|
323
327
|
private resolveOpts;
|
|
324
328
|
}
|
|
325
329
|
|
|
330
|
+
interface LizardOpts extends ConnectionOpts {
|
|
331
|
+
/**
|
|
332
|
+
* The project every sandbox created through this client belongs to — its ID,
|
|
333
|
+
* slug, or name. Required: sandboxes are billed per project, so a project-less
|
|
334
|
+
* sandbox cannot be created.
|
|
335
|
+
*/
|
|
336
|
+
project: string;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The Lizard client — the entry point for creating sandboxes.
|
|
340
|
+
*
|
|
341
|
+
* A client is pinned to one project (billing is metered per project), so every
|
|
342
|
+
* sandbox it creates is attributed correctly. The project reference — ID, slug,
|
|
343
|
+
* or name — is resolved to a project ID on first use and cached.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* import { Lizard } from '@lizard-build/sdk'
|
|
348
|
+
*
|
|
349
|
+
* const lizard = new Lizard({ project: 'my-project' }) // apiKey from LIZARD_API_KEY
|
|
350
|
+
*
|
|
351
|
+
* const sandbox = await lizard.create('base')
|
|
352
|
+
* await sandbox.process.exec('echo hello')
|
|
353
|
+
* await sandbox.kill()
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
declare class Lizard {
|
|
357
|
+
private readonly config;
|
|
358
|
+
private readonly projectRef;
|
|
359
|
+
constructor(opts: LizardOpts);
|
|
360
|
+
/** Resolve the client's project reference to a stable project ID (cached). */
|
|
361
|
+
projectId(): Promise<string>;
|
|
362
|
+
private connectionOpts;
|
|
363
|
+
/**
|
|
364
|
+
* Create a new sandbox in this client's project.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* const sandbox = await lizard.create('base')
|
|
369
|
+
* const sandbox = await lizard.create('code-interpreter-v1', { timeoutMs: 600_000 })
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
create(template?: string, opts?: Omit<SandboxOpts, 'project' | 'projectId'>): Promise<Sandbox>;
|
|
373
|
+
/** Connect to an existing sandbox by ID (resumes it if paused). */
|
|
374
|
+
connect(sandboxId: string, opts?: ConnectionOpts): Promise<Sandbox>;
|
|
375
|
+
/** List running sandboxes for the authenticated account. */
|
|
376
|
+
list(opts?: ConnectionOpts): Promise<SandboxInfo[]>;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Resolve a project reference — its ID, slug, or name — to the stable project
|
|
381
|
+
* ID the API bills against. Exact-ID refs skip the network entirely.
|
|
382
|
+
*
|
|
383
|
+
* @throws {LizardError} when the reference matches no project the key can see.
|
|
384
|
+
*/
|
|
385
|
+
declare function resolveProjectId(ref: string, config: ConnectionConfig): Promise<string>;
|
|
386
|
+
|
|
326
387
|
declare class LizardError extends Error {
|
|
327
388
|
constructor(message: string);
|
|
328
389
|
}
|
|
@@ -414,7 +475,7 @@ interface CreateContextOpts {
|
|
|
414
475
|
* ```ts
|
|
415
476
|
* import { CodeSandbox } from 'lizard/code-interpreter'
|
|
416
477
|
*
|
|
417
|
-
* const sandbox = await CodeSandbox.create({
|
|
478
|
+
* const sandbox = await CodeSandbox.create({ project: 'my-project' })
|
|
418
479
|
*
|
|
419
480
|
* await sandbox.runCode('x = 42')
|
|
420
481
|
* const result = await sandbox.runCode('print(x * 2)')
|
|
@@ -517,4 +578,4 @@ declare class Volume {
|
|
|
517
578
|
delete(projectId: string): Promise<void>;
|
|
518
579
|
}
|
|
519
580
|
|
|
520
|
-
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, LizardError, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo };
|
|
581
|
+
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, Lizard, LizardError, type LizardOpts, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo, resolveProjectId };
|
package/dist/index.d.ts
CHANGED
|
@@ -138,10 +138,14 @@ interface SandboxInfo {
|
|
|
138
138
|
}
|
|
139
139
|
interface SandboxOpts extends ConnectionOpts {
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
142
|
-
* attributed to a project so its CPU, RAM, egress, and
|
|
141
|
+
* The project this sandbox belongs to — its ID, slug, or name. Required:
|
|
142
|
+
* a sandbox must be attributed to a project so its CPU, RAM, egress, and
|
|
143
|
+
* storage are billed. Prefer the {@link Lizard} client, which pins a project
|
|
144
|
+
* for you. Ignored when {@link SandboxOpts.projectId} is set.
|
|
143
145
|
*/
|
|
144
|
-
|
|
146
|
+
project?: string;
|
|
147
|
+
/** Exact project ID — skips resolving {@link SandboxOpts.project}. */
|
|
148
|
+
projectId?: string;
|
|
145
149
|
template?: string;
|
|
146
150
|
metadata?: Record<string, string>;
|
|
147
151
|
envs?: Record<string, string>;
|
|
@@ -180,7 +184,7 @@ declare class SandboxClient {
|
|
|
180
184
|
* ```ts
|
|
181
185
|
* import { Sandbox } from 'lizard'
|
|
182
186
|
*
|
|
183
|
-
* const sandbox = await Sandbox.create('base', {
|
|
187
|
+
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
184
188
|
* await sandbox.fs.write('/app/index.js', 'console.log("hello world")')
|
|
185
189
|
* const result = await sandbox.process.exec('node /app/index.js')
|
|
186
190
|
* console.log(result.stdout) // "hello world"
|
|
@@ -189,7 +193,7 @@ declare class SandboxClient {
|
|
|
189
193
|
*
|
|
190
194
|
* @example Pause and resume a long-running session:
|
|
191
195
|
* ```ts
|
|
192
|
-
* const sandbox = await Sandbox.create('code-interpreter-v1', {
|
|
196
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project' })
|
|
193
197
|
* await sandbox.process.exec('pip install numpy')
|
|
194
198
|
* const id = sandbox.sandboxId
|
|
195
199
|
* await sandbox.pause()
|
|
@@ -234,7 +238,7 @@ declare class Sandbox extends SandboxClient {
|
|
|
234
238
|
*
|
|
235
239
|
* @example
|
|
236
240
|
* ```ts
|
|
237
|
-
* const sandbox = await Sandbox.create({
|
|
241
|
+
* const sandbox = await Sandbox.create({ project: 'my-project' })
|
|
238
242
|
* ```
|
|
239
243
|
*/
|
|
240
244
|
static create(opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -249,8 +253,8 @@ declare class Sandbox extends SandboxClient {
|
|
|
249
253
|
*
|
|
250
254
|
* @example
|
|
251
255
|
* ```ts
|
|
252
|
-
* const sandbox = await Sandbox.create('base', {
|
|
253
|
-
* const sandbox = await Sandbox.create('code-interpreter-v1', {
|
|
256
|
+
* const sandbox = await Sandbox.create('base', { project: 'my-project' })
|
|
257
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { project: 'my-project', timeoutMs: 10 * 60 * 1000 })
|
|
254
258
|
* ```
|
|
255
259
|
*/
|
|
256
260
|
static create(template: string, opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -323,6 +327,63 @@ declare class Sandbox extends SandboxClient {
|
|
|
323
327
|
private resolveOpts;
|
|
324
328
|
}
|
|
325
329
|
|
|
330
|
+
interface LizardOpts extends ConnectionOpts {
|
|
331
|
+
/**
|
|
332
|
+
* The project every sandbox created through this client belongs to — its ID,
|
|
333
|
+
* slug, or name. Required: sandboxes are billed per project, so a project-less
|
|
334
|
+
* sandbox cannot be created.
|
|
335
|
+
*/
|
|
336
|
+
project: string;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* The Lizard client — the entry point for creating sandboxes.
|
|
340
|
+
*
|
|
341
|
+
* A client is pinned to one project (billing is metered per project), so every
|
|
342
|
+
* sandbox it creates is attributed correctly. The project reference — ID, slug,
|
|
343
|
+
* or name — is resolved to a project ID on first use and cached.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* import { Lizard } from '@lizard-build/sdk'
|
|
348
|
+
*
|
|
349
|
+
* const lizard = new Lizard({ project: 'my-project' }) // apiKey from LIZARD_API_KEY
|
|
350
|
+
*
|
|
351
|
+
* const sandbox = await lizard.create('base')
|
|
352
|
+
* await sandbox.process.exec('echo hello')
|
|
353
|
+
* await sandbox.kill()
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
declare class Lizard {
|
|
357
|
+
private readonly config;
|
|
358
|
+
private readonly projectRef;
|
|
359
|
+
constructor(opts: LizardOpts);
|
|
360
|
+
/** Resolve the client's project reference to a stable project ID (cached). */
|
|
361
|
+
projectId(): Promise<string>;
|
|
362
|
+
private connectionOpts;
|
|
363
|
+
/**
|
|
364
|
+
* Create a new sandbox in this client's project.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* ```ts
|
|
368
|
+
* const sandbox = await lizard.create('base')
|
|
369
|
+
* const sandbox = await lizard.create('code-interpreter-v1', { timeoutMs: 600_000 })
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
create(template?: string, opts?: Omit<SandboxOpts, 'project' | 'projectId'>): Promise<Sandbox>;
|
|
373
|
+
/** Connect to an existing sandbox by ID (resumes it if paused). */
|
|
374
|
+
connect(sandboxId: string, opts?: ConnectionOpts): Promise<Sandbox>;
|
|
375
|
+
/** List running sandboxes for the authenticated account. */
|
|
376
|
+
list(opts?: ConnectionOpts): Promise<SandboxInfo[]>;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Resolve a project reference — its ID, slug, or name — to the stable project
|
|
381
|
+
* ID the API bills against. Exact-ID refs skip the network entirely.
|
|
382
|
+
*
|
|
383
|
+
* @throws {LizardError} when the reference matches no project the key can see.
|
|
384
|
+
*/
|
|
385
|
+
declare function resolveProjectId(ref: string, config: ConnectionConfig): Promise<string>;
|
|
386
|
+
|
|
326
387
|
declare class LizardError extends Error {
|
|
327
388
|
constructor(message: string);
|
|
328
389
|
}
|
|
@@ -414,7 +475,7 @@ interface CreateContextOpts {
|
|
|
414
475
|
* ```ts
|
|
415
476
|
* import { CodeSandbox } from 'lizard/code-interpreter'
|
|
416
477
|
*
|
|
417
|
-
* const sandbox = await CodeSandbox.create({
|
|
478
|
+
* const sandbox = await CodeSandbox.create({ project: 'my-project' })
|
|
418
479
|
*
|
|
419
480
|
* await sandbox.runCode('x = 42')
|
|
420
481
|
* const result = await sandbox.runCode('print(x * 2)')
|
|
@@ -517,4 +578,4 @@ declare class Volume {
|
|
|
517
578
|
delete(projectId: string): Promise<void>;
|
|
518
579
|
}
|
|
519
580
|
|
|
520
|
-
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, LizardError, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo };
|
|
581
|
+
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, Lizard, LizardError, type LizardOpts, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo, resolveProjectId };
|
package/dist/index.js
CHANGED
|
@@ -22,11 +22,13 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AuthenticationError: () => AuthenticationError,
|
|
24
24
|
CodeSandbox: () => CodeSandbox,
|
|
25
|
+
Lizard: () => Lizard,
|
|
25
26
|
LizardError: () => LizardError,
|
|
26
27
|
NotFoundError: () => NotFoundError,
|
|
27
28
|
Sandbox: () => Sandbox,
|
|
28
29
|
TimeoutError: () => TimeoutError,
|
|
29
|
-
Volume: () => Volume
|
|
30
|
+
Volume: () => Volume,
|
|
31
|
+
resolveProjectId: () => resolveProjectId
|
|
30
32
|
});
|
|
31
33
|
module.exports = __toCommonJS(index_exports);
|
|
32
34
|
|
|
@@ -91,6 +93,36 @@ async function handleApiError(res) {
|
|
|
91
93
|
throw new LizardError(`API error ${res.status}: ${message}`);
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
// src/project.ts
|
|
97
|
+
var projectIdCache = /* @__PURE__ */ new Map();
|
|
98
|
+
async function resolveProjectId(ref, config) {
|
|
99
|
+
const cacheKey = `${config.apiUrl}\0${ref}`;
|
|
100
|
+
const cached = projectIdCache.get(cacheKey);
|
|
101
|
+
if (cached) return cached;
|
|
102
|
+
const res = await fetch(`${config.apiUrl}/api/projects`, { headers: config.headers });
|
|
103
|
+
if (!res.ok) await handleApiError(res);
|
|
104
|
+
const projects = await res.json();
|
|
105
|
+
const lower = ref.toLowerCase();
|
|
106
|
+
const match = projects.find(
|
|
107
|
+
(p) => p.id.toLowerCase() === lower || p.slug?.toLowerCase() === lower || p.name?.toLowerCase() === lower
|
|
108
|
+
);
|
|
109
|
+
if (!match) {
|
|
110
|
+
const available = projects.map((p) => p.slug || p.id).join(", ") || "(none)";
|
|
111
|
+
throw new LizardError(
|
|
112
|
+
`Project "${ref}" not found. Available: ${available}. Pass the project's ID, slug, or name.`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
projectIdCache.set(cacheKey, match.id);
|
|
116
|
+
return match.id;
|
|
117
|
+
}
|
|
118
|
+
function requireProjectRef(opts) {
|
|
119
|
+
if (opts?.projectId) return { projectId: opts.projectId };
|
|
120
|
+
if (opts?.project) return { project: opts.project };
|
|
121
|
+
throw new LizardError(
|
|
122
|
+
'A project is required to create a sandbox. Pass `project` (its ID, slug, or name), or create sandboxes through a Lizard client: new Lizard({ project: "my-project" }).'
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
94
126
|
// src/sandbox/process.ts
|
|
95
127
|
var Process = class {
|
|
96
128
|
constructor(sandboxId, config) {
|
|
@@ -233,19 +265,16 @@ var Fs = class {
|
|
|
233
265
|
// src/sandbox/client.ts
|
|
234
266
|
var SandboxClient = class {
|
|
235
267
|
static async createSandbox(template, timeoutMs, opts) {
|
|
236
|
-
|
|
237
|
-
throw new LizardError(
|
|
238
|
-
"projectId is required: a sandbox must belong to a project so its usage is billed. Pass { projectId } to Sandbox.create()."
|
|
239
|
-
);
|
|
240
|
-
}
|
|
268
|
+
const ref = requireProjectRef(opts);
|
|
241
269
|
const config = new ConnectionConfig(opts);
|
|
270
|
+
const projectId = ref.projectId ?? await resolveProjectId(ref.project, config);
|
|
242
271
|
const res = await fetch(`${config.apiUrl}/api/sandboxes`, {
|
|
243
272
|
method: "POST",
|
|
244
273
|
headers: config.headers,
|
|
245
274
|
body: JSON.stringify({
|
|
246
|
-
projectId: opts.projectId,
|
|
247
275
|
template,
|
|
248
276
|
timeoutMs,
|
|
277
|
+
projectId,
|
|
249
278
|
metadata: opts?.metadata,
|
|
250
279
|
envs: opts?.envs,
|
|
251
280
|
volumeId: opts?.volumeId
|
|
@@ -427,6 +456,48 @@ var Sandbox = class extends SandboxClient {
|
|
|
427
456
|
Sandbox.defaultTemplate = "base";
|
|
428
457
|
Sandbox.defaultTimeoutMs = DEFAULT_SANDBOX_TIMEOUT_MS;
|
|
429
458
|
|
|
459
|
+
// src/lizard.ts
|
|
460
|
+
var Lizard = class {
|
|
461
|
+
constructor(opts) {
|
|
462
|
+
if (!opts?.project) {
|
|
463
|
+
throw new LizardError(
|
|
464
|
+
'A project is required. Pass project (its ID, slug, or name): new Lizard({ project: "my-project" }).'
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
this.config = new ConnectionConfig(opts);
|
|
468
|
+
this.projectRef = opts.project;
|
|
469
|
+
}
|
|
470
|
+
/** Resolve the client's project reference to a stable project ID (cached). */
|
|
471
|
+
async projectId() {
|
|
472
|
+
return resolveProjectId(this.projectRef, this.config);
|
|
473
|
+
}
|
|
474
|
+
async connectionOpts(extra) {
|
|
475
|
+
return { apiKey: this.config.apiKey, apiUrl: this.config.apiUrl, ...extra };
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Create a new sandbox in this client's project.
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```ts
|
|
482
|
+
* const sandbox = await lizard.create('base')
|
|
483
|
+
* const sandbox = await lizard.create('code-interpreter-v1', { timeoutMs: 600_000 })
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
async create(template, opts) {
|
|
487
|
+
const projectId = await this.projectId();
|
|
488
|
+
const sandboxOpts = { ...opts, ...await this.connectionOpts(), projectId };
|
|
489
|
+
return template ? Sandbox.create(template, sandboxOpts) : Sandbox.create(sandboxOpts);
|
|
490
|
+
}
|
|
491
|
+
/** Connect to an existing sandbox by ID (resumes it if paused). */
|
|
492
|
+
async connect(sandboxId, opts) {
|
|
493
|
+
return Sandbox.connect(sandboxId, await this.connectionOpts(opts));
|
|
494
|
+
}
|
|
495
|
+
/** List running sandboxes for the authenticated account. */
|
|
496
|
+
async list(opts) {
|
|
497
|
+
return Sandbox.list(await this.connectionOpts(opts));
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
430
501
|
// src/code-interpreter/types.ts
|
|
431
502
|
var ExecutionError = class extends Error {
|
|
432
503
|
constructor(name, message, traceback) {
|
|
@@ -669,9 +740,11 @@ var Volume = class _Volume {
|
|
|
669
740
|
0 && (module.exports = {
|
|
670
741
|
AuthenticationError,
|
|
671
742
|
CodeSandbox,
|
|
743
|
+
Lizard,
|
|
672
744
|
LizardError,
|
|
673
745
|
NotFoundError,
|
|
674
746
|
Sandbox,
|
|
675
747
|
TimeoutError,
|
|
676
|
-
Volume
|
|
748
|
+
Volume,
|
|
749
|
+
resolveProjectId
|
|
677
750
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -59,6 +59,36 @@ async function handleApiError(res) {
|
|
|
59
59
|
throw new LizardError(`API error ${res.status}: ${message}`);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// src/project.ts
|
|
63
|
+
var projectIdCache = /* @__PURE__ */ new Map();
|
|
64
|
+
async function resolveProjectId(ref, config) {
|
|
65
|
+
const cacheKey = `${config.apiUrl}\0${ref}`;
|
|
66
|
+
const cached = projectIdCache.get(cacheKey);
|
|
67
|
+
if (cached) return cached;
|
|
68
|
+
const res = await fetch(`${config.apiUrl}/api/projects`, { headers: config.headers });
|
|
69
|
+
if (!res.ok) await handleApiError(res);
|
|
70
|
+
const projects = await res.json();
|
|
71
|
+
const lower = ref.toLowerCase();
|
|
72
|
+
const match = projects.find(
|
|
73
|
+
(p) => p.id.toLowerCase() === lower || p.slug?.toLowerCase() === lower || p.name?.toLowerCase() === lower
|
|
74
|
+
);
|
|
75
|
+
if (!match) {
|
|
76
|
+
const available = projects.map((p) => p.slug || p.id).join(", ") || "(none)";
|
|
77
|
+
throw new LizardError(
|
|
78
|
+
`Project "${ref}" not found. Available: ${available}. Pass the project's ID, slug, or name.`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
projectIdCache.set(cacheKey, match.id);
|
|
82
|
+
return match.id;
|
|
83
|
+
}
|
|
84
|
+
function requireProjectRef(opts) {
|
|
85
|
+
if (opts?.projectId) return { projectId: opts.projectId };
|
|
86
|
+
if (opts?.project) return { project: opts.project };
|
|
87
|
+
throw new LizardError(
|
|
88
|
+
'A project is required to create a sandbox. Pass `project` (its ID, slug, or name), or create sandboxes through a Lizard client: new Lizard({ project: "my-project" }).'
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
62
92
|
// src/sandbox/process.ts
|
|
63
93
|
var Process = class {
|
|
64
94
|
constructor(sandboxId, config) {
|
|
@@ -201,19 +231,16 @@ var Fs = class {
|
|
|
201
231
|
// src/sandbox/client.ts
|
|
202
232
|
var SandboxClient = class {
|
|
203
233
|
static async createSandbox(template, timeoutMs, opts) {
|
|
204
|
-
|
|
205
|
-
throw new LizardError(
|
|
206
|
-
"projectId is required: a sandbox must belong to a project so its usage is billed. Pass { projectId } to Sandbox.create()."
|
|
207
|
-
);
|
|
208
|
-
}
|
|
234
|
+
const ref = requireProjectRef(opts);
|
|
209
235
|
const config = new ConnectionConfig(opts);
|
|
236
|
+
const projectId = ref.projectId ?? await resolveProjectId(ref.project, config);
|
|
210
237
|
const res = await fetch(`${config.apiUrl}/api/sandboxes`, {
|
|
211
238
|
method: "POST",
|
|
212
239
|
headers: config.headers,
|
|
213
240
|
body: JSON.stringify({
|
|
214
|
-
projectId: opts.projectId,
|
|
215
241
|
template,
|
|
216
242
|
timeoutMs,
|
|
243
|
+
projectId,
|
|
217
244
|
metadata: opts?.metadata,
|
|
218
245
|
envs: opts?.envs,
|
|
219
246
|
volumeId: opts?.volumeId
|
|
@@ -395,6 +422,48 @@ var Sandbox = class extends SandboxClient {
|
|
|
395
422
|
Sandbox.defaultTemplate = "base";
|
|
396
423
|
Sandbox.defaultTimeoutMs = DEFAULT_SANDBOX_TIMEOUT_MS;
|
|
397
424
|
|
|
425
|
+
// src/lizard.ts
|
|
426
|
+
var Lizard = class {
|
|
427
|
+
constructor(opts) {
|
|
428
|
+
if (!opts?.project) {
|
|
429
|
+
throw new LizardError(
|
|
430
|
+
'A project is required. Pass project (its ID, slug, or name): new Lizard({ project: "my-project" }).'
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
this.config = new ConnectionConfig(opts);
|
|
434
|
+
this.projectRef = opts.project;
|
|
435
|
+
}
|
|
436
|
+
/** Resolve the client's project reference to a stable project ID (cached). */
|
|
437
|
+
async projectId() {
|
|
438
|
+
return resolveProjectId(this.projectRef, this.config);
|
|
439
|
+
}
|
|
440
|
+
async connectionOpts(extra) {
|
|
441
|
+
return { apiKey: this.config.apiKey, apiUrl: this.config.apiUrl, ...extra };
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Create a new sandbox in this client's project.
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```ts
|
|
448
|
+
* const sandbox = await lizard.create('base')
|
|
449
|
+
* const sandbox = await lizard.create('code-interpreter-v1', { timeoutMs: 600_000 })
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
async create(template, opts) {
|
|
453
|
+
const projectId = await this.projectId();
|
|
454
|
+
const sandboxOpts = { ...opts, ...await this.connectionOpts(), projectId };
|
|
455
|
+
return template ? Sandbox.create(template, sandboxOpts) : Sandbox.create(sandboxOpts);
|
|
456
|
+
}
|
|
457
|
+
/** Connect to an existing sandbox by ID (resumes it if paused). */
|
|
458
|
+
async connect(sandboxId, opts) {
|
|
459
|
+
return Sandbox.connect(sandboxId, await this.connectionOpts(opts));
|
|
460
|
+
}
|
|
461
|
+
/** List running sandboxes for the authenticated account. */
|
|
462
|
+
async list(opts) {
|
|
463
|
+
return Sandbox.list(await this.connectionOpts(opts));
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
|
|
398
467
|
// src/code-interpreter/types.ts
|
|
399
468
|
var ExecutionError = class extends Error {
|
|
400
469
|
constructor(name, message, traceback) {
|
|
@@ -636,9 +705,11 @@ var Volume = class _Volume {
|
|
|
636
705
|
export {
|
|
637
706
|
AuthenticationError,
|
|
638
707
|
CodeSandbox,
|
|
708
|
+
Lizard,
|
|
639
709
|
LizardError,
|
|
640
710
|
NotFoundError,
|
|
641
711
|
Sandbox,
|
|
642
712
|
TimeoutError,
|
|
643
|
-
Volume
|
|
713
|
+
Volume,
|
|
714
|
+
resolveProjectId
|
|
644
715
|
};
|