@aerol-ai/aerolvm-sdk 0.1.9 → 0.2.1

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/dist/MicroVM.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type APIVersion } from "./internal/client.js";
2
2
  import { Sandbox } from "./Sandbox.js";
3
3
  import { Image } from "./Image.js";
4
- import type { BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, Lifecycle, MountSpecRedacted, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
4
+ import type { BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, Lifecycle, ListOptions, MountSpecRedacted, RegisterSnapshotOptions, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
5
5
  type FetchLike = typeof fetch;
6
6
  export interface MicroVMConfig {
7
7
  patToken?: string;
@@ -21,11 +21,13 @@ export declare class MicroVM {
21
21
  private readonly client;
22
22
  constructor(config?: MicroVMConfig);
23
23
  create(options: CreateOptions): Promise<Sandbox>;
24
- list(): Promise<Sandbox[]>;
24
+ list(options?: ListOptions): Promise<Sandbox[]>;
25
25
  get(id: string): Promise<Sandbox>;
26
26
  start(id: string): Promise<Sandbox>;
27
27
  stop(id: string): Promise<Sandbox>;
28
28
  createSnapshot(id: string, name: string): Promise<SandboxSnapshot>;
29
+ registerSnapshot(options: RegisterSnapshotOptions): Promise<SandboxSnapshot>;
30
+ registerSnapshotFromImage(name: string, image: Image, options?: Omit<RegisterSnapshotOptions, "name" | "image" | "dockerfileContent">): Promise<SandboxSnapshot>;
29
31
  destroy(id: string): Promise<void>;
30
32
  resize(id: string, options: ResizeOptions): Promise<Sandbox>;
31
33
  updateLifecycle(id: string, lifecycle: Lifecycle): Promise<Sandbox>;
package/dist/MicroVM.js CHANGED
@@ -25,8 +25,8 @@ export class MicroVM {
25
25
  const sandbox = await this.client.create(options);
26
26
  return this.wrap(sandbox.toJSON());
27
27
  }
28
- async list() {
29
- const sandboxes = await this.client.list();
28
+ async list(options) {
29
+ const sandboxes = await this.client.list(options);
30
30
  return sandboxes.map((sandbox) => this.wrap(sandbox.toJSON()));
31
31
  }
32
32
  async get(id) {
@@ -44,6 +44,12 @@ export class MicroVM {
44
44
  async createSnapshot(id, name) {
45
45
  return this.client.createSnapshot(id, name);
46
46
  }
47
+ async registerSnapshot(options) {
48
+ return this.client.registerSnapshot(options);
49
+ }
50
+ async registerSnapshotFromImage(name, image, options = {}) {
51
+ return this.client.registerSnapshotFromImage(name, image, options);
52
+ }
47
53
  async destroy(id) {
48
54
  await this.client.destroy(id);
49
55
  }
package/dist/index.d.ts CHANGED
@@ -2,4 +2,4 @@ export { MicroVM } from "./MicroVM.js";
2
2
  export { Sandbox } from "./Sandbox.js";
3
3
  export { Image } from "./Image.js";
4
4
  export type { MicroVMConfig } from "./MicroVM.js";
5
- export type { BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
5
+ export type { BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
@@ -1,5 +1,5 @@
1
1
  import { Image } from "../Image.js";
2
- import type { BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, HealthStatus, Lifecycle, MountSpecRedacted, NetworkUsage, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
2
+ import type { BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, HealthStatus, Lifecycle, ListOptions, MountSpecRedacted, NetworkUsage, RegisterSnapshotOptions, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
3
3
  type FetchLike = typeof fetch;
4
4
  /**
5
5
  * Wire version of the v1-style sandbox endpoints (`/v1/sandboxes`, etc.) this
@@ -55,11 +55,13 @@ export declare class APIClient {
55
55
  */
56
56
  buildImage(image: Image, options?: BuildImageOptions): Promise<BuildImageResult>;
57
57
  private resolveImage;
58
- list(): Promise<SandboxResource[]>;
58
+ list(options?: ListOptions): Promise<SandboxResource[]>;
59
59
  get(id: string): Promise<SandboxResource>;
60
60
  start(id: string): Promise<SandboxResource>;
61
61
  stop(id: string): Promise<SandboxResource>;
62
62
  createSnapshot(id: string, name: string): Promise<SandboxSnapshot>;
63
+ registerSnapshot(options: RegisterSnapshotOptions): Promise<SandboxSnapshot>;
64
+ registerSnapshotFromImage(name: string, image: Image, options?: Omit<RegisterSnapshotOptions, "name" | "image" | "dockerfileContent">): Promise<SandboxSnapshot>;
63
65
  destroy(id: string): Promise<void>;
64
66
  resize(id: string, options: ResizeOptions): Promise<SandboxResource>;
65
67
  updateLifecycle(id: string, lifecycle: Lifecycle): Promise<SandboxResource>;
@@ -85,8 +85,9 @@ export class APIClient {
85
85
  const result = await this.buildImage(options.image);
86
86
  return { ...options, image: result.image };
87
87
  }
88
- async list() {
89
- const response = await this.doJSON("GET", this.versioned("/sandboxes"));
88
+ async list(options) {
89
+ const path = this.versioned("/sandboxes") + buildTagQuery(options?.tags);
90
+ const response = await this.doJSON("GET", path);
90
91
  return response.map((item) => this.wrap(item));
91
92
  }
92
93
  async get(id) {
@@ -105,6 +106,35 @@ export class APIClient {
105
106
  const response = await this.doJSON("POST", `${this.versionPrefix}/sandboxes/${id}/snapshot`, { name });
106
107
  return fromApiSandboxSnapshot(response);
107
108
  }
109
+ async registerSnapshot(options) {
110
+ const name = options.name.trim();
111
+ if (name === "") {
112
+ throw new Error("name is required");
113
+ }
114
+ const image = options.image?.trim() ?? "";
115
+ const dockerfileContent = options.dockerfileContent?.trim() ?? "";
116
+ if (image === "" && dockerfileContent === "") {
117
+ throw new Error("image or dockerfile_content is required");
118
+ }
119
+ if (image !== "" && dockerfileContent !== "") {
120
+ throw new Error("image and dockerfile_content are mutually exclusive");
121
+ }
122
+ const response = await this.doJSON("POST", this.versioned("/snapshots"), toApiRegisterSnapshotOptions({
123
+ ...options,
124
+ name,
125
+ image: image || undefined,
126
+ dockerfileContent: dockerfileContent || undefined,
127
+ regionID: options.regionID?.trim() || undefined,
128
+ }));
129
+ return fromApiSandboxSnapshot(response);
130
+ }
131
+ async registerSnapshotFromImage(name, image, options = {}) {
132
+ return this.registerSnapshot({
133
+ ...options,
134
+ name,
135
+ dockerfileContent: image.dockerfile,
136
+ });
137
+ }
108
138
  async destroy(id) {
109
139
  await this.doJSON("DELETE", `${this.versionPrefix}/sandboxes/${id}`);
110
140
  }
@@ -361,6 +391,20 @@ function toApiCreateOptions(options) {
361
391
  runtime: options.runtime,
362
392
  };
363
393
  }
394
+ function toApiRegisterSnapshotOptions(options) {
395
+ return {
396
+ name: options.name,
397
+ image: options.image,
398
+ dockerfile_content: options.dockerfileContent,
399
+ context_hashes: options.contextHashes,
400
+ entrypoint: options.entrypoint,
401
+ region_id: options.regionID,
402
+ cpu: options.cpu,
403
+ gpu: options.gpu,
404
+ memory_mb: options.memoryMB,
405
+ disk_gb: options.diskGB,
406
+ };
407
+ }
364
408
  function toApiResizeOptions(options) {
365
409
  return {
366
410
  cpu: options.cpu,
@@ -444,6 +488,12 @@ function fromApiSandboxSnapshot(snapshot) {
444
488
  imageID: snapshot.image_id,
445
489
  sourceSandboxID: snapshot.source_sandbox_id,
446
490
  createdAt: snapshot.created_at,
491
+ entrypoint: snapshot.entrypoint,
492
+ regionID: snapshot.region_id,
493
+ cpu: snapshot.cpu,
494
+ gpu: snapshot.gpu,
495
+ memoryMB: snapshot.memory_mb,
496
+ diskGB: snapshot.disk_gb,
447
497
  };
448
498
  }
449
499
  function fromApiSession(session) {
@@ -559,6 +609,21 @@ function fromApiLifecycle(lifecycle) {
559
609
  }
560
610
  return result;
561
611
  }
612
+ // buildTagQuery renders ListOptions.tags as the server's wire format. The
613
+ // `tag.` prefix is literal — the server's parseTagFilter does a prefix check
614
+ // on the *decoded* query key, so only the user-supplied key and value get
615
+ // percent-encoded. An empty or absent map returns "" so the request URL is
616
+ // byte-identical to the pre-filter call site (no trailing "?"), keeping
617
+ // fixtures and middleware that match on path stable.
618
+ function buildTagQuery(tags) {
619
+ if (!tags)
620
+ return "";
621
+ const entries = Object.entries(tags);
622
+ if (entries.length === 0)
623
+ return "";
624
+ const parts = entries.map(([key, value]) => `tag.${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
625
+ return "?" + parts.join("&");
626
+ }
562
627
  function cloneSandbox(sandbox) {
563
628
  return {
564
629
  ...sandbox,
package/dist/types.d.ts CHANGED
@@ -28,6 +28,25 @@ export interface BuildImageResult {
28
28
  /** Pushed reference, e.g. "ghcr.io/my-org/my-image:v1.2.3". */
29
29
  pushed?: string;
30
30
  }
31
+ export interface RegisterSnapshotOptions {
32
+ /** Human-readable identifier other callers use in `CreateOptions.snapshot`. */
33
+ name: string;
34
+ /** Pre-built registry reference. Mutually exclusive with `dockerfileContent`. */
35
+ image?: string;
36
+ /** Literal Dockerfile the daemon will build. Mutually exclusive with `image`. */
37
+ dockerfileContent?: string;
38
+ /** Uploaded build-context hashes for future COPY/ADD resolution. */
39
+ contextHashes?: string[];
40
+ /** Optional command override persisted on the snapshot row. */
41
+ entrypoint?: string[];
42
+ /** Region hint persisted for read-back. */
43
+ regionID?: string;
44
+ /** Resource hints surfaced back on the snapshot row. */
45
+ cpu?: number;
46
+ gpu?: number;
47
+ memoryMB?: number;
48
+ diskGB?: number;
49
+ }
31
50
  export type MountType = "s3" | "nfs" | "sshfs" | "rclone";
32
51
  export interface MountSpec {
33
52
  type: MountType;
@@ -142,6 +161,15 @@ export interface ResizeOptions {
142
161
  memoryMB?: number;
143
162
  diskGB?: number;
144
163
  }
164
+ export interface ListOptions {
165
+ /**
166
+ * Filter the result to only sandboxes whose `tags` map contains every
167
+ * key/value pair given here (AND semantics on the server). Wire format is
168
+ * `?tag.<key>=<value>`; the SDK URL-encodes keys and values for you. Omit
169
+ * or pass an empty map to list every sandbox visible to the PAT.
170
+ */
171
+ tags?: Record<string, string>;
172
+ }
145
173
  export interface CreateSessionOptions {
146
174
  name?: string;
147
175
  argv?: string[];
@@ -192,6 +220,12 @@ export interface SandboxSnapshot {
192
220
  imageID?: string;
193
221
  sourceSandboxID: string;
194
222
  createdAt: string;
223
+ entrypoint?: string[];
224
+ regionID?: string;
225
+ cpu?: number;
226
+ gpu?: number;
227
+ memoryMB?: number;
228
+ diskGB?: number;
195
229
  }
196
230
  /**
197
231
  * Discriminated result from `exposePort`. Branch on `protocol` to access the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerol-ai/aerolvm-sdk",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",